加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

计算灰度共生矩阵

(2011-12-19 08:47:48)
标签:

杂谈

分类: 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,θ)。

http://www.cqthx.com/mr/upload/gray.jpg http://www.cqthx.com/mr/upload/glcm.jpg
  1. class CGlcm  
  2.  
  3. public 
  4.     CGlcm(void);  
  5.     virtual ~CGlcm(void);  
  6. public 
  7.     int       *m_pMat1;  
  8.     int       *m_pMat2;  
  9.     int       *m_pMat3;  
  10.     int       *m_pMat4;  
  11. protected 
  12.     int       *m_pLine[4][256];  
  13.     int        m_nMin;  
  14.     int        m_nMax;  
  15.     int        m_nSum;  
  16. public 
  17.     // 计算共生矩阵   
  18.     // 参数:   
  19.     // 1. pImageData: 图像数据指针,单通道,8位。   
  20.     // 2. nLeft,nTop,nWidth,nHeight: 计算共生矩阵的区域。   
  21.     // 3. nWidthStep: 行偏移量。   
  22.     // 4. nScale: 尺度。   
  23.     // 5. nReduction: 灰度级压缩。   
  24.     bool CalGlcm(unsigned char *pImageData, int nLeft, int nTop, int nWidth, int nHeight, int nWidthStep, int nScale, int nReduction);  
  25. };  
  26. // 灰度共生矩阵   
  27. CGlcm::CGlcm(void 
  28. m_pMat1(NULL)  
  29. m_pMat2(NULL)  
  30. m_pMat3(NULL)  
  31. m_pMat4(NULL)  
  32. m_nMin(0)  
  33. m_nMax(0)  
  34. m_nSum(0)  
  35.  
  36.     int i, j;  
  37.     unsigned int nSize sizeof(int256 256;  
  38.     // 创建共生矩阵   
  39.     m_pMat1 (int*) malloc(nSize);  
  40.     m_pMat2 (int*) malloc(nSize);  
  41.     m_pMat3 (int*) malloc(nSize);  
  42.     m_pMat4 (int*) malloc(nSize);  
  43.     if (m_pMat1 && m_pMat2 && m_pMat3 && m_pMat4)  
  44.      
  45.         for (i 0, 0; 256; i++, += 256)  
  46.          
  47.             m_pLine[0][i] m_pMat1 j;  
  48.             m_pLine[1][i] m_pMat2 j;  
  49.             m_pLine[2][i] m_pMat3 j;  
  50.             m_pLine[3][i] m_pMat4 j;  
  51.          
  52.      
  53.  
  54. CGlcm::~CGlcm(void 
  55.  
  56.     // 释放共生矩阵   
  57.     if (m_pMat1) free(m_pMat1);  
  58.     if (m_pMat2) free(m_pMat2);  
  59.     if (m_pMat3) free(m_pMat3);  
  60.     if (m_pMat4) free(m_pMat4);  
  61.  
  62. // 计算共生矩阵   
  63. bool CGlcm::CalGlcm(unsigned char *pImageData, int nLeft, int nTop, int nWidth, int nHeight, int nWidthStep, int nScale, int nReduction)  
  64.  
  65.     bool bResult false 
  66.     int x0, x1, x2;  
  67.     int y0, y1, y2;  
  68.     int nGray;  
  69.     unsigned int nSize;  
  70.     unsigned char *pLine[3];  
  71.     if (pImageData)  
  72.      
  73.         // 灰度最值   
  74.         m_nMin 0xFF;  
  75.         m_nMax 0;  
  76.         pLine[1] pImageData nWidthStep nTop nLeft;  
  77.         for (y1 0; y1 nHeight; y1++)  
  78.          
  79.             for (x1 0; x1 nWidth; x1++)  
  80.              
  81.                 // 灰度级压缩   
  82.                 if (nReduction 0)  
  83.                  
  84.                     pLine[1][x1] pLine[1][x1] >> nReduction;  
  85.                  
  86.                 nGray pLine[1][x1];  
  87.                 if (nGray m_nMin)  
  88.                  
  89.                     m_nMin nGray;  
  90.                  
  91.                 else if (nGray m_nMax)  
  92.                  
  93.                     m_nMax nGray;  
  94.                  
  95.              
  96.             pLine[1] += nWidthStep;  
  97.          
  98.         // 累加和   
  99.         m_nSum nWidth nHeight 2;  
  100.         if (m_nMax >= m_nMin)  
  101.          
  102.             // 清空内存   
  103.             nSize sizeof(int(m_nMax m_nMin 1);  
  104.             for (y1 m_nMin; y1 <= m_nMax; y1++)  
  105.              
  106.                 memset(&m_pLine[0][y1][m_nMin], 0, nSize);  
  107.                 memset(&m_pLine[1][y1][m_nMin], 0, nSize);  
  108.                 memset(&m_pLine[2][y1][m_nMin], 0, nSize);  
  109.                 memset(&m_pLine[3][y1][m_nMin], 0, nSize);  
  110.              
  111.             // 计算共生矩阵   
  112.             pLine[1] pImageData nWidthStep nTop nLeft;  
  113.             for (y0 -nScale, y1 0, y2 nScale; y1 nHeight; y0++, y1++, y2++)  
  114.              
  115.                 pLine[0] pLine[1] nWidthStep;  
  116.                 pLine[2] pLine[1] nWidthStep;  
  117.                 for (x0 -nScale, x1 0, x2 nScale; x1 nWidth; x0++, x1++, x2++)  
  118.                  
  119.                     nGray pLine[1][x1];  
  120.                     //    
  121.                     if (x2 nWidth)  
  122.                      
  123.                         m_pLine[0][nGray][pLine[1][x2]]++;  
  124.                      
  125.                     // 45    
  126.                     if (y0 && x2 nWidth)  
  127.                      
  128.                         m_pLine[1][nGray][pLine[0][x2]]++;  
  129.                      
  130.                     // 90    
  131.                     if (y0 0)  
  132.                      
  133.                         m_pLine[2][nGray][pLine[0][x1]]++;  
  134.                      
  135.                     // 135    
  136.                     if (y0 && x0 0)  
  137.                      
  138.                         m_pLine[3][nGray][pLine[0][x0]]++;  
  139.                      
  140.                     // 180    
  141.                     if (x0 0)  
  142.                      
  143.                         m_pLine[0][nGray][pLine[1][x0]]++;  
  144.                      
  145.                     // 225    
  146.                     if (x0 && y2 nHeight)  
  147.                      
  148.                         m_pLine[1][nGray][pLine[2][x0]]++;  
  149.                      
  150.                     // 270    
  151.                     if (y2 nHeight)  
  152.                      
  153.                         m_pLine[2][nGray][pLine[2][x1]]++;  
  154.                      
  155.                     // 315    
  156.                     if (y2 nHeight && x2 nWidth)  
  157.                      
  158.                         m_pLine[3][nGray][pLine[2][x2]]++;  
  159.                      
  160.                  
  161.                 pLine[1] += nWidthStep;  
  162.              
  163.             bResult true 
  164.          
  165.      
  166.     return bResult;  
  167.  


提取共生矩阵特征



 

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

  1. 角二阶矩(ASM):是灰度共生矩阵元素值的平方和,所以也称能量。它反映了图像灰度分布均匀程度和纹理粗细度。如果共生矩阵的所有值均相等,则ASM值小;相反,如果其中一些值大而其它值小,则ASM值大。当共生矩阵中元素集中分布时,此时ASM值大。ASM值大表明一种较均一和规则变化的纹理模式。
    http://www.cqthx.com/mr/upload/glcm_asm.gif
  2. 熵(ENT):是图像所具有的信息量的度量,纹理信息也属于图像的信息,是一个随机性的度量,当共生矩阵中所有元素有最大的随机性、空间共生矩阵中所有值几乎相等时,共生矩阵中元素分散分布时,熵较大。它表示了图像中纹理的非均匀程度或复杂程度。
    http://www.cqthx.com/mr/upload/glcm_ent.gif
  3. 对比度(CON):反映了图像的清晰度和纹理沟纹深浅的程度。纹理沟纹越深,其对比度越大,视觉效果越清晰;反之,对比度小,则沟纹浅,效果模糊。灰度差即对比度大的象素对越多,这个值越大。灰度公生矩阵中远离对角线的元素值越大,CON越大。
    http://www.cqthx.com/mr/upload/glcm_con.gif
  4. 逆差距(HOM):反映图像纹理的同质性,度量图像纹理局部变化的多少。其值大则说明图像纹理的不同区域间缺少变化,局部非常均匀。
    http://www.cqthx.com/mr/upload/glcm_hom.gif
  5. 相关(COR):度量空间灰度共生矩阵元素在行或列方向上的相似程度,因此,相关值大小反映了图像中局部灰度相关性。当矩阵元素值均匀相等时,相关值就大;相反,如果矩阵像元值相差很大则相关值小。如果图像中有水平方向纹理,则水平方向矩阵的COR大于其余矩阵的COR值。
    http://www.cqthx.com/mr/upload/glcm_cor.gif
  1. #include <math.h>   
  2. // 共生矩阵特征   
  3. struct GlcmFeature  
  4.  
  5.     double ASM[4];  // 角二阶矩/能量   
  6.     double ENT[4];  //    
  7.     double CON[4];  // 对比度   
  8.     double HOM[4];  // 逆差矩/同质性   
  9.     double COR[4];  // 相关性   
  10. };  
  11. // 灰度共生矩阵   
  12. class CGlcm  
  13.  
  14. public 
  15.     CGlcm(void);  
  16.     virtual ~CGlcm(void);  
  17. public 
  18.     int       *m_pMat1;  
  19.     int       *m_pMat2;  
  20.     int       *m_pMat3;  
  21.     int       *m_pMat4;  
  22. protected 
  23.     int       *m_pLine[4][256];  
  24.     int        m_nMin;  
  25.     int        m_nMax;  
  26.     int        m_nSum;  
  27. public 
  28.     // 计算共生矩阵   
  29.     // 参数:   
  30.     // 1. pImageData: 图像数据指针,单通道,8位。   
  31.     // 2. nLeft,nTop,nWidth,nHeight: 计算共生矩阵的区域。   
  32.     // 3. nWidthStep: 行偏移量。   
  33.     // 4. nScale: 尺度。   
  34.     // 5. nReduction: 灰度级压缩。   
  35.     bool CalGlcm(unsigned char *pImageData, int nLeft, int nTop, int nWidth, int nHeight, int nWidthStep, int nScale, int nReduction);  
  36.     // 共生矩阵特征   
  37.     // 参数:   
  38.     // 1. Feature: 输出共生矩阵特征。   
  39.     void GetFeature(GlcmFeature& Feature);  
  40. };  
  41. // 共生矩阵特征   
  42. void CGlcm::GetFeature(GlcmFeature& Feature)  
  43.  
  44.     int x, y;  
  45.     int nTheta;  
  46.     int nValue;  
  47.     int nTemp;  
  48.     double dValue;  
  49.     double dMean, dStdDev;  
  50.     double dSum[256];  
  51.     // 清空内存   
  52.     memset(&Feature, 0, sizeof(Feature));  
  53.     // 方向循环   
  54.     for (nTheta 0; nTheta 4; nTheta++)  
  55.      
  56.         dMean 0;  
  57.         dStdDev 0;  
  58.         // 清空内存   
  59.         memset(dSum, 0, sizeof(dSum));  
  60.         for (y m_nMin; <= m_nMax; y++)  
  61.          
  62.             for (x m_nMin; <= m_nMax; x++)  
  63.              
  64.                 nValue m_pLine[nTheta][y][x];  
  65.                 if (nValue != 0)  
  66.                  
  67.                     // 归一化共生矩阵   
  68.                     dValue (doublenValue (doublem_nSum;  
  69.                     nTemp (x y) (x y);  
  70.                     // 角二阶矩/能量   
  71.                     Feature.ASM[nTheta] += (dValue dValue);  
  72.                     //    
  73.                     Feature.ENT[nTheta] -= (dValue log(dValue));  
  74.                     // 对比度   
  75.                     Feature.CON[nTheta] += (nTemp dValue);  
  76.                     // 逆差矩/同质性   
  77.                     Feature.HOM[nTheta] += (dValue (1 nTemp));  
  78.                     // 相关性   
  79.                     Feature.COR[nTheta] += (x dValue);  
  80.                     dSum[y] += dValue;  
  81.                  
  82.              
  83.          
  84.         for (y m_nMin; <= m_nMax; y++)  
  85.          
  86.             dMean += (y dSum[y]);  
  87.          
  88.         for (y m_nMin; <= m_nMax; y++)  
  89.          
  90.             dStdDev += ((y dMean) (y dMean) dSum[y]);  
  91.          
  92.         // 相关性   
  93.         if (abs(dStdDev) 1e-15)  
  94.          
  95.             Feature.COR[nTheta] (Feature.COR[nTheta] dMean dMean) dStdDev;  
  96.          
  97.         else  
  98.          
  99.             Feature.COR[nTheta] 0;  
  100.          
  101.      

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有