精华内容
下载资源
问答
  • 运用MATLAB R2014a来完成灰度共生矩阵特征参数的求解。以纸作为纹理分析的对象。首先需将彩色图像将各颜色分量转化为灰度。所用图像的灰度级为256。为了减少计算量,对原始图像灰度级压缩,将灰度量化成16级。计算...
  • 实现了在MATLAB上灰度共生矩阵的生成,以及四个主要特征向量的提取。
  • 收稿日期:2012-03-20;... 灰度共生矩阵纹理特征提取的 Matlab 实现 焦蓬蓬,郭依正,刘丽娟,卫 星 ( 南京师范大学泰州学院,江苏 泰州 225300) 摘 要: 图像的特征提取是图像的识别和分类、基于...

    收稿日期:2012-03-20; 修回日期:2012-06-24 基金项目: 国家“十一五”计划课题( FIB070335-B8-04) 作者简介: 焦蓬蓬( 1981-) ,女,硕士,讲师,研究方向为数字信号处理。 灰度共生矩阵纹理特征提取的 Matlab 实现 焦蓬蓬,郭依正,刘丽娟,卫 星 ( 南京师范大学泰州学院,江苏 泰州 225300) 摘 要: 图像的特征提取是图像的识别和分类、基于内容的图像检索、图像数据挖掘等研究内容的基础性工作,其中图像的纹理特征对描述图像内容具有重要意义,纹理特征提取已成为目前图像领域研究的热点。文中深入研究了基于灰度共生矩阵( GLCM) 的纹理特征提取方法,给出了基于 Matlab 的简便实现代码,分析了共生矩阵各个构造参数对构造共生矩阵的影响。分析结果对优化灰度共生矩阵的构造、实现基于灰度共生矩阵( GLCM) 的特定图像的纹理特征提取等都具有重要参考意义。 关键词: 灰度共生矩阵; 纹理特征; Matlab 中图分类号: TP391. 9 文献标识码: A 文章编号:1673-629X( 2012) 11-0169-03 Implementation of Gray Level Co-occurrence Matrix Texture Feature Extraction Using Matlab JIAO Peng-peng,GUO Yi-zheng,LIU Li-juan,WEI Xing ( Taizhou College of Nanjing Normal University,Taizhou 225300,China) Abstract: The texture feature extraction of image is a foundational work for image recognition and classification,content-based image re-trieval,image data mining,etc. The texture feature of image is significant for description of image content. And it is a hot topic in the re-search of image now. The method of texture feature extraction based on gray level co-occurrence matrix ( GLCM) was studied. Analyzed the effect of each parameter on constructing the co-occurrence matrix and implemented the feature extraction using Matlab. The analytical results provide valuable reference for creating GLCM better and extracting texture features of specific kinds of images. Key words: gray level co-occurrence matrix; texture feature; Matlab 0 引 言 纹理是图像的一个重要属性,它是图像像素颜色或灰度在空间以一定形式变化而产生的图案[1]。图像的纹理特征客观存在,反

    展开全文
  • 灰度共生矩阵的原理及实现(特征提取)-OpenCV

    万次阅读 多人点赞 2017-10-20 10:41:39
    最近在研究机器学习相关内容,后面会尽量花时间...灰度共生矩阵陌生的家伙,于是便有此文。 主要参考博客1:http://blog.csdn.net/jialeheyeshu/article/details/51337225 主要参考博客2:http://blog.csdn....


    最近在研究机器学习相关内容,后面会尽量花时间整理成一个系列的博客,然后朋友让我帮他实现一种基于SVR支持向量回归的图像质量评价方法,然而在文章的开头竟然发现
    灰度共生矩阵这个陌生的家伙,于是便有此文。

    这里写图片描述

    主要参考博客1:http://blog.csdn.net/jialeheyeshu/article/details/51337225
    主要参考博客2:http://blog.csdn.net/guanyuqiu/article/details/53117507
    主要参考博客3:http://www.cnblogs.com/rong86/p/3695621.html
    主要参考博客4:http://blog.csdn.net/lingtianyulong/article/details/53032034

    1.灰度共生矩阵生成原理
      灰度共生矩阵(GLDM)的统计方法是20世纪70年代初由R.Haralick等人提出的,它是在假定图像中各像素间的空间分布关系包含了图像纹理信息的前提下,提出的具有广泛性的纹理分析方法。

       灰度共生矩阵被定义为从灰度为i的像素点出发,离开某个固定位置(相隔距离为d,方位为)的点上灰度值为的概率,即,所有估计的值可以表示成一个矩阵的形式,以此被称为灰度共生矩阵。对于纹理变化缓慢的图像,其灰度共生矩阵对角线上的数值较大;而对于纹理变化较快的图像,其灰度共生矩阵对角线上的数值较小,对角线两侧的值较大。由于灰度共生矩阵的数据量较大,一般不直接作为区分纹理的特征,而是基于它构建的一些统计量作为纹理分类特征。Haralick曾提出了14种基于灰度共生矩阵计算出来的统计量:即:能量、熵、对比度、均匀性、相关性、方差、和平均、和方差、和熵、差方差、差平均、差熵、相关信息测度以及最大相关系数。

      在网上看了很多灰度共生矩阵生成的例子感觉都没有说明白,要不就直接上结果要不就给一堆看不懂的代码和公式,后来看了matlab中的介绍就明白了,其实很简单,仔细把下面的看三遍就理解怎么来的了!(我是第三篇看明白的,当时很紧张,相信你们没问题)
      下图显示了如何求解灰度共生矩阵,以(1,1)点为例,GLCM(1,1)值为1说明只有一对灰度为1的像素水平相邻。GLCM(1,2)值为2,是因为有两对灰度为1和2的像素水平相邻。(MatLab说明文档)
    这里写图片描述

    GLCM表其实就是所有像素可能的组合,比如,GLCM(1,1)就是I中像素值为1和1的组合,GLCM(4,5)就是I中像素4和像素5的组合,GLCM(i,j)的值呢就是I中像素为i,像素为j的有有多少和相邻的成对点。这个相邻有个规则:就是f(x,y),f(x+a,y+b)相邻,就是只有x相隔a的单位,y相隔b个单位,我们认为是相邻的。
    平时我们说相邻:B点在A点右边,其实就是这里的a=1,b=0,也就是f(x,y)和f(x+1,y+0)相邻。
    于是就有了:
    a=1,b=0 时我们就说水平相邻:也就是0度的时候
    a=1,b=1 时我们就说对角相邻,也就是45度的时候
    a=-1,b=1时 即135度
    其他角度类似。
    在a=1,b=0时:GLCM(1,1)=1;其实就是I中有几个1和1相邻(1个)(按上面的规则)GLCM(1,2)=2,几个1和2相邻(2个)。ok!
    后面好多的性质,都是在把这个矩阵计算出来之后再在这个基础上运算的,那些就不难了!

    附加理解2:
    共生矩阵用两个位置的像素的联合概率密度来定义,它不仅反映亮度的分布特征,也反映具有同样亮度或者接近亮度的像素之间的位置分布特性,是有关图像亮度变化的二阶统计特征。它是定义一组纹理特征的基础。

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

    灰度直方图是对图像上单个像素具有某个灰度进行统计的结果,

    而灰度共生矩阵是对图像上保持某距离的两像素分别具有某灰度的状况进行统计得到的。

    取图像(N×N)中任意一点 (x,y)及偏离它的另一点 (x+a,y+b),设该点对的灰度值为(g1,g2)。令点(x,y) 在整个画面上移动,则会得到各种 (g1,g2)值,设灰度值的级数为 k,则(g1,g2) 的组合共有 k^2;种。对于整个画面,统计出每一种(g1,g2)值出现的次数,然后排列成一个方阵,在用(g1,g2) 出现的总次数将它们归一化为出现的概率P(g1,g2),这样的方阵称为灰度共生矩阵。距离差分值(a,b) 取不同的数值组合,可以得到不同情况下的联合概率矩阵。(a,b)取值要根据纹理周期分布的特性来选择,对于较细的纹理,选取(1,0)、(1,1)、(2,0)等小的差分值。  当 a=1,b=0时,像素对是水平的,即0度扫描;当a=0,b=1 时,像素对是垂直的,即90度扫描;当 a=1,b=1时,像素对是右对角线的,即45度扫描;当 a=-1,b=-1时,像素对是左对角线,即135度扫描。
    这样,两个象素灰度级同时发生的概率,就将 (x,y)的空间坐标转化为“灰度对” (g1,g2)的描述,形成了灰度共生矩阵。(百度百科)
    一幅图象的灰度共生矩阵能反映出图象灰度关于方向、相邻间隔、变化幅度的综合信息,它是分析图象的局部模式和它们排列规则的基础。

    感觉差不多了吧!

    2.灰度共生矩阵特征量(字写的不好,请见谅)

    (上述公式的来源要仔细推敲一番,在这里我的目的主要不是这个,所以咩有很详细的写出来,欢迎交流留言)

    3.Code

    GLCM.h

    
    #include<iostream>
    #include <cassert>
    #include <vector>
    #include <iterator>
    #include <functional>
    #include <algorithm>
    #include <opencv2/opencv.hpp>
    
    using namespace std;
    using namespace cv;
    
    typedef vector<vector<int> > VecGLCM;
    
    typedef struct _GLCMFeatures
    {
        _GLCMFeatures()
            : energy(0.0)
            , entropy(0.0)
            , contrast(0.0)
            , idMoment(0.0)
        {
    
        }
    
        double energy;      // 能量 
        double entropy;     // 熵
        double contrast;    // 对比度
        double idMoment;    // 逆差分矩, inverse difference moment
    
    } GLCMFeatures;
    
    class GLCM
    {
    public:
        GLCM();
        ~GLCM();
    
    public:
        // 枚举灰度共生矩阵的方向
        enum 
        {
            GLCM_HORIZATION = 0,        // 水平
            GLCM_VERTICAL = 1,          // 垂直
            GLCM_ANGLE45 = 2,           // 45度角
            GLCM_ANGLE135 = 3           // 135度角
        };
    
    public:
        // 计算灰度共生矩阵
        void calGLCM(IplImage* inputImg, VecGLCM& vecGLCM, int angle);
        // 计算特征值
        void getGLCMFeatures(VecGLCM& vecGLCM, GLCMFeatures& features);
    public:
        // 初始化灰度共生矩阵
        void initGLCM(VecGLCM& vecGLCM, int size = 16);
        // 设置灰度划分等级,默认值为 16
        void setGrayLevel(int grayLevel) { m_grayLevel = grayLevel; }
        // 获取灰度等级
        int getGrayLevel() const { return m_grayLevel; }
    private:
        // 计算水平灰度共生矩阵
        void getHorisonGLCM(VecGLCM &src, VecGLCM &dst, int imgWidth, int imgHeight);
        // 计算垂直灰度共生矩阵
        void getVertialGLCM(VecGLCM &src, VecGLCM &dst, int imgWidth, int imgHeight);
        // 计算 45 度灰度共生矩阵
        void getGLCM45(VecGLCM &src, VecGLCM &dst, int imgWidth, int imgHeight);
        // 计算 135 度灰度共生矩阵
        void getGLCM135(VecGLCM &src, VecGLCM &dst, int imgWidth, int imgHeight);
    
    private:
        int m_grayLevel;        // 将灰度共生矩阵划分为 grayLevel 个等级
    
    };

    GLCM.cpp

    #include "GLCM.h"
    
    GLCM::GLCM() : m_grayLevel(16)
    {
    
    }
    
    GLCM::~GLCM()
    {
    
    }
    
    //==============================================================================
    // 函数名称: initGLCM
    // 参数说明: vecGLCM,要进行初始化的共生矩阵,为二维方阵
    //          size, 二维矩阵的大小,必须与图像划分的灰度等级相等
    // 函数功能: 初始化二维矩阵
    //==============================================================================
    
    void GLCM::initGLCM(VecGLCM& vecGLCM, int size)
    {
        assert(size == m_grayLevel);
        vecGLCM.resize(size);
        for (int i = 0; i < size; ++i)
        {
            vecGLCM[i].resize(size);
        }
    
        for (int i = 0; i < size; ++i)
        {
            for (int j = 0; j < size; ++j)
            {
                vecGLCM[i][j] = 0;
            }
        }
    }
    
    //==============================================================================
    // 函数名称: getHorisonGLCM
    // 参数说明: src,要进行处理的矩阵,源数据
    //          dst,输出矩阵,计算后的矩阵,即要求的灰度共生矩阵
    //          imgWidth, 图像宽度
    //          imgHeight, 图像高度
    // 函数功能: 计算水平方向的灰度共生矩阵
    //==============================================================================
    
    void GLCM::getHorisonGLCM(VecGLCM &src, VecGLCM &dst, int imgWidth, int imgHeight)
    {
        int height = imgHeight;
        int width = imgWidth;
    
        for (int i = 0; i < height; ++i)
        {
            for (int j = 0; j < width - 1; ++j)
            {
                int rows = src[i][j];
                int cols = src[i][j + 1];
                dst[rows][cols]++;
            }
        }
    
    
    }
    
    //==============================================================================
    // 函数名称: getVertialGLCM
    // 参数说明: src,要进行处理的矩阵,源数据
    //          dst,输出矩阵,计算后的矩阵,即要求的灰度共生矩阵
    //          imgWidth, 图像宽度
    //          imgHeight, 图像高度
    // 函数功能: 计算垂直方向的灰度共生矩阵
    //==============================================================================
    
    void GLCM::getVertialGLCM(VecGLCM &src, VecGLCM &dst, int imgWidth, int imgHeight)
    {
        int height = imgHeight;
        int width = imgWidth;
        for (int i = 0; i < height - 1; ++i)
        {
            for (int j = 0; j < width; ++j)
            {
                int rows = src[i][j];
                int cols = src[i + 1][j];
                dst[rows][cols]++;
            }
        }
    }
    
    //==============================================================================
    // 函数名称: getGLCM45
    // 参数说明: src,要进行处理的矩阵,源数据
    //          dst,输出矩阵,计算后的矩阵,即要求的灰度共生矩阵
    //          imgWidth, 图像宽度
    //          imgHeight, 图像高度
    // 函数功能: 计算45度的灰度共生矩阵
    //==============================================================================
    
    void GLCM::getGLCM45(VecGLCM &src, VecGLCM &dst, int imgWidth, int imgHeight)
    {
        int height = imgHeight;
        int width = imgWidth;
        for (int i = 0; i < height - 1; ++i)
        {
            for (int j = 0; j < width - 1; ++j)
            {
                int rows = src[i][j];
                int cols = src[i + 1][j + 1];
                dst[rows][cols]++;
            }
        }
    }
    
    
    //==============================================================================
    // 函数名称: getGLCM135
    // 参数说明: src,要进行处理的矩阵,源数据
    //          dst,输出矩阵,计算后的矩阵,即要求的灰度共生矩阵
    //          imgWidth, 图像宽度
    //          imgHeight, 图像高度
    // 函数功能: 计算 135 度的灰度共生矩阵
    //==============================================================================
    
    void GLCM::getGLCM135(VecGLCM& src, VecGLCM& dst, int imgWidth, int imgHeight)
    {
        int height = imgHeight;
        int width = imgWidth;
        for (int i = 0; i < height - 1; ++i)
        {
            for (int j = 1; j < width; ++j)
            {
                int rows = src[i][j];
                int cols = src[i + 1][j - 1];
                dst[rows][cols]++;
            }
        }
    }
    
    //==============================================================================
    // 函数名称: calGLCM
    // 参数说明: inputImg,要进行纹理特征计算的图像,为灰度图像
    //          vecGLCM, 输出矩阵,根据灰度图像计算出的灰度共生阵
    //          angle,灰度共生矩阵的方向,有水平、垂直、45度、135度四个方向
    // 函数功能: 计算灰度共生矩阵
    //==============================================================================
    
    void GLCM::calGLCM(IplImage* inputImg, VecGLCM& vecGLCM, int angle)
    {
        assert(inputImg->nChannels == 1);
        IplImage* src = NULL;
        src = cvCreateImage(cvGetSize(inputImg), IPL_DEPTH_32S, inputImg->nChannels);
        cvConvert(inputImg, src);
    
        int height = src->height;
        int width = src->width;
        int maxGrayLevel = 0;
        // 寻找最大像素灰度最大值
        for (int i = 0; i < height; ++i)
        {
            for (int j = 0; j < width; ++j)
            {
                int grayVal = cvGetReal2D(src, i, j);
                if (grayVal > maxGrayLevel)
                {
                    maxGrayLevel = grayVal;
                }
    
            }
        }// end for i
    
        ++maxGrayLevel;
        VecGLCM tempVec;
        // 初始化动态数组
        tempVec.resize(height);
        for (int i = 0; i < height; ++i)
        {
            tempVec[i].resize(width);
        }
    
        if (maxGrayLevel > 16)//若灰度级数大于16,则将图像的灰度级缩小至16级,减小灰度共生矩阵的大小。
        {
            for (int i = 0; i < height; ++i)
            {
                for (int j = 0; j < width; ++j)
                {
                    int tmpVal = cvGetReal2D(src, i, j);
                    tmpVal /= m_grayLevel;
                    tempVec[i][j] = tmpVal;
                }
            }
    
            if (angle == GLCM_HORIZATION)  // 水平方向
                getHorisonGLCM(tempVec, vecGLCM, width, height);
            if (angle == GLCM_VERTICAL)    // 垂直方向
                getVertialGLCM(tempVec, vecGLCM, width, height);
            if (angle == GLCM_ANGLE45)     // 45 度灰度共生阵
                getGLCM45(tempVec, vecGLCM, width, height);
            if (angle == GLCM_ANGLE135)    // 135 度灰度共生阵
                getGLCM135(tempVec, vecGLCM, width, height);
        }
        else//若灰度级数小于16,则生成相应的灰度共生矩阵
        {
            for (int i = 0; i < height; ++i)
            {
                for (int j = 1; j < width; ++j)
                {
                    int tmpVal = cvGetReal2D(src, i, j);
                    tempVec[i][j] = tmpVal;
                }
            }
    
            if (angle == GLCM_HORIZATION)  // 水平方向
                getHorisonGLCM(tempVec, vecGLCM, width, height);
            if (angle == GLCM_VERTICAL)    // 垂直方向
                getVertialGLCM(tempVec, vecGLCM, width, height);
            if (angle == GLCM_ANGLE45)     // 45 度灰度共生阵
                getGLCM45(tempVec, vecGLCM, width, height);
            if (angle == GLCM_ANGLE135)    // 135 度灰度共生阵
                getGLCM135(tempVec, vecGLCM, width, height);
        }
    
        cvReleaseImage(&src);
    }
    
    //==============================================================================
    // 函数名称: getGLCMFeatures
    // 参数说明: vecGLCM, 输入矩阵,灰度共生阵
    //          features,灰度共生矩阵计算的特征值,主要包含了能量、熵、对比度、逆差分矩
    // 函数功能: 根据灰度共生矩阵计算的特征值
    //==============================================================================
    
    void GLCM::getGLCMFeatures(VecGLCM& vecGLCM, GLCMFeatures& features)
    {
        int total = 0;
    
        for (int i = 0; i < m_grayLevel; ++i)
        {
            for (int j = 0; j < m_grayLevel; ++j)
            {
                total += vecGLCM[i][j];     // 求所有图像的灰度值的和
            }
        }
    
        vector<vector<double> > temp;
        temp.resize(m_grayLevel);
        for (int i = 0; i < m_grayLevel; ++i)
        {
            temp[i].resize(m_grayLevel);
        }
    
        // 归一化
        for (int i = 0; i < m_grayLevel; ++i)
        {
            for (int j = 0; j < m_grayLevel; ++j)
            {
                temp[i][j] = (double)vecGLCM[i][j] / (double)total;
            }
        }
    
        for (int i = 0; i < m_grayLevel; ++i)
        {
            for (int j = 0; j < m_grayLevel; ++j)
            {
                features.energy += temp[i][j] * temp[i][j];
    
                if (temp[i][j]>0)
                    features.entropy -= temp[i][j] * log(temp[i][j]);               //熵     
    
                features.contrast += (double)(i - j)*(double)(i - j)*temp[i][j];        //对比度
                features.idMoment += temp[i][j] / (1 + (double)(i - j)*(double)(i - j));//逆差矩
            }
        }
    }

    main.cpp

    #include "GLCM.h"
    #include <string>
    
    void getFileName();
    string names[2000];
    char data[20];
    const string filename = "C:\\Users\\ltc\\Desktop\\data5\\Sobel\\数值处理\\背景\\";
    
    int main()
    {
        fstream finout1("data.txt", ios::in | ios::out|ios::trunc);
        getFileName();
        int i = 0;
        char data1[20];
        while (names[i].length() > 5){
            strcpy_s(data1, names[i].c_str());
            string imagename = data1;
            //灰度共生矩阵
            IplImage* img = cvLoadImage(data1, 0);
            cvSetImageROI(img, cvRect(1453, 1149,557, 557));
            /*cvNamedWindow("ShowSRC"); 
            cvShowImage("ShowSRC",img); 
            cvWaitKey(0);  */
    
            GLCM glcm;
            VecGLCM vec;
            GLCMFeatures features;
            glcm.initGLCM(vec);
            // 水平
            glcm.calGLCM(img, vec, GLCM::GLCM_HORIZATION);
            glcm.getGLCMFeatures(vec, features);
            double energy_hor = features.energy;
            double entropy_hor = features.entropy;
            double contrast_hor = features.contrast;
            double idMoment_hor = features.idMoment;
    
            // 垂直
            glcm.calGLCM(img, vec, GLCM::GLCM_VERTICAL);
            glcm.getGLCMFeatures(vec, features);
            double energy_vetical = features.energy;
            double entropy_vetical = features.entropy;
            double contrast_vetical = features.contrast;
            double idMoment_vetical = features.idMoment;
    
    
            // 45 度
            glcm.calGLCM(img, vec, GLCM::GLCM_ANGLE45);
            glcm.getGLCMFeatures(vec, features);
            double energy_45 = features.energy;
            double entropy_45 = features.entropy;
            double contrast_45 = features.contrast;
            double idMoment_45 = features.idMoment;
    
    
            // 135 度
            glcm.calGLCM(img, vec, GLCM::GLCM_ANGLE135);
            glcm.getGLCMFeatures(vec, features);
            double energy_135 = features.energy;
            double entropy_135 = features.entropy;
            double contrast_135 = features.contrast;
            double idMoment_135 = features.idMoment;
    
            double energy_average = (energy_135 + energy_45 + energy_hor + energy_vetical) / 4;
            double entropy_average = (entropy_135 + entropy_45 + entropy_hor + entropy_vetical) / 4;
            double contrast_average = (contrast_135 + contrast_45 + contrast_hor + contrast_vetical) / 4;
            double idMoment_average = (idMoment_135 + idMoment_45 + idMoment_hor + idMoment_vetical) / 4;
    
    
            cout<< energy_average<<"  " <<entropy_average <<"  "<< contrast_average<<"  " << idMoment_average << endl;
            finout1 << energy_average<<"  " <<entropy_average <<"  "<< contrast_average<<"  " << idMoment_average << endl;
            i++;
        }
        system("pause");
        return 0;
    }
    
    void getFileName(){
        fstream finout("C:\\Users\\ltc\\Desktop\\data5\\FILENAME.TXT", ios::in | ios::out);
        ostringstream outstr;
        if (finout.is_open()){
            finout.seekg(0);
            int i = 0;
            while (finout.getline(data, 19)){
                outstr << data;
    
                names[i] = outstr.str();
                //cout <<setw(30)<<i<<setw(30)<<names[i]<<'\n';
                i++;
                outstr.str("");
    
            }
        }
        else
            cout << "failed" << endl;
    }

    最近事情较多,博客没有及时更新,但是留言私信我都会看到,欢迎交流!
    青雲-吾道乐途

    展开全文
  • 灰度共生矩阵特征分析法相邻某一间隔长度的两像素,它们之间要么具有相同的灰度级,要么具有不同的灰度级,若能找出这样两像素的联合分布的统计形式,对于图像的纹理分析很有意义。灰度共生矩阵(GLDM)的统计方法...

    灰度共生矩阵特征分析法

    相邻某一间隔长度的两个像素,它们之间要么具有相同的灰度级,要么具有不同的灰度级,若能找出这样两个像素的联合分布的统计形式,对于图像的纹理分析很有意义。

    灰度共生矩阵(GLDM)的统计方法是20世纪70年代初由R.Haralick等人提出的,它是在假定图像中各像素间的空间分布关系包含了图像纹理信息的前提下,提出的具有广泛性的纹理分析方法。

    灰度共生矩阵被定义为从图像中每一个灰度为i的像素点出发,离开某个固定位置(相隔距离为d,方位为0度、45度、90度等),正好灰度值为j的概率,即所有估计的值可以表示成一个矩阵的形式,以此被称为灰度共生矩阵。

    这里:

    1.从哪个灰度级i出发,人为指定。

    2.相隔距离与方向也人为指定,方向可以通过[0 d]来指定。

    0度:              [0 d]

    45度:             [-d d]

    90度:             [-d 0]

    135度:            [-d -d]

    3.另一个灰度级j也人为指定。

    对于纹理变化缓慢的图像,其灰度共生矩阵对角线上的数值较大;而对于纹理变化较快的图像,其灰度共生矩阵对角线上的数值较小,对角线两侧的值较大。

    由于灰度共生矩阵的数据量较大,一般不直接作为区分纹理的特征,而是基于它构建的一些统计量作为纹理分类特征。

    Haralick曾提出了14种基于灰度共生矩阵计算出来的统计量:即:能量、熵、对比度、均匀性、相关性、方差、和平均、和方差、和熵、差方差、差平均、差熵、相关信息测度以及最大相关系数。

    下图显示了如何求解灰度共生矩阵:

    下面这幅图总有8个灰度级

    以出发点灰度级1,目标点灰度级也为1为例,设查找方向水平间隔为1(方向为水平方向,包括左右),GLCM(1,1)值为1说明只有1对的像素水平相邻。

    以出发点灰度级1,目标点灰度级也为2为例,设查找方向水平间隔为1(方向为水平方向,包括左右),GLCM(1,2)值为1说明只有2对的像素水平相邻。

    举例几种常用的统计值

    1.角二阶矩(Angular Second Moment, ASM)

    角二阶矩又称能量,是图像灰度分布均匀程度和纹理粗细的一个度量,反映了图像灰度分布均匀程度和纹理粗细度。当图像纹理均一规则时,能量值较大;反之灰度共生矩阵的元素值相近,能量值较小。

    2.熵(Entropy, ENT)

    熵度量了图像包含信息量的随机性,表现了图像的复杂程度。当共生矩阵中所有值均相等或者像素值表现出最大的随机性时,熵最大。

    3.对比度

    对比度反应了图像的清晰度和纹理的沟纹深浅。纹理越清晰反差越大对比度也就越大。

    4.反差分矩阵(Inverse Differential Moment, IDM)

    反差分矩阵又称逆方差,反映了纹理的清晰程度和规则程度,纹理清晰、规律性较强、易于描述的,值较大。

    5.能量

    能量变换反映了图像灰度分布均匀程度和纹理粗细度。若灰度共生矩阵的元素值相近,则能量较小,表示纹理细致;若其中一些值大,而其它值小,则能量值较大。能量值大表明一种较均一和规则变化的纹理模式。

    6.逆方差

    逆方差反映了图像纹理局部变化的大小,若图像纹理的不同区域间较均匀,变化缓慢,逆方差会较大,反之较小。

    7.相关性

    用来度量图像的灰度级在行或列方向上的相似程度,因此值得大小反应了局部灰度相关性,值越大,相关性也越大。

    展开全文
  • 灰度共生矩阵(附python代码)

    千次阅读 2020-06-03 16:45:23
    灰度共生矩阵陌生的家伙,于是便有此文。 主要参考博客1:http://blog.csdn.net/jialeheyeshu/article/details/51337225 主要参考博客2:http://blog.csdn.net/guanyuqiu/article/details/53117507 主要参考...

    理论内容引自https://blog.csdn.net/qq_37059483/article/details/78292869


    最近在研究机器学习相关内容,后面会尽量花时间整理成一个系列的博客,然后朋友让我帮他实现一种基于SVR支持向量回归的图像质量评价方法,然而在文章的开头竟然发现
    灰度共生矩阵这个陌生的家伙,于是便有此文。

    主要参考博客1:http://blog.csdn.net/jialeheyeshu/article/details/51337225
    主要参考博客2:http://blog.csdn.net/guanyuqiu/article/details/53117507
    主要参考博客3:http://www.cnblogs.com/rong86/p/3695621.html
    主要参考博客4:http://blog.csdn.net/lingtianyulong/article/details/53032034

    1.灰度共生矩阵生成原理
      灰度共生矩阵(GLDM)的统计方法是20世纪70年代初由R.Haralick等人提出的,它是在假定图像中各像素间的空间分布关系包含了图像纹理信息的前提下,提出的具有广泛性的纹理分析方法。

       灰度共生矩阵被定义为从灰度为i的像素点出发,离开某个固定位置(相隔距离为d,方位为)的点上灰度值为的概率,即,所有估计的值可以表示成一个矩阵的形式,以此被称为灰度共生矩阵。对于纹理变化缓慢的图像,其灰度共生矩阵对角线上的数值较大;而对于纹理变化较快的图像,其灰度共生矩阵对角线上的数值较小,对角线两侧的值较大。由于灰度共生矩阵的数据量较大,一般不直接作为区分纹理的特征,而是基于它构建的一些统计量作为纹理分类特征。Haralick曾提出了14种基于灰度共生矩阵计算出来的统计量:即:能量、熵、对比度、均匀性、相关性、方差、和平均、和方差、和熵、差方差、差平均、差熵、相关信息测度以及最大相关系数。

      在网上看了很多灰度共生矩阵生成的例子感觉都没有说明白,要不就直接上结果要不就给一堆看不懂的代码和公式,后来看了matlab中的介绍就明白了,其实很简单,仔细把下面的看三遍就理解怎么来的了!(我是第三篇看明白的,当时很紧张,相信你们没问题)
      下图显示了如何求解灰度共生矩阵,以(1,1)点为例,GLCM(1,1)值为1说明只有一对灰度为1的像素水平相邻。GLCM(1,2)值为2,是因为有两对灰度为1和2的像素水平相邻。(MatLab说明文档)
    这里写图片描述

    GLCM表其实就是所有像素可能的组合,比如,GLCM(1,1)就是I中像素值为1和1的组合,GLCM(4,5)就是I中像素4和像素5的组合,GLCM(i,j)的值呢就是I中像素为i,像素为j的有有多少和相邻的成对点。这个相邻有个规则:就是f(x,y),f(x+a,y+b)相邻,就是只有x相隔a的单位,y相隔b个单位,我们认为是相邻的。
    平时我们说相邻:B点在A点右边,其实就是这里的a=1,b=0,也就是f(x,y)和f(x+1,y+0)相邻。
    于是就有了:
    a=1,b=0 时我们就说水平相邻:也就是0度的时候
    a=1,b=1 时我们就说对角相邻,也就是45度的时候
    a=-1,b=1时 即135度
    其他角度类似。
    在a=1,b=0时:GLCM(1,1)=1;其实就是I中有几个1和1相邻(1个)(按上面的规则)GLCM(1,2)=2,几个1和2相邻(2个)。ok!
    后面好多的性质,都是在把这个矩阵计算出来之后再在这个基础上运算的,那些就不难了!

    附加理解2:
    共生矩阵用两个位置的像素的联合概率密度来定义,它不仅反映亮度的分布特征,也反映具有同样亮度或者接近亮度的像素之间的位置分布特性,是有关图像亮度变化的二阶统计特征。它是定义一组纹理特征的基础。

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

    灰度直方图是对图像上单个像素具有某个灰度进行统计的结果,

    而灰度共生矩阵是对图像上保持某距离的两像素分别具有某灰度的状况进行统计得到的。

    取图像(N×N)中任意一点 (x,y)及偏离它的另一点 (x+a,y+b),设该点对的灰度值为(g1,g2)。令点(x,y) 在整个画面上移动,则会得到各种 (g1,g2)值,设灰度值的级数为 k,则(g1,g2) 的组合共有 k^2;种。对于整个画面,统计出每一种(g1,g2)值出现的次数,然后排列成一个方阵,在用(g1,g2) 出现的总次数将它们归一化为出现的概率P(g1,g2),这样的方阵称为灰度共生矩阵。距离差分值(a,b) 取不同的数值组合,可以得到不同情况下的联合概率矩阵。(a,b)取值要根据纹理周期分布的特性来选择,对于较细的纹理,选取(1,0)、(1,1)、(2,0)等小的差分值。  当 a=1,b=0时,像素对是水平的,即0度扫描;当a=0,b=1 时,像素对是垂直的,即90度扫描;当 a=1,b=1时,像素对是右对角线的,即45度扫描;当 a=-1,b=-1时,像素对是左对角线,即135度扫描。
    这样,两个象素灰度级同时发生的概率,就将 (x,y)的空间坐标转化为“灰度对” (g1,g2)的描述,形成了灰度共生矩阵。(百度百科)
    一幅图象的灰度共生矩阵能反映出图象灰度关于方向、相邻间隔、变化幅度的综合信息,它是分析图象的局部模式和它们排列规则的基础。

    感觉差不多了吧!

    2.灰度共生矩阵特征量(字写的不好,请见谅)

    2.1对比度

    度量 矩阵的值是如何分布和图像中局部变化的多少,反应了图像的清晰度和纹理的沟纹深浅。纹理的沟纹越深,反差越大,效果越清晰;反之,对比值小,则沟纹浅,效果模糊。
    在这里插入图片描述

    2.2 能量

    能量变换反映了图像灰度分布均匀程度和纹理粗细度。若灰度共生矩阵的元素值相近,则能量较小,表示纹理细致;若其中一些值大,而其它值小,则能量值较大。能量值大表明一种较均一和规则变化的纹理模式。

    在这里插入图片描述

    2.3 熵

    图像包含信息量的随机性度量。当共生矩阵中所有值均相等或者像素值表现出最大的随机性时,熵最大;因此熵值表明了图像灰度分布的复杂程度,熵值越大,图像越复杂。

    在这里插入图片描述

    2.4 逆方差

    逆方差反映了图像纹理局部变化的大小,若图像纹理的不同区域间较均匀,变化缓慢,逆方差会较大,反之较小。

    在这里插入图片描述

    2.5相关性

    用来度量图像的灰度级在行或列方向上的相似程度,因此值得大小反应了局部灰度相关性,值越大,相关性也越大。

    在这里插入图片描述
    3、代码

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    import cv2
    import math
    
    #定义最大灰度级数
    gray_level = 16
    
    def maxGrayLevel(img):
        max_gray_level=0
        (height,width)=img.shape
        print ("图像的高宽分别为:height,width",height,width)
        for y in range(height):
            for x in range(width):
                if img[y][x] > max_gray_level:
                    max_gray_level = img[y][x]
        print("max_gray_level:",max_gray_level)
        return max_gray_level+1
    
    def getGlcm(input,d_x,d_y):
        srcdata=input.copy()
        ret=[[0.0 for i in range(gray_level)] for j in range(gray_level)]
        (height,width) = input.shape
    
        max_gray_level=maxGrayLevel(input)
        #若灰度级数大于gray_level,则将图像的灰度级缩小至gray_level,减小灰度共生矩阵的大小
        if max_gray_level > gray_level:
            for j in range(height):
                for i in range(width):
                    srcdata[j][i] = srcdata[j][i]*gray_level / max_gray_level
    
        for j in range(height-d_y):
            for i in range(width-d_x):
                rows = srcdata[j][i]
                cols = srcdata[j + d_y][i+d_x]
                ret[rows][cols]+=1.0
    
        for i in range(gray_level):
            for j in range(gray_level):
                ret[i][j]/=float(height*width)
    
        return ret
    
    def feature_computer(p):
        #con:对比度反应了图像的清晰度和纹理的沟纹深浅。纹理越清晰反差越大对比度也就越大。
        #eng:熵(Entropy, ENT)度量了图像包含信息量的随机性,表现了图像的复杂程度。当共生矩阵中所有值均相等或者像素值表现出最大的随机性时,熵最大。
        #agm:角二阶矩(能量),图像灰度分布均匀程度和纹理粗细的度量。当图像纹理均一规则时,能量值较大;反之灰度共生矩阵的元素值相近,能量值较小。
        #idm:反差分矩阵又称逆方差,反映了纹理的清晰程度和规则程度,纹理清晰、规律性较强、易于描述的,值较大。
        Con=0.0
        Eng=0.0
        Asm=0.0
        Idm=0.0
        for i in range(gray_level):
            for j in range(gray_level):
                Con+=(i-j)*(i-j)*p[i][j]
                Asm+=p[i][j]*p[i][j]
                Idm+=p[i][j]/(1+(i-j)*(i-j))
                if p[i][j]>0.0:
                    Eng+=p[i][j]*math.log(p[i][j])
        return Asm,Con,-Eng,Idm
    
    def test(image_name):
        img = cv2.imread(image_name)
        try:
            img_shape=img.shape
        except:
            print ('imread error')
            return
    
        #这里如果用‘/’会报错TypeError: integer argument expected, got float
        #其实主要的错误是因为 因为cv2.resize内的参数是要求为整数
        img=cv2.resize(img,(img_shape[1]//2,img_shape[0]//2),interpolation=cv2.INTER_CUBIC)
    
        img_gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
        glcm_0=getGlcm(img_gray, 1,0)
        #glcm_1=getGlcm(src_gray, 0,1)
        #glcm_2=getGlcm(src_gray, 1,1)
        #glcm_3=getGlcm(src_gray, -1,1)
        print(glcm_0)
    
        asm,con,eng,idm=feature_computer(glcm_0)
    
        return [asm,con,eng,idm]
    
    if __name__=='__main__':
        result = test("/home/images/2019-05-27/8/20190527_17_29_03_X1_Y2.jpg")
        print(result)
    
    
    
    展开全文
  • 灰度共生矩阵及其统计量使用

    万次阅读 2018-07-01 17:20:19
    网上关于灰度共生矩阵及其统计量的介绍有很多,这里就不再赘述了。...Haralick等人定义了14个纹理分析的灰度共生矩阵特征参数。Ulaby等人研究发现:在基GLCM的14个纹理特征中,仅有4个特征是不相关的,这...
  • matlab灰度共生矩阵

    2021-04-25 11:35:56
    通过实验证明了基于灰度共生矩阵的统计特征的有效性。洪继光于 1984 年在灰...0.0931894 图 2 实验用半调图 该结果各项数据经与使用 Matlab 处理的结果......针对图像灰度共 生矩阵纹理二次特征提取问题的需求,本文...
  • 灰度共生矩阵特征提取—OpenCV

    万次阅读 2016-11-04 10:06:11
    因为OpenCV中自带的灰度共生矩阵的计算使用过程中,经常出现问题;之前在项目中使用了别人基于OpenCV重新编写cl_texture的灰度共生矩阵,但该代码只能在MFC环境下使用,且不能释放内存;现有的网上流行的基于OpenCV...
  • 那么生成的单个像素点的灰度共生矩阵的维度是64×64) 下面用一例子来说明计算过程: 假设我们现在有一副图像,我们得到其中的一像素点的灰度共生矩阵,计算其纹理特征值,它的大小为6×6,灰度被分为4阶(0,1...
  • 灰度共生矩阵(GLCM)

    2020-04-13 17:08:34
    灰度共生矩阵(GLCM) 算法简介 灰度共生矩阵法(GLCM, Gray - level co - occurrence matrix),就是通过计算灰度图像得到它的共生矩阵,然后透过计算该共生矩阵得到矩阵的部分特征值,来分别代表图像的某些纹理特征...
  • 图像特征_灰度共生矩阵

    千次阅读 2016-09-20 17:28:57
    转:http://www.cnblogs.com/tiandsp/archive/2013/03/23/2977673.html ...Gray-level co-occurrence matrix from an image 全 图像的灰度共生矩阵灰度共生矩阵是像素距离和角度的矩阵
  • python灰度共生矩阵GLCM,带公式和代码

    千次阅读 热门讨论 2019-09-05 10:35:45
    灰度共生矩阵所代表的含义是图像的灰度值在空间的某个方向上的特点,但是如何衡量两目标图像纹理之间的差异是不能直接使用灰度共生矩阵表示出来的,所以需要使用一特定的模型去统计灰度共生矩阵的特性来描述纹理...
  • 灰度共生矩阵-python

    万次阅读 多人点赞 2018-06-06 18:26:09
    本篇博客参考灰度共生矩阵(GLCM)附Python代码 ,对其进行了完善...灰度共生矩阵中每元素的值可以定义为(x, y)点与(x + dx, y + dy)点的值对为(i, j)的概率。统计整幅图像中每一种灰度值组合出现的概率矩阵 P 即...
  • //若灰度级数大于16,则将图像的灰度级缩小至16级,减小灰度共生矩阵的大小。 { for ( int i = 0 ; i ; i++) { int *srcdata = src.ptr< int >(i); for ( int j = 0 ; j ; j++) { srcdata[j] = ( ...
  • 纹理特征提取方法:LBP, 灰度共生矩阵

    万次阅读 多人点赞 2017-05-10 17:21:27
    纹理特征提取方法:LBP, 灰度共生矩阵在前面的博文《图像纹理特征总体简述》中,笔者总结了图像纹理特征及其分类。在这里笔者对其中两种算法介绍并总结。参考网址: 《纹理特征提取》 《【纹理特征】LBP 》 ...
  • 灰度共生矩阵(超简单理解)

    万次阅读 多人点赞 2020-06-01 15:43:22
      灰度共生矩阵被定义为从灰度为i的像素点出发,离开某个固定位置(相隔距离为d,方位为)的点上灰度值为的概率,即,所有估计的值可以表示成一矩阵的形式,以此被称为灰度共生矩阵。对于纹理变化缓慢的图像,其...
  • 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(...
  • GLCM复习备用:纹理分析是对图像灰度(浓淡)空间分布模式的提取和分析。纹理分析在遥感图像、X射线照片、细胞图像判读和处理方面有广泛的应用。关于纹理,还没有一统一的数学模型。它起源于表征纺织品表面性质的...
  • Emgucv不完整图像分割试验(三)——纹理+色彩分割 ,...尤其是计算灰度共生矩阵方面。 网搜Accord可搜素C#语言下完整的人工智能类库,afrog已经被吸收进去,参见accord.image 使用时最好从Nuget安装。获...
  • 纹理——灰度共生矩阵公式及代码

    千次阅读 2019-08-27 15:29:07
    Level Co-occurence Matrix,GLCM)被定义为从灰度为i的像素点出发,离开某个固定位置(相隔距离为d,方位为)的点上灰度值为的概率,即,所有估计的值可以表示成一矩阵的形式,以此被称为灰度共生矩阵。...
  • 本博文简述灰度共生矩阵的定义、实现原理,介绍MATLAB提供的函数用法以及实现
  • 灰度共生矩阵及其数字特征Any number system has a set of symbols known as Digits with some rules performing arithmetic operations. A collection of these makes a number has two parts. They are integer ...
  • 灰度共生矩阵的原理及代码实现(python) 1原理: 灰度共生矩阵(Gray Level Co-occurrence Matrix,...在实际应用中,一幅灰度影像的灰度级一般为256级,在计算由灰度共生矩阵推导出的纹理特征时,要求影像的灰...
  • 灰度共生矩阵

    千次阅读 2017-10-27 15:36:01
    灰度共生矩阵      灰度共生矩阵,Gray Level Co-occurrence Matrix,简写为GLCM  由于纹理是由灰度分布在空间位置上反复出现而形成的,因而在图像空间中相隔某距离的两象素之间会存在一定的灰度关系...
  • 我下了一灰度梯度共生矩阵提取纹理特征的源程序,现在我处理图像 比如说matlab自带的一幅图像cions.png下面是源程序:function OUT=GrayGradinet(IN)% 灰度梯度共生矩阵 H%归一化灰度梯度矩阵 H_basic%小梯度...
  • 灰度共生矩阵(GLCM)附Python代码

    万次阅读 多人点赞 2018-03-06 22:47:42
    灰度共生矩阵(Gray-Level Co-occurrence Matrix,GLCM)统计了灰度图中像素间的灰度值分布规律以区分不同的纹理。 度共生矩阵可以定义为一灰度为iii的像素点与另一与之对应位置上的像素点的灰度值为jjj的概率...

空空如也

空空如也

1 2 3 4 5 ... 18
收藏数 345
精华内容 138
关键字:

灰度共生矩阵14个特征