计算灰度共生矩阵
2011-12-19 08:47阅读:
分类: C/C++
OpenCV
2010-12-09 14:07 423人阅读
评论(0)
收藏 举报
共生矩阵用两个位置的象素的联合概率密度来定义,它不仅反映亮度的分布特性,也反映具有同样亮度或接近亮度的象素之间的位置分布特性,是有关图象亮度变化的二阶统计特征。它是定义一组纹理特征的基础。
灰度共生矩阵能反映出图象灰度关于方向、相邻间隔、变化幅度的综合信息。设f(x,y)为一幅二维数字图象,其大小为M×N,灰度级别为Ng,则满足一定空间关系的灰度共生矩阵为:
P(i,j)=#{(x1,y1),(x2,y2)∈M×N|f(x1,y1)=
i,f(x2,y2)=j}
其中#(x)表示集合x中的元素个数,显然P为Ng×Ng的矩阵,若(x1,y1)与(x2,y2)间距离为d,两者与坐标横轴的夹角为θ,则可以得到各种间距及角度的灰度共生矩阵P(i,j,d,θ)。
 |
 |
- class CGlcm
- {
- public:
-
CGlcm(void);
-
virtual
~CGlcm(void);
- public:
- int
*m_pMat1;
- int
*m_pMat2;
- int
*m_pMat3;
- int
*m_pMat4;
- protected:
- int
*m_pLine[4][256];
- int
m_nMin;
- int
m_nMax;
- int
m_nSum;
- public:
- //
计算共生矩阵
- //
参数:
- // 1.
pImageData: 图像数据指针,单通道,8位。
- // 2.
nLeft,nTop,nWidth,nHeight: 计算共生矩阵的区域。
- // 3.
nWidthStep: 行偏移量。
- // 4.
nScale: 尺度。
- // 5.
nReduction: 灰度级压缩。
- bool
CalGlcm(unsigned char
*pImageData, int
nLeft, int
nTop, int
nWidth, int
nHeight, int
nWidthStep, int
nScale, int
nReduction);
- };
- // 灰度共生矩阵
- CGlcm::CGlcm(void)
- : m_pMat1(NULL)
- , m_pMat2(NULL)
- , m_pMat3(NULL)
- , m_pMat4(NULL)
- , m_nMin(0)
- , m_nMax(0)
- , m_nSum(0)
- {
- int
i, j;
- unsigned
int nSize =
sizeof(int)
* 256 * 256;
- //
创建共生矩阵
- m_pMat1 =
(int*) malloc(nSize);
- m_pMat2 =
(int*) malloc(nSize);
- m_pMat3 =
(int*) malloc(nSize);
- m_pMat4 =
(int*) malloc(nSize);
- if
(m_pMat1 && m_pMat2
&& m_pMat3 && m_pMat4)
- {
-
for (i = 0,
j = 0; i < 256;
i++, j += 256)
-
{
-
m_pLine[0][i] =
m_pMat1 + j;
-
m_pLine[1][i] =
m_pMat2 + j;
-
m_pLine[2][i] =
m_pMat3 + j;
-
m_pLine[3][i] =
m_pMat4 + j;
-
}
- }
- }
- CGlcm::~CGlcm(void)
- {
- //
释放共生矩阵
- if
(m_pMat1) free(m_pMat1);
- if
(m_pMat2) free(m_pMat2);
- if
(m_pMat3) free(m_pMat3);
- if
(m_pMat4) free(m_pMat4);
- }
- // 计算共生矩阵
- bool CGlcm::CalGlcm(unsigned
char *pImageData,
int nLeft,
int nTop,
int nWidth,
int nHeight,
int nWidthStep,
int nScale,
int nReduction)
- {
- bool
bResult =
false;
- int
x0, x1, x2;
- int
y0, y1, y2;
- int
nGray;
- unsigned
int nSize;
- unsigned
char *pLine[3];
- if
(pImageData)
- {
-
// 灰度最值
-
m_nMin = 0xFF;
-
m_nMax = 0;
-
pLine[1] = pImageData +
nWidthStep * nTop + nLeft;
-
for (y1 = 0;
y1 < nHeight; y1++)
-
{
-
for
(x1 = 0; x1 <
nWidth; x1++)
-
{
-
// 灰度级压缩
-
if (nReduction >
0)
-
{
-
pLine[1][x1] =
pLine[1][x1] >> nReduction;
-
}
-
nGray = pLine[1][x1];
-
if (nGray <
m_nMin)
-
{
-
m_nMin =
nGray;
-
}
-
else if
(nGray > m_nMax)
-
{
-
m_nMax =
nGray;
-
}
-
}
-
pLine[1] +=
nWidthStep;
-
}
-
// 累加和
-
m_nSum = nWidth * nHeight
* 2;
-
if (m_nMax >=
m_nMin)
-
{
-
//
清空内存
-
nSize =
sizeof(int)
* (m_nMax - m_nMin + 1);
-
for
(y1 = m_nMin; y1 <=
m_nMax; y1++)
-
{
-
memset(&m_pLine[0][y1][m_nMin], 0, nSize);
-
memset(&m_pLine[1][y1][m_nMin], 0, nSize);
-
memset(&m_pLine[2][y1][m_nMin], 0, nSize);
-
memset(&m_pLine[3][y1][m_nMin], 0, nSize);
-
}
-
//
计算共生矩阵
-
pLine[1] =
pImageData + nWidthStep * nTop
+ nLeft;
-
for
(y0 = -nScale, y1 =
0, y2 = nScale; y1 <
nHeight; y0++, y1++, y2++)
-
{
-
pLine[0] = pLine[1] -
nWidthStep;
-
pLine[2] = pLine[1] +
nWidthStep;
-
for (x0 =
-nScale, x1 = 0, x2 =
nScale; x1 < nWidth; x0++,
x1++, x2++)
-
{
-
nGray =
pLine[1][x1];
-
// 0
度
-
if
(x2 < nWidth)
-
{
-
m_pLine[0][nGray][pLine[1][x2]]++;
-
}
-
// 45
度
-
if
(y0 > 0 && x2
< nWidth)
-
{
-
m_pLine[1][nGray][pLine[0][x2]]++;
-
}
-
// 90
度
-
if
(y0 > 0)
-
{
-
m_pLine[2][nGray][pLine[0][x1]]++;
-
}
-
// 135
度
-
if
(y0 > 0 && x0
> 0)
-
{
-
m_pLine[3][nGray][pLine[0][x0]]++;
-
}
-
// 180
度
-
if
(x0 > 0)
-
{
-
m_pLine[0][nGray][pLine[1][x0]]++;
-
}
-
// 225
度
-
if
(x0 > 0 && y2
< nHeight)
-
{
-
m_pLine[1][nGray][pLine[2][x0]]++;
-
}
-
// 270
度
-
if
(y2 < nHeight)
-
{
-
m_pLine[2][nGray][pLine[2][x1]]++;
-
}
-
// 315
度
-
if
(y2 < nHeight &&
x2 < nWidth)
-
{
-
m_pLine[3][nGray][pLine[2][x2]]++;
-
}
-
}
-
pLine[1] += nWidthStep;
-
}
-
bResult =
true;
-
}
- }
- return
bResult;
- }
提取共生矩阵特征
为了能更直观地以共生矩阵描述纹理状况,从共生矩阵导出一些反映矩阵状况的参数,典型的有以下几种:
-
角二阶矩(ASM):是灰度共生矩阵元素值的平方和,所以也称能量。它反映了图像灰度分布均匀程度和纹理粗细度。如果共生矩阵的所有值均相等,则ASM值小;相反,如果其中一些值大而其它值小,则ASM值大。当共生矩阵中元素集中分布时,此时ASM值大。ASM值大表明一种较均一和规则变化的纹理模式。

