纹理作为一种区域特征,是对于图像各像元之间空间分布的一种描述。由于纹理能充分利用图像信息,无论从理论上或常识出发它都可以成为描述与识别图像的重要依据,与其他图像特征相比,它能更好地兼顾图像宏观性质与细微结构两个方面,因此纹理成为目标识别需要提取的重要特征。提取纹理特征的方法很多,如基于局部统计特性的特征、基于随机场模型的特征、基于空间频率的特征、分形特征等,其中,应用最广泛的是基于灰值共生矩阵的特征。
我这里是已以下方式,来求得灰度共生矩阵,其间距为1
也将灰度级进行了等概率量化,减小维度。
代码如下:
// c++_glcm.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#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
using namespace std;
using namespace cv;
void feature_extra(Mat& glcm);
//glcm_make.h
#include
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
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(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(i,j) = glcm.at(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(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(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(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(i,j);
//熵
if (m == 0)
continue;
entropy += m*log10(1/m);
}
cout << "能量为: " <
//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(i,j) == grayVal1) && (image.at(i + 1, j) == grayVal2) )
{
numbers_0++;
}
if ( (image.at(i,j) == grayVal1) && (image.at(i + 1, j - 1) == grayVal2) )
{
numbers_45++;
}
if ( (image.at(i,j) == grayVal1) && (image.at(i , j - 1) == grayVal2) )
{
numbers_90++;
}
if ( (image.at(i,j) == grayVal1) && (image.at(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(i, j) = image.at(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(i,j) = numbers_0;
numbers_0 = 0;
}
}
}