来自于gitee,直接上源代码:
// // Created by lihao on 2020/4/15. //https://gitee.com/lihao-20200423/lihao-code/commit/67962c76cd08257d08d078e5b47152352754e9a1 #ifndef DETECT_SOCKS_GGCM_H #define DETECT_SOCKS_GGCM_H #include <iostream> #include <vector> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; typedef vector<vector<int>> VecGGCM; typedef struct _GGCMFeatures { _GGCMFeatures() : small_grads_dominance(0.0) , big_grads_dominance(0.0) , gray_asymmetry(0.0) , grads_asymmetry(0.0) , energy(0.0) , gray_mean(0.0) , grads_mean(0.0) , gray_variance(0.0) , grads_variance(0.0) , corelation(0.0) , gray_entropy(0.0) , grads_entropy(0.0) , entropy(0.0) , inertia(0.0) , differ_moment(0.0) {} float small_grads_dominance; //小梯度优势 float big_grads_dominance; //大梯度优势 float gray_asymmetry; //灰度分布不均匀性 float grads_asymmetry; //梯度分布不均匀性 float energy; //能量 float gray_mean ; // 灰度均值 float grads_mean ; // 梯度均值 float gray_variance ; // 灰度均方差 float grads_variance ; // 梯度均方差 float corelation ; // 相关性 float gray_entropy ; //灰度熵 float grads_entropy ; // 梯度熵 float entropy ; // 混合熵 float inertia ; // 惯性 float differ_moment ; // 逆差距 } GGCMFeatures; class GGCM { public: GGCM(); ~GGCM(); private: int m_grayLevel; // 将灰度共生矩阵划分为 grayLevel 个等级 public: // 初始化灰度-梯度共生矩阵 void initGGCM(VecGGCM& vecGGCM, int size = 16); // 计算灰度-梯度共生矩阵 void calGGCM(Mat &inputImg,VecGGCM &vecGGCM,VecGGCM &tempVec_Gray,VecGGCM &tempVec_Gradient); // 计算特征值 void getGGCMFeatures(VecGGCM& vecGGCM, GGCMFeatures& features); }; #endif //DETECT_SOCKS_GGCM_H
然后是实现文件:
// // Created by lihao on 2020/4/15. // #include "GGCM.h" GGCM::GGCM() : m_grayLevel(16){} GGCM::~GGCM(){} void GGCM::initGGCM(VecGGCM& vecGGCM, int size){ assert(size == m_grayLevel); vecGGCM.resize(size); for (int i = 0; i < size; ++i){ vecGGCM[i].resize(size); } for (int i = 0; i < size; ++i){ for (int j = 0; j < size; ++j){ vecGGCM[i][j] = 0; } } } void GGCM::calGGCM(Mat &inputImg, VecGGCM& vecGGCM,VecGGCM &tempVec_Gray,VecGGCM &tempVec_Gradient){ Mat src; src=inputImg.clone(); int height = src.rows; int width = src.cols; int maxGrayLevel = 0; // 寻找最大像素灰度最大值 for (int i = 0; i < height; ++i){ for (int j = 0; j < width; ++j){ int grayVal = src.at<uchar>(i,j); if (grayVal > maxGrayLevel){ maxGrayLevel = grayVal; } } } ++maxGrayLevel; tempVec_Gray.resize(height); for (int i = 0; i < height; ++i){ tempVec_Gray[i].resize(width); } // 灰度归一化 if (maxGrayLevel > m_grayLevel)//若灰度级数大于16,则将图像的灰度级缩小至16级。 { for (int i = 0; i < height; ++i){ for (int j = 0; j < width; ++j){ int tmpVal = src.at<uchar>(i,j); tempVec_Gray[i][j] = int(tmpVal*m_grayLevel/maxGrayLevel); } } } else{ //若灰度级数小于16,则生成相应的灰度矩阵 for (int i = 0; i < height; ++i){ for (int j = 0; j < width; ++j){ int tmpVal = src.at<uchar>(i,j); tempVec_Gray[i][j] = tmpVal; } } } tempVec_Gradient.resize(height); for (int i = 0; i < height; ++i){ tempVec_Gradient[i].resize(width); } int maxGradientLevel = 0; // 求图像的梯度 for (int i = 0; i < height; ++i){ for (int j = 0; j < width; ++j){ if(i==0||i==height-1||j==0||j==width-1){ tempVec_Gradient[i][j]=0; }else{ int g_x=src.at<uchar>(i+1,j-1)+2*src.at<uchar>(i+1,j)+src.at<uchar>(i+1,j+1) -src.at<uchar>(i-1,j-1)-2*src.at<uchar>(i-1,j)-src.at<uchar>(i-1,j+1); int g_y=src.at<uchar>(i-1,j+1)+2*src.at<uchar>(i,j+1)+src.at<uchar>(i+1,j+1) -src.at<uchar>(i-1,j+1)-2*src.at<uchar>(i,j-1)-src.at<uchar>(i+1,j-1); int g=sqrt(g_x*g_x+g_y*g_y); tempVec_Gradient[i][j]=g; if(g>maxGradientLevel){ maxGradientLevel=g; } } } } ++maxGradientLevel; // 梯度归一化 if(maxGradientLevel>m_grayLevel){ for (int i = 0; i < height; ++i){ for (int j = 0; j < width; ++j){ int tmpVal = tempVec_Gradient[i][j]; tempVec_Gradient[i][j] = int(tmpVal*m_grayLevel/maxGradientLevel); } } } //得到梯度-灰度共生矩阵 for (int i = 0; i < height; ++i){ for (int j = 0; j < width; ++j){ int row=tempVec_Gray[i][j]; int col=tempVec_Gradient[i][j]; vecGGCM[row][col]++; } } } // 二维数组求和 template<typename T> float sumVVector(vector<vector<T>> v) { float ans = 0; for(int i = 0; i < v.size(); ++i) { for(int j = 0; j < v[i].size(); ++j) { ans += v[i][j]; } } return ans; } // 二维数组按行求和 template<typename T> float sumRowVVector(vector<vector<T>> v, int num) { float ans = 0; for(int i = 0; i < v.size(); ++i) { ans += v[num][i]; } return ans; } // 二维数组按列求和 template<typename T> float sumColVVector(vector<vector<T>> v, int num) { float ans = 0; for(int i = 0; i < v.size(); ++i) { ans += v[i][num]; } return ans; } void GGCM::getGGCMFeatures(VecGGCM& vecGGCM, GGCMFeatures& features){ float total=sumVVector(vecGGCM); for (int i = 0; i < m_grayLevel; ++i){ float sumRowGray = 0; sumRowGray = sumRowVVector(vecGGCM, i); float sumColGrad =0; sumColGrad=sumColVVector(vecGGCM, i); for (int j = 0; j < m_grayLevel; ++j){ features.small_grads_dominance += vecGGCM[i][j] / pow(j+1, 2); features.big_grads_dominance+=vecGGCM[i][j] * pow(j+1 ,2); } features.gray_asymmetry += pow(sumRowGray, 2); features.grads_asymmetry += pow(sumColGrad, 2); } features.small_grads_dominance /= total; features.big_grads_dominance /= total; features.gray_asymmetry /= total; features.grads_asymmetry /= total; vector<vector<float>> vecPGGCM; vecPGGCM.resize(m_grayLevel); for (int i = 0; i < m_grayLevel; ++i){ vecPGGCM[i].resize(m_grayLevel); } for(int i=0;i<vecGGCM.size();i++){ for(int j=0;j<vecGGCM[i].size();j++){ int tmp=vecGGCM[i][j]; vecPGGCM[i][j]=tmp/total; } } for(int i=0;i<m_grayLevel;i++){ float sumRowGray = 0; sumRowGray = sumRowVVector(vecPGGCM, i); float sumColGrad=0; sumColGrad = sumColVVector(vecPGGCM, i); for(int j=0;j<m_grayLevel;j++){ features.energy += pow(vecPGGCM[i][j], 2); if(vecGGCM[i][j] != 0) { features.entropy -= vecPGGCM[i][j] * log(vecPGGCM[i][j]); features.inertia += pow((i-j), 2) * vecPGGCM[i][j]; } features.differ_moment += vecPGGCM[i][j] / (1 + pow((i-j), 2)); } features.gray_mean += (i+1) * sumRowGray; features.grads_mean += (i+1) * sumColGrad; if(sumRowGray != 0){ features.gray_entropy -= sumRowGray * log(sumRowGray); } if(sumColGrad!=0){ features.grads_entropy-=sumColGrad*log(sumColGrad); } } for(int i=0;i<m_grayLevel;i++){ float sumRowGray = 0; sumRowGray = sumRowVVector(vecPGGCM, i); features.gray_variance+=pow(i+1-features.gray_mean,2)*sumRowGray; float sumColGrad=0; sumColGrad = sumColVVector(vecPGGCM, i); features.grads_variance+=pow(i+1-features.grads_mean,2)*sumColGrad; } features.gray_variance = pow(features.gray_variance, 0.5); features.grads_variance = pow(features.grads_variance, 0.5); for(int i = 0; i < m_grayLevel; ++i){ for(int j = 0; j < m_grayLevel; ++j){ features.corelation += (i+1-features.gray_mean) * (j+1-features.grads_mean) * vecPGGCM[i][j]; } } features.corelation=features.corelation/(features.gray_variance*features.grads_variance); }
用法很简单,直接按照顺序调用三个public函数即可!