-
熵(ENT):是图像所具有的信息量的度量,纹理信息也属于图像的信息,是一个随机性的度量,当共生矩阵中所有元素有最大的随机性、空间共生矩阵中所有值几乎相等时,共生矩阵中元素分散分布时,熵较大。它表示了图像中纹理的非均匀程度或复杂程度。

-
对比度(CON):反映了图像的清晰度和纹理沟纹深浅的程度。纹理沟纹越深,其对比度越大,视觉效果越清晰;反之,对比度小,则沟纹浅,效果模糊。灰度差即对比度大的象素对越多,这个值越大。灰度公生矩阵中远离对角线的元素值越大,CON越大。

-
逆差距(HOM):反映图像纹理的同质性,度量图像纹理局部变化的多少。其值大则说明图像纹理的不同区域间缺少变化,局部非常均匀。

-
相关(COR):度量空间灰度共生矩阵元素在行或列方向上的相似程度,因此,相关值大小反映了图像中局部灰度相关性。当矩阵元素值均匀相等时,相关值就大;相反,如果矩阵像元值相差很大则相关值小。如果图像中有水平方向纹理,则水平方向矩阵的COR大于其余矩阵的COR值。

view
plaincopy to
clipboardprint?
- #include <math.h>
- // 共生矩阵特征
- struct GlcmFeature
- {
- double
ASM[4]; //
角二阶矩/能量
- double
ENT[4]; // 熵
- double
CON[4]; //
对比度
- double
HOM[4]; //
逆差矩/同质性
- double
COR[4]; //
相关性
- };
- // 灰度共生矩阵
- class CGlcm
- {
- public:
-
CGlcm(void);
-
virtual
~CGlcm(void);
- public:
- int
*m_pMat1;
- int
*m_pMat2;
- int
*m_pMat3;
- int
*m_pMat4;
- protected:
- int
*m_pLine[4][256];
- int
m_nMin;
- int
m_nMax;
- int
m_nSum;
- public:
- //
计算共生矩阵
- //
参数:
- // 1.
pImageData: 图像数据指针,单通道,8位。
- // 2.
nLeft,nTop,nWidth,nHeight: 计算共生矩阵的区域。
- // 3.
nWidthStep: 行偏移量。
- // 4.
nScale: 尺度。
- // 5.
nReduction: 灰度级压缩。
- bool
CalGlcm(unsigned char
*pImageData, int
nLeft, int
nTop, int
nWidth, int
nHeight, int
nWidthStep, int
nScale, int
nReduction);
- //
共生矩阵特征
- //
参数:
- // 1.
Feature: 输出共生矩阵特征。
- void
GetFeature(GlcmFeature& Feature);
- };
- // 共生矩阵特征
- void
CGlcm::GetFeature(GlcmFeature& Feature)
- {
- int
x, y;
- int
nTheta;
- int
nValue;
- int
nTemp;
- double
dValue;
- double
dMean, dStdDev;
- double
dSum[256];
- //
清空内存
- memset(&Feature,
0, sizeof(Feature));
- //
方向循环
- for
(nTheta = 0; nTheta <
4; nTheta++)
- {
-
dMean = 0;
-
dStdDev = 0;
-
// 清空内存
-
memset(dSum, 0,
sizeof(dSum));
-
for (y =
m_nMin; y <= m_nMax; y++)
-
{
-
for
(x = m_nMin; x <=
m_nMax; x++)
-
{
-
nValue = m_pLine[nTheta][y][x];
-
if (nValue !=
0)
-
{
-
//
归一化共生矩阵
-
dValue =
(double) nValue /
(double) m_nSum;
-
nTemp = (x
- y) * (x - y);
-
//
角二阶矩/能量
-
Feature.ASM[nTheta]
+= (dValue * dValue);
-
//
熵
-
Feature.ENT[nTheta]
-= (dValue * log(dValue));
-
//
对比度
-
Feature.CON[nTheta]
+= (nTemp * dValue);
-
//
逆差矩/同质性
-
Feature.HOM[nTheta]
+= (dValue / (1 +
nTemp));
-
//
相关性
-
Feature.COR[nTheta]
+= (x * y * dValue);
-
dSum[y] +=
dValue;
-
}
-
}
-
}
-
for (y =
m_nMin; y <= m_nMax; y++)
-
{
-
dMean += (y
* dSum[y]);
-
}
-
for (y =
m_nMin; y <= m_nMax; y++)
-
{
-
dStdDev += ((y
- dMean) * (y - dMean)
* dSum[y]);
-
}
-
// 相关性
-
if (abs(dStdDev)
> 1e-15)
-
{
-
Feature.COR[nTheta] =
(Feature.COR[nTheta] - dMean *
dMean) / dStdDev;
-
}
-
else
-
{
-
Feature.COR[nTheta] =
0;
-
}
- }