1 前言

纹理特征在地物光谱特征比较相似的时候常作为一种特征用于图像的分类和信息提取。本文主要介绍基于灰度共生矩阵的图像纹理提取。

2 灰度共生矩阵

纹理石油灰度分布在空间位置上反复出现而形成的,因而图像空间中相隔某距离的两个像素之间存在一定的灰度关系,即图像中灰度的空间相关特性。灰度共生矩阵是一种通过研究灰度的空间相关特性来描述纹理的常用方法。

有一个网站提供了非常详细的关于灰度共生矩阵的介绍,我在这里就不赘述了。 

3 纹理提取的算法流程

本文重点说明一下遥感影像纹理提取的算法流程,如下图1所示:

 

python使用灰度共生矩阵提取纹理特征向量 envi灰度共生矩阵提取纹理_i++

图 1 纹理提取算法流程

具体描述如下:

1)        灰度降级,对原始影像进行灰度降级如8,16,32,64等;

纹理计算的灰度降级策略来源于IDL的bytscl函数介绍,具体描述如下:

 

python使用灰度共生矩阵提取纹理特征向量 envi灰度共生矩阵提取纹理_灰度_02

图 2 灰度降级

2)        根据设定好的窗口大小,逐窗口计算灰度共生矩阵;

3)        根据选择的二阶统计量,计算纹理值。

4  纹理算子

协同性(GLCM_HOM):对应ENVI的Homogeneity

python使用灰度共生矩阵提取纹理特征向量 envi灰度共生矩阵提取纹理_灰度_03

 

反差性(GLCM_CON):

python使用灰度共生矩阵提取纹理特征向量 envi灰度共生矩阵提取纹理_#include_04

 

非相似性(GLCM_DIS):

python使用灰度共生矩阵提取纹理特征向量 envi灰度共生矩阵提取纹理_#include_05

 

均值GLCM_MEAN:对应ENVI的Mean

python使用灰度共生矩阵提取纹理特征向量 envi灰度共生矩阵提取纹理_i++_06

 

方差GLCM_VAR:对应ENVI的Variance

python使用灰度共生矩阵提取纹理特征向量 envi灰度共生矩阵提取纹理_i++_07

 

角二阶矩GLCM_ASM:对应ENVI的Second Moment

python使用灰度共生矩阵提取纹理特征向量 envi灰度共生矩阵提取纹理_i++_08

 

相关性GLCM_COR:对应ENVI的Correlation

python使用灰度共生矩阵提取纹理特征向量 envi灰度共生矩阵提取纹理_灰度_09

 

GLDV角二阶矩GLDV_ASM:

 

python使用灰度共生矩阵提取纹理特征向量 envi灰度共生矩阵提取纹理_灰度_10

熵GLCM_ENTROPY:对应ENVI的Entropy

python使用灰度共生矩阵提取纹理特征向量 envi灰度共生矩阵提取纹理_灰度_11

 

归一化灰度矢量均值GLDV_MEAN:对应ENVI的Dissimilarity

python使用灰度共生矩阵提取纹理特征向量 envi灰度共生矩阵提取纹理_#include_12

 

归一化角二阶矩GLDV_CON:对应ENVI的Contrast

python使用灰度共生矩阵提取纹理特征向量 envi灰度共生矩阵提取纹理_#include_13

 

5  代码实现

要是有哪位大神可以指点下如何提高纹理计算的效率感激不尽~

先上传头文件和源文件

1 #pragma once
 2 #include <iostream>
 3 #include <string>
 4 #include <vector>
 5 
 6 class CCo_occurrenceTextureExtration
 7 {
 8 public:
 9     CCo_occurrenceTextureExtration(void);
10     ~CCo_occurrenceTextureExtration(void);
11 
12 
13     typedef enum ANGLE_TYPE
14     {
15         DEGREE_0,
16         DEGREE_45,
17         DEGREE_90,
18         DEGREE_135
19     };
20     typedef enum LIST_TYPE
21     {
22         GLCM_HOM,
23         GLCM_CON, 
24         GLCM_DIS,
25         GLCM_MEAN, 
26         GLCM_VAR, 
27         GLCM_ASM,
28         GLCM_COR,
29         GLDV_ASM,  
30         GLCM_ENTROPY,
31         GLDV_MEAN, 
32         GLDV_CON,
33     };
34 
35 
36     //影像灰度降级(包括直方图均衡化)
37     bool Init();
38     bool ReduceGrayLevel();
39     bool ExtraTextureWinEXE();
40     bool ExtraTexturePixEXE();
41     int ExtraTexturePixOpenCLEXE();
42 private:
43     char* LoadProgSource(const char* cFilename, const char* cPreamble, size_t* szFinalLength);
44     bool GetGrayCoocurrenceMatrix(std::vector<std::vector<int>>grayValue,
45         std::vector<std::vector<float>> &grayMatrix,int &m_count);
46     float CalGLCMStatistics(std::vector<std::vector<float>> grayMatrix,
47         const int count);
48     double* cdf(int *h,int length);
49 
50 public:
51     std::string m_strInFileName;
52     std::string m_strOutFileName;
53     std::string m_strReduceLevelFileName;
54     int m_iWidth;
55     int m_iHeigth;
56     int m_iBandCount;
57     int *m_BandMap;
58     int m_AngleMode;
59     int m_TextureMode;
60     int m_dis;
61     int m_grayLevel;
62     int m_winWidth;
63     int m_winHeigth;
64     
65 };

源文件如下:

