灰度共生矩阵

灰度直方图是对整张图像所有像素点的灰度值进行统计的结果。

灰度共生矩阵是对图像上保持某种距离的两像素点的灰度状况进行统计的结果。

 

取图像 (N×N) 中任意一点 (x,y)及偏离它的另一点 (x+a,y+b),设该点对的灰度值为 (g1,g2)。令点(x,y) 在整个画面上移动,则会得到各种 (g1,g2)值,设灰度值的级数为 k,则(g1,g2) 的组合共有 k 的平方种。对于整个画面,统计出每一种 (g1,g2)值出现的次数,然后排列成一个方阵,再用(g1,g2) 出现的总次数将它们归一化为出现的概率P(g1,g2)这样的方阵称为灰度共生矩阵。距离差分值(a,b) 取不同的数值组合,可以得到不同情况下的联合概率矩阵。(a,b) 取值要根据纹理周期分布的特性来选择,对于较细的纹理,选取(1,0)、(1,1)、(2,0)等小的差分值。

当 a=1,b=0时,像素对是水平的,即0度扫描;

当 a=0,b=1 时,像素对是垂直的,即90度扫描;

当 a=1,b=1时,像素对是右对角线的,即45度扫描;

当 a=-1,b=1时,像素对是左对角线,即135度扫描。

 

  1 #include "cbir.h"
  2 
  3 #define GLCM_DISTEN 3  //偏离距离 
  4 #define GLCM_CLASS 8 //灰度降级  
  5 
  6 /*
  7 功能:
  8     求图像4个方向的灰度共生矩阵,并计算4个特征值,保存于featherVector[]
  9 参数:
 10     Grey_Image:灰度图像
 11     angleDirection:方向
 12     featherVector:保存特征值
 13 */
 14 
 15 int calGLCM(Mat Grey_Image, int angleDirection, double* featureVector)
 16 {
 17     int i, j;
 18     int width, height;
 19 
 20     width = Grey_Image.cols;
 21     height = Grey_Image.rows;
 22 
 23     int * glcm = new int[GLCM_CLASS * GLCM_CLASS];//灰度共生矩 8 * 8 一维数组
 24     int * histImage = new int[width * height];//降级后的图像 300 * 200 一维数组
 25 
 26     if (NULL == glcm || NULL == histImage)
 27         return 2;
 28 
 29     //降低图像灰度等级,把图像256个灰度级按顺序分为8个区间  
 30     uchar *data = (uchar*)Grey_Image.data;
 31     for (i = 0; i < height; i++) {
 32         for (j = 0; j < width; j++) {
 33             histImage[i * width + j] = (int)(data[width * i + j] * GLCM_CLASS / 256);// 除32取整 = 降级后的灰度
 34         }
 35     }
 36 
 37     //初始化共生矩阵  
 38     for (i = 0; i < GLCM_CLASS; i++)
 39         for (j = 0; j < GLCM_CLASS; j++)
 40             glcm[i * GLCM_CLASS + j] = 0;// 8 x 8 置零
 41 
 42     //计算灰度共生矩阵  
 43     int k, l;
 44 
 45     // 0°水平
 46     if (angleDirection == 0)
 47     {
 48         // 遍历降级后的图像 300 * 200
 49         for (i = 0; i < height; i++)
 50         {
 51             for (j = 0; j < width; j++)
 52             {
 53                 l = histImage[i * width + j];//取图像点(i,j)像素值
 54 
 55                 if (j + GLCM_DISTEN < width)
 56                 {
 57                     k = histImage[i * width + j + GLCM_DISTEN];//取图像点(i,j+d)像素值
 58                     glcm[l * GLCM_CLASS + k]++;// 将灰度共生矩中(value(i,j),value(i,j+d))值加1
 59                 }
 60             }
 61         }
 62     }
 63 
 64     // 90°垂直
 65     else if (angleDirection == 90)
 66     {
 67         for (i = 0; i < height; i++)
 68         {
 69             for (j = 0; j < width; j++)
 70             {
 71                 l = histImage[i * width + j];//取图像点(i,j)像素值
 72 
 73                 if (i + GLCM_DISTEN < height)
 74                 {
 75                     k = histImage[(i + GLCM_DISTEN) * width + j];//取图像点(i+d,j)像素值
 76                     glcm[l * GLCM_CLASS + k]++;// 将灰度共生矩中(value(i,j),value(i+d,j))值加1
 77                 }
 78             }
 79         }
 80     }
 81 
 82     // 45°
 83     else if (angleDirection == 45)
 84     {
 85         for (i = 0; i < height; i++)
 86         {
 87             for (j = 0; j < width; j++)
 88             {
 89                 l = histImage[i * width + j];//取图像点(i,j)像素值
 90 
 91                 if (j + GLCM_DISTEN < width && i + GLCM_DISTEN < height)
 92                 {
 93                     k = histImage[(i + GLCM_DISTEN) * width + j + GLCM_DISTEN];//取图像点(i+d,j+d)像素值
 94                     glcm[l * GLCM_CLASS + k]++;// 将灰度共生矩中(value(i,j),value(i+d,j+d))值加1
 95                 }
 96             }
 97         }
 98     }
 99 
100     // 135°
101     else if (angleDirection == 135)
102     {
103         for (i = 0; i < height; i++)
104         {
105             for (j = 0; j < width; j++)
106             {
107                 l = histImage[i * width + j];//取图像点(i,j)像素值
108 
109                 if (j - GLCM_DISTEN >= 0 && i - GLCM_DISTEN >= 0)
110                 {
111                     k = histImage[(i - GLCM_DISTEN) * width + j - GLCM_DISTEN];//取图像点(i+d,j-d)像素值
112                     glcm[l * GLCM_CLASS + k]++;// 将灰度共生矩中(value(i,j),value(i+d,j-d))值加1
113                 }
114             }
115         }
116     }
117 
118     //计算特征值  
119     double entropy = 0, energy = 0, contrast = 0, homogenity = 0;
120 
121     for (i = 0; i < GLCM_CLASS; i++)
122     {
123         for (j = 0; j < GLCM_CLASS; j++)
124         {
125             //
126             if (glcm[i * GLCM_CLASS + j] > 0)
127                 entropy -= glcm[i * GLCM_CLASS + j] * log10(double(glcm[i * GLCM_CLASS + j]));
128 
129             //能量  
130             energy += glcm[i * GLCM_CLASS + j] * glcm[i * GLCM_CLASS + j];
131 
132             //对比度  
133             contrast += (i - j) * (i - j) * glcm[i * GLCM_CLASS + j];
134 
135             //一致性  
136             homogenity += 1.0 / (1 + (i - j) * (i - j)) * glcm[i * GLCM_CLASS + j];
137         }
138     }
139 
140     //返回特征值  
141     i = 0;
142     featureVector[i++] = entropy;
143     featureVector[i++] = energy;
144     featureVector[i++] = contrast;
145     featureVector[i++] = homogenity;
146 
147     delete[] glcm;
148     delete[] histImage;
149 
150     return 0;
151 }
152 
153 
154 /*
155 功能:
156     纹理特征:灰度共生矩
157 参数:
158     src:传入图像
159 */
160 
161 double AveDev[8];// 保存 8 个特征值
162 
163 double getEigenValueByHDGSJ(Mat src)
164 {
165     Mat dst = rgb2grey(src);//RNG -> GRAY
166     imshow("1", dst);
167     waitKey(1000);
168 
169     // 垂直 0°
170     double GLCM_0[4] = { 0 };
171     calGLCM(dst, 0, GLCM_0);
172     cout << setprecision(20) << " 0°熵:" << GLCM_0[0] << endl;
173     cout << setprecision(20) << " 0°能量:" << GLCM_0[1] << endl;
174     cout << setprecision(20) << " 0°对比度:" << GLCM_0[2] << endl;
175     cout << setprecision(20) << " 0°一致性:" << GLCM_0[3] << endl;
176 
177     double Average0 = 0.25 * (GLCM_0[0] + GLCM_0[1] + GLCM_0[2] + GLCM_0[3]);
178     cout << setprecision(20) << " 0°均值:" << Average0 << endl;
179 
180     double temp0 = 1;
181     for (int i = 0; i < 4; i++)
182     {
183         temp0 += GLCM_0[i] * GLCM_0[i];
184     }
185     double StaDev0 = sqrt(0.25 * temp0);
186     cout << setprecision(20) << " 0°标准差:" << StaDev0 << endl;
187 
188     cout << endl;
189 
190     // 水平 90°
191     double GLCM_90[4] = { 0 };
192     calGLCM(dst, 90, GLCM_90);
193     cout << setprecision(20) << " 90°熵:" << GLCM_90[0] << endl;
194     cout << setprecision(20) << " 90°能量:" << GLCM_90[1] << endl;
195     cout << setprecision(20) << " 90°对比度:" << GLCM_90[2] << endl;
196     cout << setprecision(20) << " 90°一致性:" << GLCM_90[3] << endl;
197 
198     double Average90 = 0.25 * (GLCM_90[0] + GLCM_90[1] + GLCM_90[2] + GLCM_90[3]);
199     cout << setprecision(20) << " 90°均值:" << Average90 << endl;
200 
201     double temp90 = 1;
202     for (int i = 0; i < 4; i++)
203     {
204         temp90 += GLCM_90[i] * GLCM_90[i];
205     }
206     double StaDev90 = sqrt(0.25 * temp90);
207     cout << setprecision(20) << " 90°标准差:" << StaDev90 << endl;
208 
209     cout << endl;
210 
211     // 45°
212     double GLCM_45[4] = { 0 };
213     calGLCM(dst, 45, GLCM_45);
214     cout << setprecision(20) << " 45°熵:" << GLCM_45[0] << endl;
215     cout << setprecision(20) << " 45°能量:" << GLCM_45[1] << endl;
216     cout << setprecision(20) << " 45°对比度:" << GLCM_45[2] << endl;
217     cout << setprecision(20) << " 45°一致性:" << GLCM_45[3] << endl;
218 
219     double Average45 = 0.25 * (GLCM_45[0] + GLCM_45[1] + GLCM_45[2] + GLCM_45[3]);
220     cout << setprecision(20) << " 45°均值:" << Average45 << endl;
221 
222     double temp45 = 1;
223     for (int i = 0; i < 4; i++)
224     {
225         temp45 += GLCM_45[i] * GLCM_45[i];
226     }
227     double StaDev45 = sqrt(0.25 * temp45);
228     cout << setprecision(20) << " 45°标准差:" << StaDev45 << endl;
229 
230     cout << endl;
231 
232     // 135°
233     double GLCM_135[4] = { 0 };
234     calGLCM(dst, 135, GLCM_135);
235     cout << setprecision(20) << " 135°熵:" << GLCM_135[0] << endl;
236     cout << setprecision(20) << " 135°能量:" << GLCM_135[1] << endl;
237     cout << setprecision(20) << " 135°对比度:" << GLCM_135[2] << endl;
238     cout << setprecision(20) << " 135°一致性:" << GLCM_135[3] << endl;
239 
240     double Average135 = 0.25 * (GLCM_135[0] + GLCM_135[1] + GLCM_135[2] + GLCM_135[3]);
241     cout << setprecision(20) << " 135°均值:" << Average135 << endl;
242 
243     double temp135 = 1;
244     for (int i = 0; i < 4; i++)
245     {
246         temp135 += GLCM_135[i] * GLCM_135[i];
247     }
248     double StaDev135 = sqrt(0.25 * temp135);
249     cout << setprecision(20) << " 135°标准差:" << StaDev135 << endl;
250 
251     cout << endl;
252 
253     AveDev[0] = Average0;
254     AveDev[1] = Average90;
255     AveDev[2] = Average45;
256     AveDev[3] = Average135;
257     AveDev[4] = StaDev0;
258     AveDev[5] = StaDev90;
259     AveDev[6] = StaDev45;
260     AveDev[7] = StaDev135;
261 
262     return 0;
263 
264 }

 

 

 

posted @ 2016-07-09 19:00  中国病人  阅读(885)  评论(0编辑  收藏  举报