纹理作为一种区域特征,是对于图像各像元之间空间分布的一种描述。由于纹理能充分利用图像信息,无论从理论上或常识出发它都可以成为描述与识别图像的重要依据,与其他图像特征相比,它能更好地兼顾图像宏观性质与细微结构两个方面,因此纹理成为目标识别需要提取的重要特征。提取纹理特征的方法很多,如基于局部统计特性的特征、基于随机场模型的特征、基于空间频率的特征、分形特征等,其中,应用最广泛的是基于灰值共生矩阵的特征。
我这里是已以下方式,来求得灰度共生矩阵,其间距为1
也将灰度级进行了等概率量化,减小维度。
代码如下:
// c++_glcm.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <opencv245.h> #include "glcm_make.h" #include "defautVal.h" #include "feature_extra.h" using namespace cv; using namespace std; int _tmain(int argc, _TCHAR* argv[]) { Mat src = imread("C:\\Users\\sony\\Desktop\\a1_001.jpg",0); /*imshow("1", src);*/ normalize(src, src, 0.0, 255.0, NORM_MINMAX); /*imshow("2",src); waitKey(0);*/ Mat img = src.clone(); Mat glcm(grayScal, grayScal, CV_32FC1, Scalar(0.0)); //0度的灰度共生矩阵 glcm_make(glcm, img); cout << glcm << endl; feature_extra(glcm); return 0; }
//defautVal.h #define grayScal 16 //double contrast; //对比度 //double correlation; //纹理相关性 //double energy; //能量 //double homogeneity; //一致性 //double entropy; //熵
//feature_extra.h #include <opencv245.h> using namespace std; using namespace cv; void feature_extra(Mat& glcm);
//glcm_make.h #include <opencv245.h> using namespace cv; using namespace std; void glcm_make(Mat& glcm, Mat& image);
//feature_extra.cpp #include "stdafx.h" #include "glcm_make.h" #include "feature_extra.h" #include <math.h> double contrast = 0; //对比度 double correlation = 0; //纹理相关性 double energy = 0; //能量 double homogeneity = 0; //一致性 double entropy = 0; //熵 void feature_extra(Mat& glcm) { //灰度共生矩阵归一化 double sum = 0.0; for (int i = 0; i < glcm.rows - 1; ++i) { for (int j = 0; j < glcm.cols - 1; ++j) { sum += glcm.at<float>(i,j); } } Mat glcm1(glcm.size(), CV_32FC1, Scalar(0.0)); for (int i = 0; i < glcm1.rows - 1; ++i) { for (int j = 0; j < glcm1.cols - 1; ++j) { glcm1.at<float>(i,j) = glcm.at<float>(i,j)/sum; } } cout << glcm1 << endl; double m = 0; double k = 0; double ui = 0; double uj = 0; double si_2 = 0; double sj_2 = 0; for (int i = 0; i < glcm1.rows - 1; ++i) { for (int j = 0; j < glcm1.cols - 1; ++j) { m = glcm1.at<float>(i,j); //能量 energy += m*m; //对比度 contrast += (i-j)*(i-j)*m; // 'Homogeneity' 即齐次性(同质性),返回的值反映了GLCM中元素相对于GLCM对角线的分布的紧密度 homogeneity += m*(1 + abs(i - j)); //自相关的一些参数 ui += i*m; uj += j*m; } } m = 0; for (int i = 0; i < glcm1.rows - 1; ++i) { for (int j = 0; j < glcm1.cols - 1; ++j) { m = glcm1.at<float>(i,j); si_2 += m*(i - ui)*(i - ui); sj_2 += m*(j - ui)*(j - ui); } } m = 0; for (int i = 0; i < glcm1.rows - 1; ++i) { for (int j = 0; j < glcm1.cols - 1; ++j) { m = glcm1.at<float>(i,j); //自相关 correlation += (i*j*m - ui*uj)/sqrt(si_2)*sqrt(sj_2); } } m = 0; for (int i = 0; i < glcm1.rows - 1; ++i) for (int j = 0; j < glcm1.cols - 1; ++j) { m = glcm1.at<float>(i,j); //熵 if (m == 0) continue; entropy += m*log10(1/m); } cout << "能量为: " <<energy<<endl; cout << "熵为: " <<entropy<<endl; cout << "对比度为: " <<contrast<<endl; cout << "自相关为: " <<correlation<<endl; cout << "齐次性为: " <<homogeneity<<endl; }
//glcm_make.cpp #include "stdafx.h" #include "glcm_make.h" #include "defautVal.h" int numbers_0 = 0; int numbers_45 = 0; int numbers_90 = 0; int numbers_135 = 0; //得到0度,灰度对的个数 void pairsNumber(int grayVal1, int grayVal2, Mat image) { for (int i = 1; i < image.rows - 2; ++i) { for(int j = 1; j < image.cols - 2; ++j) { if ( (image.at<uchar>(i,j) == grayVal1) && (image.at<uchar>(i + 1, j) == grayVal2) ) { numbers_0++; } if ( (image.at<uchar>(i,j) == grayVal1) && (image.at<uchar>(i + 1, j - 1) == grayVal2) ) { numbers_45++; } if ( (image.at<uchar>(i,j) == grayVal1) && (image.at<uchar>(i , j - 1) == grayVal2) ) { numbers_90++; } if ( (image.at<uchar>(i,j) == grayVal1) && (image.at<uchar>(i - 1 , j - 1) == grayVal2) ) { numbers_135++; } } } } void glcm_make(Mat& glcm, Mat& image) { //把图片灰度级0到255等值量化为0到15 for (int i = 0 ; i < image.rows; ++i) { for (int j = 0; j < image.cols; ++j) { image.at<uchar>(i, j) = image.at<uchar>(i, j)/grayScal; } } //表示灰度级16 for (int i = 0; i < glcm.rows - 1; ++i) { for(int j = 0; j < glcm.cols - 1; ++j) { pairsNumber(i, j, image); glcm.at<float>(i,j) = numbers_0; numbers_0 = 0; } } }