1 #include "Co_occurrenceTextureExtration.h"
  2 #include <gdal_alg_priv.h>
  3 #include <gdal_priv.h>
  4 #include <math.h>
  5 #include <omp.h>
  6 #include <CL/cl.h>
  7 #include <stdlib.h>
  8 #include <malloc.h>
  9 #pragma comment(lib,"OpenCL.lib")
 10 
 11 CCo_occurrenceTextureExtration::CCo_occurrenceTextureExtration( )
 12 {
 13     m_BandMap = NULL;
 14 }
 15 CCo_occurrenceTextureExtration::~CCo_occurrenceTextureExtration(void)
 16 {
 17     if(!m_BandMap){
 18         delete []m_BandMap;
 19     }
 20 }
 21 
 22 bool CCo_occurrenceTextureExtration::Init()
 23 {
 24     GDALAllRegister();
 25     GDALDataset *poDS = (GDALDataset*)GDALOpen(m_strInFileName.c_str(),GA_ReadOnly);
 26     m_iWidth = poDS->GetRasterXSize();
 27     m_iHeigth = poDS->GetRasterYSize();
 28     m_iBandCount = poDS->GetRasterCount();
 29 
 30     m_BandMap = new int[m_iBandCount];
 31     int i = 0;
 32     while(i < m_iBandCount){
 33         m_BandMap[i] = i+1;
 34         i++;
 35     }
 36     GDALClose((GDALDatasetH)poDS);
 37     return TRUE;
 38 }
 39 
 40 bool CCo_occurrenceTextureExtration::ReduceGrayLevel()
 41 {
 42     //直方图均衡化
 43     ///// 统计直方图
 44     GDALAllRegister();
 45     GDALDataset *poDS = (GDALDataset*)GDALOpen(m_strInFileName.c_str(),GA_ReadOnly);
 46     double adfMSSGeoTransform[6] = {0};
 47     poDS->GetGeoTransform(adfMSSGeoTransform);
 48     GDALDataType eDT = poDS->GetRasterBand(1)->GetRasterDataType();
 49     //创建文件
 50     GDALDriver *poOutDriver = (GDALDriver*)GDALGetDriverByName("GTIFF");
 51     GDALDataset *poOutDS  = poOutDriver->Create(m_strReduceLevelFileName.c_str(),
 52         m_iWidth,m_iHeigth,m_iBandCount,GDT_Byte,NULL);
 53     poOutDS->SetGeoTransform(adfMSSGeoTransform);
 54     poOutDS->SetProjection(poDS->GetProjectionRef());
 55     for(int i = 0;i<m_iBandCount;i++){
 56         double *bandMINMAX = new double[2];
 57         GDALRasterBand *poBand = poDS->GetRasterBand(m_BandMap[i]);
 58         GDALRasterBand *poNewBand = poOutDS->GetRasterBand(i+1);
 59         poBand->ComputeRasterMinMax(FALSE,bandMINMAX);
 60         for(int j = 0;j<m_iHeigth;j++){
 61             double *readBuff = new double[m_iWidth];
 62             unsigned char*writeBuff = new unsigned char[m_iWidth];
 63             poBand->RasterIO(GF_Read,0,j,m_iWidth,1,readBuff,m_iWidth,1,GDT_Float64,0,0);
 64             int k = 0;
 65             while(k<m_iWidth){
 66                 int tmp = 0;
 67                 if(eDT == GDT_Float32 || eDT == GDT_Float64){
 68                     tmp = int((m_grayLevel-1+0.99999)*(readBuff[k] - bandMINMAX[0])/(bandMINMAX[1] - bandMINMAX[0]));
 69                 }else{
 70                     tmp = int((m_grayLevel)*(readBuff[k] - bandMINMAX[0] - 1)/(bandMINMAX[1] - bandMINMAX[0]));
 71                 }
 72                 writeBuff[k] = unsigned char(tmp);
 73                 k++;
 74             }
 75             CPLErr str = poNewBand->RasterIO(GF_Write,0,j,m_iWidth,1,writeBuff,m_iWidth,1,GDT_Byte,0,0);
 76             delete []readBuff;readBuff = NULL;
 77             delete []writeBuff;writeBuff = NULL;
 78         }
 79         delete []bandMINMAX;bandMINMAX = NULL;
 80     }
 81     GDALClose((GDALDatasetH) poDS);
 82     GDALClose((GDALDatasetH) poOutDS);
 83     return TRUE;
 84 }
 85 
 86 double* CCo_occurrenceTextureExtration::cdf( int *h,int length )
 87 {
 88     int n = 0;  
 89     for( int i = 0; i < length - 1; i++ )  
 90     {  
 91         n += h[i];  
 92     }  
 93     double* p = new double[length];  
 94     int c = h[0];  
 95     p[0] = ( double )c / n;  
 96     for( int i = 1; i < length - 1; i++ )  
 97     {  
 98         c += h[i];  
 99         p[i] = ( double )c / n;  
100     }  
101     return p; 
102 }
103 
104 char* CCo_occurrenceTextureExtration::LoadProgSource( const char* cFilename, const char* cPreamble, size_t* szFinalLength )
105 {
106     FILE* pFileStream = NULL;
107     size_t szSourceLength;
108 
109     // open the OpenCL source code file
110     pFileStream = fopen(cFilename, "rb");
111     if(pFileStream == 0) 
112     {     
113         return NULL;
114     }
115 
116     size_t szPreambleLength = strlen(cPreamble);
117 
118     // get the length of the source code
119     fseek(pFileStream, 0, SEEK_END); 
120     szSourceLength = ftell(pFileStream);
121     fseek(pFileStream, 0, SEEK_SET); 
122 
123     // allocate a buffer for the source code string and read it in
124     char* cSourceString = (char *)malloc(szSourceLength + szPreambleLength + 1); 
125     memcpy(cSourceString, cPreamble, szPreambleLength);
126     if (fread((cSourceString) + szPreambleLength, szSourceLength, 1, pFileStream) != 1)
127     {
128         fclose(pFileStream);
129         free(cSourceString);
130         return 0;
131     }
132 
133     // close the file and return the total length of the combined (preamble + source) string
134     fclose(pFileStream);
135     if(szFinalLength != 0)
136     {
137         *szFinalLength = szSourceLength + szPreambleLength;
138     }
139     cSourceString[szSourceLength + szPreambleLength] = '\0';
140 
141     return cSourceString;
142 }
143 
144 bool CCo_occurrenceTextureExtration::GetGrayCoocurrenceMatrix(std::vector<std::vector<int>>grayValue,
145                                                               std::vector<std::vector<float>> &m_grayMatrix,
146                                                               int &m_count)
147 {
148     int i,j,r,c;
149     m_count = 0;
150     int ii = 0;
151 
152     switch(m_AngleMode)
153     {
154     case DEGREE_0:
155         i = 0;
156         while(i<m_winHeigth){
157             j = 0;
158             while(j<m_winWidth){
159                 int endR = i;
160                 int endC = j + m_dis;
161                 if(endC < m_winWidth){
162                     r = grayValue[i][j];
163                     c = grayValue[endR][endC];
164                     m_grayMatrix[r][c] += 1;
165                     m_grayMatrix[c][r] += 1;
166                     m_count = m_count+2;
167                 }
168                 j++;
169             }
170             i++;
171         }
172         break;
173     case DEGREE_45:
174         i = 0;
175         while(i<m_winHeigth){
176             j = 0;
177             while(j<m_winWidth){
178                 int endR = i - m_dis;
179                 int endC = j + m_dis;
180                 if(endR>=0 && endR < m_winHeigth && endC >=0 && endC < m_winWidth){
181                     r = grayValue[i][j];
182                     c = grayValue[endR][endC];
183                     m_grayMatrix[r][c] += 1;
184                     m_grayMatrix[c][r] += 1;
185                     m_count = m_count+2;
186                 }
187                 j++;
188             }
189             i++;
190         }
191         break;
192     case DEGREE_90:
193         i= 0;
194         while(i<m_winHeigth){
195             j = 0;
196             while(j < m_winWidth){
197                 int endR = i - m_dis;
198                 int endC = j;
199                 if(endR >= 0){
200                     r = grayValue[i][j];
201                     c = grayValue[endR][endC];
202                     m_grayMatrix[r][c] += 1;
203                     m_grayMatrix[c][r] += 1;
204                     m_count = m_count+2;
205                 }
206                 j++;
207             }
208             i++;
209         }
210         break;
211     case DEGREE_135:
212         i = 0;
213         while(i<m_winHeigth){
214             j = 0;
215             while(j<m_winWidth){
216                 int endR = i - m_dis;
217                 int endC = j - m_dis;
218                 if(endR >= 0 && endC >= 0){
219                     r = grayValue[i][j];
220                     c = grayValue[endR][endC];
221                     m_grayMatrix[r][c] += 1;
222                     m_grayMatrix[c][r] += 1;
223                     m_count = m_count+2;
224                 }
225                 j++;
226             }
227             i++;
228         }
229         break;
230     default:
231         return FALSE;
232     }
233     return TRUE;
234 }
235 
236 float CCo_occurrenceTextureExtration::CalGLCMStatistics(std::vector<std::vector<float>> m_grayMatrix,
237                                                         const int m_count)
238 {
239     int i,j,k;
240     float imean = 0.0f;
241     float jmean = 0.0f;
242     float ivar = 0.0f;
243     float jvar = 0.0f;;
244     float res = 0.0f;
245     switch(m_TextureMode)
246     {
247     case GLCM_HOM:  //同质性
248         i = 0;
249         while(i < m_grayLevel){
250             j = 0;
251             while(j < m_grayLevel){
252                 if(m_grayMatrix[i][j] != 0){
253                     float Pij = m_grayMatrix[i][j]*1.0f/m_count;
254                     res += Pij/(1 + (i-j)*(i-j));
255                 }
256                 j++;
257             }
258             i++;
259         }
260         break;
261     case GLCM_CON:  //对比度
262         i = 0;
263         while(i < m_grayLevel){
264             j = 0;
265             while(j < m_grayLevel){
266                 if(m_grayMatrix[i][j] != 0){
267                     float Pij = m_grayMatrix[i][j]*1.0f/m_count;
268                     res += Pij*(i-j)*(i-j);
269                 }
270                 j++;
271             }
272             i++;
273         }
274         break;
275     case GLCM_DIS:  //非相似性
276         i = 0;
277         while(i < m_grayLevel){
278             j = 0;
279             while(j < m_grayLevel){
280                 if(m_grayMatrix[i][j] != 0){
281                     float Pij = m_grayMatrix[i][j]*1.0f/m_count;
282                     res += Pij*std::abs(i-j);
283                 }
284                 j++;
285             }
286             i++;
287         }
288         break;
289     case GLCM_COR:  // 相关性
290         i = 0;
291         while(i < m_grayLevel){
292             j = 0;
293             while(j < m_grayLevel){
294                 if(m_grayMatrix[i][j] != 0){
295                     float Pij = m_grayMatrix[i][j]*1.0f/m_count;
296                     imean += Pij * i;
297                     jmean += Pij * j;
298                 }
299                 j++;
300             }
301             i++;
302         }
303         //  var
304         i = 0;
305         while(i < m_grayLevel){
306             j = 0;
307             while(j < m_grayLevel){
308                 if(m_grayMatrix[i][j] != 0){
309                     float Pij = m_grayMatrix[i][j]*1.0f/m_count;
310                     ivar += Pij * (i - imean)*(i - imean);
311                     jvar += Pij * (j - imean)*(j - imean);
312                 }
313                 j++;
314             }
315             i++;
316         }
317         // xiangguanx
318         i = 0;
319         while(i < m_grayLevel){
320             j = 0;
321             while(j < m_grayLevel){
322                 if(m_grayMatrix[i][j] != 0){
323                     float Pij = m_grayMatrix[i][j]*1.0f/m_count;
324                     res += (Pij *(i - imean)*(j - jmean))/sqrt(ivar*jvar);
325                 }
326                 j++;
327             }
328             i++;
329         }
330         break;
331     case GLCM_MEAN:  // 均值
332         i = 0;
333         while(i < m_grayLevel){
334             j = 0;
335             while(j < m_grayLevel){
336                 if(m_grayMatrix[i][j] != 0){
337                     float Pij = m_grayMatrix[i][j]*1.0f/m_count;
338                     imean += Pij * i;
339                     //jmean += Pij * j;
340                 }
341                 j++;
342             }
343             i++;
344         }
345         res = imean;
346         break;
347     case GLCM_VAR:  // 方差
348         //  mean
349         i = 0;
350         while(i < m_grayLevel){
351             j = 0;
352             while(j < m_grayLevel){
353                 if(m_grayMatrix[i][j] != 0){
354                     float Pij = m_grayMatrix[i][j]*1.0f/m_count;
355                     imean += Pij * i;
356                 }
357                 j++;
358             }
359             i++;
360         }
361         //  var
362         i = 0;
363         while(i < m_grayLevel){
364             j = 0;
365             while(j < m_grayLevel){
366                 if(m_grayMatrix[i][j] != 0){
367                     float Pij = m_grayMatrix[i][j]*1.0f/m_count;
368                     ivar += Pij * (i - imean)*(i - imean);
369                 }
370                 j++;
371             }
372             i++;
373         }
374         //res = (ivar + jvar)/2;
375         res = ivar;
376         break;
377     case GLCM_ASM:  // 角二阶矩
378         i = 0;
379         while(i < m_grayLevel){
380             j = 0;
381             while(j < m_grayLevel){
382                 if(m_grayMatrix[i][j] != 0){
383                     float Pij = m_grayMatrix[i][j]*1.0f/m_count;
384                     res += Pij*Pij;
385                 }
386                 j++;
387             }
388             i++;
389         }
390         break;
391     case GLCM_ENTROPY:  // 熵
392         i = 0;
393         while(i < m_grayLevel){
394             j = 0;
395             while(j < m_grayLevel){
396                 if(m_grayMatrix[i][j] != 0){
397                     float Pij = m_grayMatrix[i][j]*1.0f/m_count;
398                     res += -1.0f*Pij * log(Pij);
399                 }
400                 j++;
401             }
402             i++;
403         }
404         break;
405     case GLDV_MEAN:
406         k = 0;
407         while(k<m_grayLevel){
408             i = 0;
409             while(i < m_grayLevel){
410                 j = 0;
411                 while(j < m_grayLevel){
412                     if(m_grayMatrix[i][j] != 0 && std::abs(i-j)== k){
413                         float Pij = m_grayMatrix[i][j]*1.0f/m_count;
414                         res += Pij*k;
415                     }
416                     j++;
417                 }
418                 i++;
419             }
420             k++;
421         }
422         break;
423     case GLDV_CON:
424         k = 0;
425         while(k<m_grayLevel){
426             i = 0;
427             while(i < m_grayLevel){
428                 j = 0;
429                 while(j < m_grayLevel){
430                     if(m_grayMatrix[i][j] != 0 && std::abs(i-j)== k){
431                         float Pij = m_grayMatrix[i][j]*1.0f/m_count;
432                         res += Pij*k*k;
433                     }
434                     j++;
435                 }
436                 i++;
437             }
438             k++;
439         }
440         break;
441     case GLDV_ASM:
442         k = 0;
443         while(k<m_grayLevel){
444             i = 0;
445             while(i < m_grayLevel){
446                 j = 0;
447                 while(j < m_grayLevel){
448                     if(m_grayMatrix[i][j] != 0 && std::abs(i-j)== k){
449                         float Pij = m_grayMatrix[i][j]*1.0f/m_count;
450                         res += Pij*Pij;
451                     }
452                     j++;
453                 }
454                 i++;
455             }
456             k++;
457         }
458         break;
459     }
460     return res;
461 }
462 
463 bool CCo_occurrenceTextureExtration::ExtraTextureWinEXE()
464 {
465     //读影像
466     GDALAllRegister();
467     GDALDataset *poDS = (GDALDataset*)GDALOpen(m_strReduceLevelFileName.c_str(),GA_ReadOnly);
468     if(!poDS){
469         return FALSE;
470     }
471     //GDALRasterBand *poBand = poDS->GetRasterBand(1);
472     double adfMSSGeoTransform[6] = {0};
473     poDS->GetGeoTransform(adfMSSGeoTransform);
474     //创建文件
475     GDALDriver *poOutDriver = (GDALDriver*)GDALGetDriverByName("GTIFF");
476     GDALDataset *poOutDS  = poOutDriver->Create(m_strOutFileName.c_str(),
477         m_iWidth,m_iHeigth,m_iBandCount,GDT_Float32,NULL);
478     poOutDS->SetGeoTransform(adfMSSGeoTransform);
479     poOutDS->SetProjection(poDS->GetProjectionRef());
480     int b = 0;
481     while(b<m_iBandCount){
482         GDALRasterBand *poBand = poDS->GetRasterBand(b+1);
483         GDALRasterBand *poNewBand = poOutDS->GetRasterBand(b+1);
484         int i = 0;
485         while(i<m_iHeigth){
486             int startR = i;    
487             int endR = startR + m_winHeigth - 1;
488             if(endR > m_iHeigth-1){
489                 endR = m_iHeigth - 1;
490                 startR = endR - m_winHeigth + 1;
491             }
492             unsigned char *readBuff = new unsigned char[m_iWidth * m_winHeigth];
493             float *writeBuff = new float[m_iWidth* m_winHeigth];
494             poBand->RasterIO(GF_Read,0,startR,m_iWidth,m_winHeigth,readBuff,m_iWidth,
495                 m_winHeigth,GDT_Byte,0,0);
496 
497             int j = 0;
498             while(j < m_iWidth){
499                 int startC = j;            
500                 int endC = startC + m_winWidth - 1;
501                 if(endC > m_iWidth - 1){
502                     endC = m_iWidth - 1;
503                     startC = endC - m_winWidth + 1;
504                 }
505                 std::vector<std::vector<int>> grayValue;
506                 grayValue = std::vector<std::vector<int>>(m_winHeigth,std::vector<int>(m_winWidth,0));
507                 std::vector<std::vector<float>> grayMatrix;
508                 grayMatrix = std::vector<std::vector<float>>(m_grayLevel,std::vector<float>(m_grayLevel,0.0f));
509                 int k = 0;
510                 while(k < m_winHeigth){
511                     int l = 0 ;
512                     while(l < m_winWidth){
513                         grayValue[k][l] = int(readBuff[k*m_iWidth +startC+l]);
514                         l++;
515                     }
516                     k++;
517                 }
518                 int count = 0;
519                 if(!GetGrayCoocurrenceMatrix(grayValue,grayMatrix,count)){
520                     return FALSE;
521                 }
522                 float tmp = CalGLCMStatistics(grayMatrix,count);            
523                 k = 0;
524                 while(k < m_winHeigth){
525                     int l = 0 ;
526                     while(l < m_winWidth){
527                         writeBuff[k*m_iWidth +startC+l] = tmp;
528                         l++;
529                     }
530                     k++;
531                 }
532                 j = j + m_winWidth;
533             }
534             poNewBand->RasterIO(GF_Write,0,startR,m_iWidth,m_winHeigth,writeBuff,m_iWidth,
535                 m_winHeigth,GDT_Float32,0,0);
536             //更新灰度共生矩阵
537             delete []readBuff;readBuff = NULL;
538             delete []writeBuff;writeBuff = NULL;
539             i = i + m_winHeigth;
540         }
541         b++;
542     }
543     GDALClose((GDALDatasetH)poDS);
544     GDALClose((GDALDatasetH)poOutDS);
545     return TRUE;
546 }
547 
548 bool CCo_occurrenceTextureExtration::ExtraTexturePixEXE()
549 {
550     //读影像
551     GDALAllRegister();
552     GDALDataset *poDS = (GDALDataset*)GDALOpen(m_strReduceLevelFileName.c_str(),GA_ReadOnly);
553     if(!poDS){
554         return FALSE;
555     }
556     double adfMSSGeoTransform[6] = {0};
557     poDS->GetGeoTransform(adfMSSGeoTransform);
558     //创建文件
559     GDALDriver *poOutDriver = (GDALDriver*)GDALGetDriverByName("GTIFF");
560     GDALDataset *poOutDS  = poOutDriver->Create(m_strOutFileName.c_str(),
561         m_iWidth,m_iHeigth,m_iBandCount,GDT_Float32,NULL);
562     poOutDS->SetGeoTransform(adfMSSGeoTransform);
563     poOutDS->SetProjection(poDS->GetProjectionRef());
564     int nLineSpace,nPixSpace,nBandSpace;
565     nLineSpace = sizeof(unsigned char)*m_iWidth*m_iBandCount;
566     nPixSpace = 0;
567     nBandSpace = sizeof(unsigned char)*m_iWidth;
568 
569     int iNumRow = 128;  // 分块读取的行数
570     int overloadPix = m_winHeigth-1;
571     if(m_iHeigth < iNumRow && m_iHeigth > m_winHeigth){
572         iNumRow = m_winHeigth;
573     }
574     if(m_iHeigth < m_winHeigth){
575         return FALSE;
576     }
577     int loopNum = (m_iHeigth + iNumRow - 1)/(iNumRow - overloadPix);
578     float stepProcess = 100.0f/(100.0f*loopNum*(iNumRow - overloadPix));
579 
580     for(int i = 0;i<loopNum;i++){
581         int tmpRowNum = iNumRow;
582         int startR = i*iNumRow - i*(overloadPix/2);
583         if(startR < 0)
584         {
585             startR = 0;
586         }
587         int endR = startR + tmpRowNum - 1;
588         if(endR > m_iHeigth -1 ){
589             endR = m_iHeigth -1;
590             tmpRowNum = endR - startR + 1;
591         }
592         unsigned char *readBuff = new unsigned char[tmpRowNum*m_iWidth*m_iBandCount];
593         float *writeBuff = new float[m_iWidth*m_iBandCount*(tmpRowNum - overloadPix)];
594         poDS->RasterIO(GF_Read,0,startR,m_iWidth,tmpRowNum,readBuff,m_iWidth,
595             tmpRowNum,GDT_Byte,m_iBandCount,m_BandMap,nPixSpace,nLineSpace,nBandSpace);
596 
597         for(int iR = overloadPix/2;iR < tmpRowNum - overloadPix/2;iR++)
598         {
599             // zhuyong 2016 10 17
600 #pragma omp parallel for num_threads(2)
601             for(int j = 0;j < m_iWidth;j++)
602             {
603                 int startC = j - m_winWidth/2;
604                 int endC = j + m_winWidth/2;
605                 if(startC<0){
606                     startC = 0;
607                     endC = startC + m_winWidth -1;
608                 }
609                 if(endC > m_iWidth-1){
610                     endC = m_iWidth -1;
611                     startC = endC - m_winWidth +1;
612                 }
613                 // 波段计算
614                 int b = 0;
615                 while(b < m_iBandCount){
616                     // 获取灰度值
617                     std::vector<std::vector<int>> grayValue;
618                     grayValue = std::vector<std::vector<int>>(m_winHeigth,std::vector<int>(m_winWidth,0));
619                     std::vector<std::vector<float>> grayMatrix;
620                     grayMatrix = std::vector<std::vector<float>>(m_grayLevel,std::vector<float>(m_grayLevel,0.0f));
621                     int k = 0;
622                     while(k < m_winHeigth){
623                         int l = 0 ;
624                         while(l < m_winWidth){
625                             grayValue[k][l] = int(readBuff[(iR  - overloadPix/2 + k)*m_iWidth*m_iBandCount + b*m_iWidth + startC+l]);
626                             l++;
627                         }
628                         k++;
629                     }
630                     int count = 0;
631                     if(!GetGrayCoocurrenceMatrix(grayValue,grayMatrix,count)){
632                     }
633                     float tmp = CalGLCMStatistics(grayMatrix,count);
634                     writeBuff[(iR- overloadPix/2)*m_iWidth*m_iBandCount+ b*m_iWidth + j] = tmp;
635                     b++;
636                 }
637             }
638         }
639         poOutDS->RasterIO(GF_Write,0,startR+overloadPix/2,m_iWidth,tmpRowNum - overloadPix,writeBuff,
640             m_iWidth,tmpRowNum - overloadPix,GDT_Float32,m_iBandCount,m_BandMap,nPixSpace,sizeof(float)*m_iWidth*m_iBandCount,
641             sizeof(float)*m_iWidth);
642         delete []readBuff;readBuff = NULL;
643         delete []writeBuff;writeBuff = NULL;
644     }
645 
646     GDALClose((GDALDatasetH)poDS);
647     GDALClose((GDALDatasetH)poOutDS);
648     return TRUE;
649 }
650 
651 int CCo_occurrenceTextureExtration::ExtraTexturePixOpenCLEXE()
652 {
653     //读影像
654     GDALAllRegister();
655     GDALDataset *poDS = (GDALDataset*)GDALOpen(m_strReduceLevelFileName.c_str(),GA_ReadOnly);
656     if(!poDS){
657         return FALSE;
658     }
659     double adfMSSGeoTransform[6] = {0};
660     poDS->GetGeoTransform(adfMSSGeoTransform);
661     //创建文件
662     GDALDriver *poOutDriver = (GDALDriver*)GDALGetDriverByName("GTIFF");
663     GDALDataset *poOutDS  = poOutDriver->Create(m_strOutFileName.c_str(),
664         m_iWidth,m_iHeigth,m_iBandCount,GDT_Float32,NULL);
665     poOutDS->SetGeoTransform(adfMSSGeoTransform);
666     poOutDS->SetProjection(poDS->GetProjectionRef());
667 
668     int nLineSpace,nPixSpace,nBandSpace;
669     nLineSpace = sizeof(unsigned char)*m_iWidth*m_iBandCount;
670     nPixSpace = 0;
671     nBandSpace = sizeof(unsigned char)*m_iWidth;
672 
673     int iNumRow = 32;  // 分块读取的行数
674     int overloadPix = m_winHeigth-1;
675     if(m_iHeigth < iNumRow && m_iHeigth > m_winHeigth){
676         iNumRow = m_winHeigth;
677     }
678     if(m_iHeigth < m_winHeigth){
679         return FALSE;
680     }
681     int loopNum = ceil((m_iHeigth*1.0f - iNumRow)/(iNumRow - overloadPix)) + 1;
682 
683     // OpenCL部分 =============== 1 创建平台
684     cl_uint num_platforms;
685     cl_int ret = clGetPlatformIDs(0,NULL,&num_platforms);
686     if(ret != CL_SUCCESS || num_platforms < 1){
687         printf("clGetPlatformIDs Error\n");
688         return -1;
689     }
690     cl_platform_id platform_id = NULL;
691     ret = clGetPlatformIDs(1,&platform_id,NULL);
692     if(ret != CL_SUCCESS){
693         printf("clGetPlatformIDs Error2\n");
694         return -1;
695     }
696 
697     // OpenCL部分 =============== 2 获得设备
698     cl_uint num_devices;
699     ret = clGetDeviceIDs(platform_id,CL_DEVICE_TYPE_GPU,0,NULL,
700         &num_devices);
701     if(ret != CL_SUCCESS || num_devices < 1){
702         printf("clGetDeviceIDs Error\n");
703         return -1;
704     }
705     cl_device_id device_id;
706     ret = clGetDeviceIDs(platform_id,CL_DEVICE_TYPE_GPU,1,&device_id,NULL);
707     if(ret != CL_SUCCESS){
708         printf("clGetDeviceIDs Error2\n");
709         return -1;
710     }
711 
712     // OpenCL部分 =============== 3 创建Context
713     cl_context_properties props[] = {CL_CONTEXT_PLATFORM,
714         (cl_context_properties)platform_id,0};
715     cl_context context = NULL;
716     context = clCreateContext(props,1,&device_id,NULL,NULL,&ret);
717     if(ret != CL_SUCCESS || context == NULL){
718         printf("clCreateContext Error\n");
719         return -1;
720     }
721 
722     // OpenCL部分 =============== 4 创建Command Queue
723     cl_command_queue command_queue = NULL;
724     command_queue = clCreateCommandQueue(context,device_id,0,&ret);
725     if(ret != CL_SUCCESS || command_queue == NULL){
726         printf("clCreateCommandQueue Error\n");
727         return -1;
728     }
729 
730     // OpenCL部分 =============== 6 创建编译Program
731     const char *strfile = "D:\\PIE3\\src\\Test\\TextOpecCLResample\\TextOpecCLResample\\Co_occurrenceMatrixKernel.txt";
732     size_t lenSource = 0;
733     char *kernelSource = LoadProgSource(strfile,"",&lenSource);
734     cl_program *programs = (cl_program *)malloc(loopNum*sizeof(cl_program));
735     memset(programs,0,sizeof(cl_program)*loopNum);
736 
737     cl_kernel *kernels = (cl_kernel*)malloc(loopNum*sizeof(cl_kernel));
738     memset(kernels,0,sizeof(cl_kernel)*loopNum);
739 
740     int startR = 0;
741     for(int i = 0;i<loopNum;i++)
742     {
743         int tmpRowNum = iNumRow;
744         if(startR < 0)
745         {
746             startR = 0;
747         }
748         int endR = startR + tmpRowNum - 1;
749         if(endR > m_iHeigth -1 ){
750             endR = m_iHeigth -1;
751             tmpRowNum = endR - startR + 1;
752         }
753         unsigned char *readBuff = new unsigned char[tmpRowNum*m_iWidth*m_iBandCount];
754         float *writeBuff = new float[m_iWidth*m_iBandCount*(tmpRowNum - overloadPix)];
755         poDS->RasterIO(GF_Read,0,startR,m_iWidth,tmpRowNum,readBuff,m_iWidth,
756             tmpRowNum,GDT_Byte,m_iBandCount,m_BandMap,nPixSpace,nLineSpace,nBandSpace);
757 
758         // OpenCL部分 =============== 5 创建Memory Object
759         cl_mem mem_read = NULL;
760         mem_read = clCreateBuffer(context,CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
761             sizeof(cl_uchar)*tmpRowNum*m_iWidth*m_iBandCount,readBuff,&ret);
762         if(ret != CL_SUCCESS || NULL == mem_read){
763             printf("clCreateBuffer Error\n");
764             return -1;
765         }
766 
767         cl_mem mem_write = NULL;
768         mem_write = clCreateBuffer(context,CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
769             sizeof(cl_float)*m_iWidth*m_iBandCount*(tmpRowNum - overloadPix),writeBuff,&ret);
770         if(ret != CL_SUCCESS || NULL == mem_write){
771             printf("clCreateBuffer Error\n");
772             return -1;
773         }
774 
775         // OpenCL部分 =============== 6 创建编译Program
776         //const char *strfile = "D:\\PIE3\\src\\Test\\TextOpecCLResample\\TextOpecCLResample\\Co_occurrenceMatrixKernel.txt";
777         //size_t lenSource = 0;
778         //char *kernelSource = LoadProgSource(strfile,"",&lenSource);
779         //cl_program program = NULL;
780         programs[i] = clCreateProgramWithSource(context,1,(const char**)&kernelSource,
781             NULL,&ret);
782         if(ret != CL_SUCCESS || NULL == programs[i]){
783             printf("clCreateProgramWithSource Error\n");
784             return -1;
785         }
786         ret = clBuildProgram(programs[i],1,&device_id,NULL,NULL,NULL);
787         if(ret != CL_SUCCESS){
788             char* build_log;
789             size_t log_size;
790             //查询日志的大小
791             clGetProgramBuildInfo(programs[i], device_id, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size);
792             build_log = new char[log_size+1];
793             //获得编译日志信息
794             ret = clGetProgramBuildInfo(programs[i], device_id, CL_PROGRAM_BUILD_LOG, log_size, build_log, NULL);
795             build_log[log_size] = '\0';
796             printf("%s\n",build_log);
797             printf("编译失败!");
798             delete []build_log;
799             return -1;
800         }
801 
802         // OpenCL部分 =============== 7 创建Kernel
803         //cl_kernel kernel = NULL;
804         kernels[i] = clCreateKernel(programs[i],"Co_occurrenceMatrixKernel",&ret);
805         if(ret != CL_SUCCESS || NULL == kernels[i]){
806             printf("clCreateProgramWithSource Error\n");
807             return -1;
808         }
809 
810         // OpenCL部分 =============== 8 设置Kernel参数
811         ret = clSetKernelArg(kernels[i],0,sizeof(cl_mem),&mem_read);
812         ret |= clSetKernelArg(kernels[i],1,sizeof(cl_mem),&mem_write);
813         ret |= clSetKernelArg(kernels[i],2,sizeof(cl_int),&m_iHeigth);
814         ret |= clSetKernelArg(kernels[i],3,sizeof(cl_int),&m_iWidth);
815         ret |= clSetKernelArg(kernels[i],4,sizeof(cl_int),&m_iBandCount);
816         ret |= clSetKernelArg(kernels[i],5,sizeof(cl_int),&tmpRowNum);
817         ret |= clSetKernelArg(kernels[i],6,sizeof(cl_int),&overloadPix);
818         ret |= clSetKernelArg(kernels[i],7,sizeof(cl_int),&m_grayLevel);
819         ret |= clSetKernelArg(kernels[i],8,sizeof(cl_int),&m_winHeigth);
820         ret |= clSetKernelArg(kernels[i],9,sizeof(cl_int),&m_winWidth);
821         ret |= clSetKernelArg(kernels[i],10,sizeof(cl_int),&m_dis);
822         ret |= clSetKernelArg(kernels[i],11,sizeof(cl_int),&m_AngleMode);
823         ret |= clSetKernelArg(kernels[i],12,sizeof(cl_int),&m_TextureMode);
824         if(ret != CL_SUCCESS){
825             printf("clSetKernelArg Error\n");
826             return -1;
827         }
828 
829         // OpenCL部分 =============== 9 设置Group Size
830         cl_uint work_dim = 2;
831         size_t global_work_size[] = {m_iWidth,tmpRowNum};
832         size_t *local_work_size = NULL;
833 
834         // OpenCL部分 =============== 10 执行内核
835         ret = clEnqueueNDRangeKernel(command_queue,kernels[i],work_dim,NULL,global_work_size,
836             local_work_size,0,NULL,NULL);
837         ret |= clFinish(command_queue);
838         if(ret != CL_SUCCESS){
839             printf("clEnqueueNDRangeKernel Error\n");
840             return -1;
841         }
842 
843         writeBuff = (float*)clEnqueueMapBuffer(command_queue,mem_write,CL_TRUE,CL_MAP_READ | CL_MAP_WRITE,
844             0,sizeof(cl_float)*m_iWidth*m_iBandCount*(tmpRowNum - overloadPix),0,NULL,NULL,&ret);
845         //ret = clEnqueueReadBuffer(command_queue,mem_resample,CL_TRUE,0,
846         //    sizeof(cl_float)*tmpRowNum*resampleWidth*mssBandCount,(void*)resampleBuf,0,NULL,NULL);
847         if(ret != CL_SUCCESS){
848             printf("clEnqueueMapBuffer Error\n");
849             return -1;
850         }
851         poOutDS->RasterIO(GF_Write,0,startR+overloadPix/2,m_iWidth,tmpRowNum - overloadPix,writeBuff,
852             m_iWidth,tmpRowNum - overloadPix,GDT_Float32,m_iBandCount,m_BandMap,nPixSpace,sizeof(float)*m_iWidth*m_iBandCount,
853             sizeof(float)*m_iWidth);
854         delete []readBuff;readBuff = NULL;
855         delete []writeBuff;writeBuff = NULL;
856 
857         // OpenCL部分 =============== 12 释放资源
858         if(NULL != mem_read) clReleaseMemObject(mem_read);
859         if(NULL != mem_write) clReleaseMemObject(mem_write);
860         std::cout<<i<<"  "<<loopNum<<std::endl;
861         startR = startR + tmpRowNum - overloadPix;
862     }
863     // OpenCL部分 =============== 12 释放资源
864     int i = 0;
865     while(i < loopNum){
866         if(NULL != kernels[i]) clReleaseKernel(kernels[i]);
867         if(NULL != programs[i]) clReleaseProgram(programs[i]);
868         i++;
869     }
870     if(NULL != command_queue) clReleaseCommandQueue(command_queue);
871     if(NULL != context) clReleaseContext(context);
872     GDALClose((GDALDatasetH)poDS);
873     GDALClose((GDALDatasetH)poOutDS);
874     return 0;
875 }

