提取共生矩阵特征

计算灰度共生矩阵


   共生矩阵用两个位置的象素的联合概率密度来定义,它不仅反映亮度的分布特性,也反映具有同样亮度或接近亮度的象素之间的位置分布特性,是有关图象亮度变化的二阶统计特征。它是定义一组纹理特征的基础。

   灰度共生矩阵能反映出图象灰度关于方向、相邻间隔、变化幅度的综合信息。设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; }


提取共生矩阵特征


 

  为了能更直观地以共生矩阵描述纹理状况,从共生矩阵导出一些反映矩阵状况的参数,典型的有以下几种:

  1. 角 二阶矩(ASM):是灰度共生矩阵元素值的平方和,所以也称能量。它反映了图像灰度分布均匀程度和纹理粗细度。如果共生矩阵的所有值均相等,则ASM值 小;相反,如果其中一些值大而其它值小,则ASM值大。当共生矩阵中元素集中分布时,此时ASM值大。ASM值大表明一种较均一和规则变化的纹理模式。
  2. 熵(ENT):是图像所具有的信息量的度量,纹理信息也属于图像的信息,是一个随机性的度量,当共生矩阵中所有元素有最大的随机性、空间共生矩阵中所有值几乎相等时,共生矩阵中元素分散分布时,熵较大。它表示了图像中纹理的非均匀程度或复杂程度。
  3. 对比度(CON):反映了图像的清晰度和纹理沟纹深浅的程度。纹理沟纹越深,其对比度越大,视觉效果越清晰;反之,对比度小,则沟纹浅,效果模糊。灰度差即对比度大的象素对越多,这个值越大。灰度公生矩阵中远离对角线的元素值越大,CON越大。
  4. 逆差距(HOM):反映图像纹理的同质性,度量图像纹理局部变化的多少。其值大则说明图像纹理的不同区域间缺少变化,局部非常均匀。
  5. 相 关(COR):度量空间灰度共生矩阵元素在行或列方向上的相似程度,因此,相关值大小反映了图像中局部灰度相关性。当矩阵元素值均匀相等时,相关值就大; 相反,如果矩阵像元值相差很大则相关值小。如果图像中有水平方向纹理,则水平方向矩阵的COR大于其余矩阵的COR值。

#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; } } }

 

 

 

转载于:https://www.cnblogs.com/wqvbjhc/archive/2010/12/09/2465129.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值