zoukankan      html  css  js  c++  java
  • 基于opencv的灰度梯度共生矩阵

    来自于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函数即可!

  • 相关阅读:
    【NOIP 2003】 加分二叉树
    【POJ 1655】 Balancing Act
    【HDU 3613】Best Reward
    【POJ 3461】 Oulipo
    【POJ 2752】 Seek the Name, Seek the Fame
    【POJ 1961】 Period
    【POJ 2406】 Power Strings
    BZOJ3028 食物(生成函数)
    BZOJ5372 PKUSC2018神仙的游戏(NTT)
    BZOJ4836 二元运算(分治FFT)
  • 原文地址:https://www.cnblogs.com/autumoonchina/p/14911527.html
Copyright © 2011-2022 走看看