GPU核函数:

1 #pragma OPENCL EXTENSION cl_amd_printf:enable
  2 
  3 int GetGrayCoocurrenceMatrix(const int *grayValue,
  4                               float *grayMatrix,
  5                               int winHeight,
  6                               int winWidth,
  7                               int grayLevel,
  8                               int dis,
  9                               int AngleMode)
 10 {
 11     int i,j,r,c;
 12     int count = 0;
 13     switch(AngleMode)
 14     {
 15     case 0:
 16         i = 0;
 17         while(i<winHeight){
 18             j = 0;
 19             while(j<winWidth){
 20                 int endR = i;
 21                 int endC = j + dis;
 22                 if(endC < winWidth){
 23                     r = grayValue[i*winHeight + j];
 24                     c = grayValue[endR*winHeight + endC];
 25                     grayMatrix[r*grayLevel + c] += 1;
 26                     grayMatrix[c*grayLevel + r] += 1;
 27                     count = count+2;
 28                 }
 29                 j++;
 30             }
 31             i++;
 32         }
 33         break;
 34     case 1:
 35         i = 0;
 36         while(i<winHeight){
 37             j = 0;
 38             while(j<winWidth){
 39                 int endR = i - dis;
 40                 int endC = j + dis;
 41                 if(endR>=0 && endR < winHeight && endC >=0 && endC < winWidth){
 42                     r = grayValue[i*winHeight + j];
 43                     c = grayValue[endR*winHeight + endC];
 44                     grayMatrix[r*grayLevel + c] += 1;
 45                     grayMatrix[c*grayLevel + r] += 1;
 46                     count = count+2;
 47                 }
 48                 j++;
 49             }
 50             i++;
 51         }
 52         break;
 53     case 2:
 54         i= 0;
 55         while(i<winHeight){
 56             j = 0;
 57             while(j < winWidth){
 58                 int endR = i - dis;
 59                 int endC = j;
 60                 if(endR >= 0){
 61                     r = grayValue[i*winHeight + j];
 62                     c = grayValue[endR*winHeight + endC];
 63                     grayMatrix[r*grayLevel + c] += 1;
 64                     grayMatrix[c*grayLevel + r] += 1;
 65                     count = count+2;
 66                 }
 67                 j++;
 68             }
 69             i++;
 70         }
 71         break;
 72     case 3:
 73         i = 0;
 74         while(i<winHeight){
 75             j = 0;
 76             while(j<winWidth){
 77                 int endR = i - dis;
 78                 int endC = j - dis;
 79                 if(endR >= 0 && endC >= 0){
 80                     r = grayValue[i*winHeight + j];
 81                     c = grayValue[endR*winHeight + endC];
 82                     grayMatrix[r*grayLevel + c] += 1;
 83                     grayMatrix[c*grayLevel + r] += 1;
 84                     count = count+2;
 85                 }
 86                 j++;
 87             }
 88             i++;
 89         }
 90         break;
 91     default:
 92         return 0;
 93     }
 94     return count;
 95 }
 96 
 97 float CalGLCMStatistics(float *grayMatrix,
 98                         const int grayLevel,
 99                         const int count,
100                         int TextureMode)
101 {
102     int i,j,k;
103     float imean = 0.0f;
104     float jmean = 0.0f;
105     float ivar = 0.0f;
106     float jvar = 0.0f;;
107     float res = 0.0f;
108     switch(TextureMode)
109     {
110     case 0:  //同质性
111         i = 0;
112         while(i < grayLevel){
113             j = 0;
114             while(j < grayLevel){
115                 if(grayMatrix[i*grayLevel + j] != 0){
116                     float Pij = grayMatrix[i*grayLevel + j]*1.0f/count;
117                     res += Pij/(1 + (i-j)*(i-j));
118                 }
119                 j++;
120             }
121             i++;
122         }
123         break;
124     case 1:  //对比度
125         i = 0;
126         while(i < grayLevel){
127             j = 0;
128             while(j < grayLevel){
129                 if(grayMatrix[i*grayLevel + j] != 0){
130                     float Pij = grayMatrix[i*grayLevel + j]*1.0f/count;
131                     res += Pij*(i-j)*(i-j);
132                 }
133                 j++;
134             }
135             i++;
136         }
137         break;
138     case 2:  //非相似性
139         i = 0;
140         while(i < grayLevel){
141             j = 0;
142             while(j < grayLevel){
143                 if(grayMatrix[i*grayLevel + j] != 0){
144                     float Pij = grayMatrix[i*grayLevel + j]*1.0f/count;
145                     res += Pij*abs(i-j);
146                 }
147                 j++;
148             }
149             i++;
150         }
151         break;
152     case 3:  // 相关性
153         i = 0;
154         while(i < grayLevel){
155             j = 0;
156             while(j < grayLevel){
157                 if(grayMatrix[i*grayLevel + j] != 0){
158                     float Pij = grayMatrix[i*grayLevel + j]*1.0f/count;
159                     imean += Pij * i;
160                     jmean += Pij * j;
161                 }
162                 j++;
163             }
164             i++;
165         }
166         //  var
167         i = 0;
168         while(i < grayLevel){
169             j = 0;
170             while(j < grayLevel){
171                 if(grayMatrix[i*grayLevel + j] != 0){
172                     float Pij = grayMatrix[i*grayLevel + j]*1.0f/count;
173                     ivar += Pij * (i - imean)*(i - imean);
174                     jvar += Pij * (j - imean)*(j - imean);
175                 }
176                 j++;
177             }
178             i++;
179         }
180         // xiangguanx
181         i = 0;
182         while(i < grayLevel){
183             j = 0;
184             while(j < grayLevel){
185                 if(grayMatrix[i*grayLevel + j] != 0){
186                     float Pij = grayMatrix[i*grayLevel + j]*1.0f/count;
187                     res += (Pij *(i - imean)*(j - jmean))/sqrt(ivar*jvar);
188                 }
189                 j++;
190             }
191             i++;
192         }
193         break;
194     case 4:  // 均值
195         i = 0;
196         while(i < grayLevel){
197             j = 0;
198             while(j < grayLevel){
199                 if(grayMatrix[i*grayLevel + j] != 0){
200                     float Pij = grayMatrix[i*grayLevel + j]*1.0f/count;
201                     imean += Pij * i;
202                     //jmean += Pij * j;
203                 }
204                 j++;
205             }
206             i++;
207         }
208         res = imean;
209         break;
210     case 5:  // 方差
211         //  mean
212         i = 0;
213         while(i < grayLevel){
214             j = 0;
215             while(j < grayLevel){
216                 if(grayMatrix[i*grayLevel + j] != 0){
217                     float Pij = grayMatrix[i*grayLevel + j]*1.0f/count;
218                     imean += Pij * i;
219                 }
220                 j++;
221             }
222             i++;
223         }
224         //  var
225         i = 0;
226         while(i < grayLevel){
227             j = 0;
228             while(j < grayLevel){
229                 if(grayMatrix[i*grayLevel + j] != 0){
230                     float Pij = grayMatrix[i*grayLevel + j]*1.0f/count;
231                     ivar += Pij * (i - imean)*(i - imean);
232                 }
233                 j++;
234             }
235             i++;
236         }
237         res = ivar;
238         break;
239     case 6:  // 角二阶矩
240         i = 0;
241         while(i < grayLevel){
242             j = 0;
243             while(j < grayLevel){
244                 if(grayMatrix[i*grayLevel + j] != 0){
245                     float Pij = grayMatrix[i*grayLevel + j]*1.0f/count;
246                     res += Pij*Pij;
247                 }
248                 j++;
249             }
250             i++;
251         }
252         break;
253     case 7:  // 熵
254         i = 0;
255         while(i < grayLevel){
256             j = 0;
257             while(j < grayLevel){
258                 if(grayMatrix[i*grayLevel + j] != 0){
259                     float Pij = grayMatrix[i*grayLevel + j]*1.0f/count;
260                     res += -1.0f*Pij * log(Pij);
261                 }
262                 j++;
263             }
264             i++;
265         }
266         break;
267     case 8:
268         k = 0;
269         while(k<grayLevel){
270             i = 0;
271             while(i < grayLevel){
272                 j = 0;
273                 while(j < grayLevel){
274                     if(grayMatrix[i*grayLevel + j] != 0 && abs(i-j)== k){
275                         float Pij = grayMatrix[i*grayLevel + j]*1.0f/count;
276                         res += Pij*k;
277                     }
278                     j++;
279                 }
280                 i++;
281             }
282             k++;
283         }
284         break;
285     case 9:
286         k = 0;
287         while(k<grayLevel){
288             i = 0;
289             while(i < grayLevel){
290                 j = 0;
291                 while(j < grayLevel){
292                     if(grayMatrix[i*grayLevel + j] != 0 && abs(i-j)== k){
293                         float Pij = grayMatrix[i*grayLevel + j]*1.0f/count;
294                         res += Pij*k*k;
295                     }
296                     j++;
297                 }
298                 i++;
299             }
300             k++;
301         }
302         break;
303     case 10:
304         k = 0;
305         while(k<grayLevel){
306             i = 0;
307             while(i < grayLevel){
308                 j = 0;
309                 while(j < grayLevel){
310                     if(grayMatrix[i*grayLevel + j] != 0 && abs(i-j)== k){
311                         float Pij = grayMatrix[i*grayLevel + j]*1.0f/count;
312                         res += Pij*Pij;
313                     }
314                     j++;
315                 }
316                 i++;
317             }
318             k++;
319         }
320         break;
321     }
322     return res;
323 }
324 
325 
326 
327 
328 
329 
330 __kernel void Co_occurrenceMatrixKernel(__global const unsigned char *oriData,
331                                         __global float *writeData,
332                                         int iHeight,
333                                         int iWidth,
334                                         int iBandCount,
335                                         int curRowNum,
336                                         int overloadPix,
337                                         int grayLevel,
338                                         int winHeight,
339                                         int winWidth,
340                                         int dis,
341                                         int AngleMode,
342                                         int TextureMode)
343 {
344     int idx = get_global_id(1);  // 采样行
345     int idy = get_global_id(0);  // 采样列
346     if(idx >= overloadPix/2 && idx < curRowNum - overloadPix/2 && idy < iWidth)
347     {
348         // 获得灰度值
349         int startC = idy - winWidth/2;
350         int endC = idy + winWidth/2;
351         if(startC<0){
352             startC = 0;
353             endC = startC + winWidth -1;
354         }
355         if(endC > iWidth-1){
356             endC = iWidth -1;
357             startC = endC - winWidth +1;
358         }
359         int b = 0;
360         while(b < iBandCount)
361         {
362             int grayValue[625] = {0};
363             int k = 0;
364             while(k < winHeight){
365                 int l = 0 ;
366                 while(l < winWidth){
367                     int tmpP = (int)(idx  - overloadPix/2 + k)*iWidth*iBandCount + b*iWidth + startC+l;
368                     grayValue[k*winHeight + l] = (int)oriData[tmpP];
369                     l++;
370                 }
371                 k++;
372             }
373             float grayMatrix[1024] = {0};
374             int count = GetGrayCoocurrenceMatrix(grayValue,grayMatrix,winHeight,winWidth,grayLevel,dis,AngleMode);
375             float tmp = CalGLCMStatistics(grayMatrix,grayLevel,count,TextureMode);
376             writeData[(idx- overloadPix/2)*iWidth*iBandCount+ b*iWidth + idy] = tmp;
377             b++;
378         }
379     }
380 }