文章目录

  • 1,灰度共生矩阵(Gray Level Cooccurrence Matrix)
    • 1.0感谢
    • 1.1初识
    • 1.2Opencv实现
  • 2,灰度梯度共生矩阵(Gray-Gradient Cooccurence Matrix,GGCM)
    • 2.0,感谢
    • 2.1,初识
    • 2.2,Opencv实现

学习记录,不当之处多多指教,在此感谢以下博主

1,灰度共生矩阵(Gray Level Cooccurrence Matrix)

1.0感谢

灰度共生矩阵的原理及实现(特征提取)-OpenCV
灰度共生矩阵的生成和理解
灰度共生矩阵原理

1.1初识


以水平相邻为例:
GLCM(1,1)=1表示I图中左右相邻都为1的只有一对
GLCM(1,2)=2表示I图中左右分别为1,2的有两对,如上图的红线所示

通常我们假设有两个点f(x,y)与f(x+a,y+b)相邻:x方向相隔a,y方向相隔b
a=1,b=0:水平相邻,0度
a=1,b=1:对角相邻,45度
a=-1,b=1:对角相邻,135度

1,灰度共生矩阵定义为:从灰度为i的像素点出发,统计保持一定距离的两具有某灰度分布的像素。统计"灰度对"同时发生的概率,形成了灰度共生矩阵。
2,共生矩阵用两个位置的像素的联合概率密度来定义,它不仅反应亮度的分布特征,也反映具有相同亮度或者接近亮度像素之间的位置分布特性,是有关图像亮度变换的二阶统计特征。
3,一般不直接作为区分纹理特征(数据量大),一般采用如下统计量:能量,熵,对比度,均匀性,相关性,方差,和平均,和方差,和熵,差方差,差平均,差熵,相关信息测度,最大相关系数。

能量:角二阶矩阵(Angular Second Moment,ASM),Energy,uniformity,uniformity of energy
公式: ASM=sum(p(i,j).^2)
 p(i,j)是归一化的灰度共生矩阵。反应了图像灰度分布均匀程度和纹理粗细度,图像均匀,纹理较细,反应在共生矩阵就是大量集中在某一部分,因此ASM值大。

熵:(Entropy,ENT)
公式: ENT = sum(p(i,j)*(-log(p(i,j))))
 p(i,j)是归一化的灰度共生矩阵。描述图像具有的信息量的度量,表明图像的复杂度,和复杂度成正比。

反差分矩阵:(Inverse Differential Moment,IDM)
公式: IDM = sum(p(i,j)/(1+(i-j)^2))
 反应了纹理的清晰程度和规则程度,纹理清晰,规律性强,易于描述,值较大,反之较小。

对比度:(Contrast)
公式: contrast= sum(p(i,j)*(i-j)^2)
 返回图像中某个像素与它的邻居之间的对比度。反映了图像的清晰度和纹理沟纹深浅的程度

1.2Opencv实现

代码源自: 传送门

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;      // 能量ASM:angular second moment  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);// 设置灰度划分等级,默认值为 16void 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 "stdafx.h"
#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 = (tmpVal*m_grayLevel)/maxGrayLevel;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]; //ASMif (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));//逆差矩}}
}

调用:

     //src为输入图像IplImage,自己load一张图像即可IplImage* img = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);cvCopy(src,img);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;

 原作者灰度分级

//GLCM.cpp Line187
tmpVal /= m_grayLevel);

改为

tmpVal = (tmpVal*m_grayLevel)/maxGrayLevel;

2,灰度梯度共生矩阵(Gray-Gradient Cooccurence Matrix,GGCM)

2.0,感谢

灰度梯度共生矩阵纹理特征
灰度梯度共生矩阵Python

2.1,初识

 1,灰度梯度共生矩阵不仅反应了灰度之间的关系,还反映了梯度之间的关系。灰度是构建图像的基础,梯度是构建图像边缘的要素。
 2,描绘了图像内各像素点灰度与梯度的分布规律,给出了像点与其领域内像点的空间关系,能很好的描绘纹理。对于方向性的纹理也可以从梯度方向上反应出来。
 3,由之前相邻的像素点组成的共生矩阵变成灰度度和梯度图对应点组成的共生矩阵。
 4, 与GLCM的区别,GLCM是灰度级nGray*nGray组成的矩阵,GGCM是灰度级nGray与梯度级nGrad组成的矩阵。GLCM统计的是灰度对(相邻或其他方式)的个数,GGCM统计的是灰度-梯度对(灰度图像,梯度图像相同位置对应)的个数。

2.2,Opencv实现

灰度共生矩阵灰度梯度共生矩阵相关推荐

  1. 图像的灰度化灰度值的读取Matlab

    matlab中图像的灰度化: H = imread('test.png'); I = rgb2gray(H); 原图和灰度图: 在matlab工作区选取灰度矩阵I,即可得到图像详细的灰度值矩阵 图片上 ...

  2. 图像灰度值 灰度值与像素值的关系

    图像灰度值的概念是什么?灰度也可以认为是亮度,简单说就是色彩的深浅程度. 实际上在我们的日常生活中,通过三原色色彩深浅的组合,可以组成各种不同的颜色.产品能够展现的灰度数量越多,也就意味着这款产品的色 ...

  3. OpenCV 中用cv::IMREAD_GRAYSCALE与cv::cvtColor转灰度得到灰度图不一致问题

    首先要强调的是,对于原本灰度的图像,进行默认cv::imread读取,读到的仍是CV_8UC3(16)类型的,而非CV_8UC1(1).其三个通道像素值相等! 因此要正确读入灰度图,需要加一些参数. ...

  4. php灰度发布,灰度发布浅析

    定义 灰度发布就是已一种平滑过渡的方式来发布,通过切换线上新旧版本之间的路由权重,逐步从旧版本切换到新版本:比如要上线新功能,首先只是更新少量的服务节点,通过路由权重,让少部分用户体验新版本,如果没有 ...

  5. 基于灰度共生矩阵(GLCM)的图像纹理分析与提取

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 灰度共生矩阵 灰度共生矩阵(Gray Level CO-Occur ...

  6. 二维特征分类的基础_纹理特征1:灰度共生矩阵(GLCM)

    GLCM复习备用: 纹理分析是对图像灰度(浓淡)空间分布模式的提取和分析.纹理分析在遥感图像.X射线照片.细胞图像判读和处理方面有广泛的应用.关于纹理,还没有一个统一的数学模型.它起源于表征纺织品表面 ...

  7. 计算灰度共生矩阵GLCM

    灰度共生矩阵 灰度共生矩阵定义为像素对的联合分布概率,是一个对称矩阵,它不仅反映图像灰度在相邻的方向.相邻间隔.变化幅度的综合信息,但也反映了相同的灰度级像素之间的位置分布特征,是计算纹理特征的基础. ...

  8. 灰度共生矩阵及matlab实现

    matlab函数: graycomatrix() 功           能:创建灰度共生矩阵 Gray-level co-occurrence matrix from an image 图像的灰度共 ...

  9. 特征提取——灰度共生矩阵(GLCM)

    一. 定义 由于灰度图的纹理是由不同灰度值在空间位置上以某种模式反复出现而形成的,因而在图像空间中相隔某距离的两像素之间会存在一定的灰度关系,即图像中灰度值存在空间相关性.灰度共生矩阵正是利用这一原理 ...

最新文章

  1. js回调函数和函数带参数的使用示例
  2. 有关rsync的一些语句
  3. yolov4负样本_了解各种挂件--帮助读懂YOLOV4
  4. AutoML大提速,谷歌开源自动化寻找最优ML模型新平台Model Search
  5. 2009岁末之复用系统框架(B/S)
  6. 免费!200块全志XR806开源鸿蒙开发板试用
  7. SQL Server查询锁等待
  8. 什么手机用起来最烫手?2019上半年手机温度榜公布...
  9. 浮点数例外 (核心已转储)_五粮液作为“核心支持企业”在进博会精彩亮相_产业综合_行业...
  10. 关于多媒体编解码器和音视频格式
  11. html整人js代码大全,这几行 javascript 代码能让你的浏览器崩溃?
  12. 计算机怎么获取权限删除文件,电脑删除文件需要获取trustedinstaller权限怎么回事...
  13. Excel VBA 高级编程-出入库系统
  14. html语言中网页主体标记是,HTML 网页主体标记
  15. How to Become a Straight-A student
  16. Error “Client wants topic A to have B, but our version has C. Dropping connection.“
  17. 虚拟机上装oracle,cmd窗口输入法有问题,按了U,I,O,P,J,K,L,M这些键为什么不是UIOPJK
  18. 数据分析师培训告诉你 三个最常见的数据分析面试方向
  19. 365智能云打印怎么样?365小票无线订单打印机好用吗?
  20. OpenCV-颜色通道的分离、合并

热门文章

  1. python分析qq聊天记录汉字频率
  2. 情感驿站 | 人生若是修行路,红尘处处皆道场
  3. android 自动更新 覆盖安装后 自动启动的问题
  4. python编写超市销售系统_Python基础项目:超市商品销售管理系统
  5. sql2008+vs2008安装心得以及详细教程
  6. 服务器信息维护员岗位职责,数据管理员岗位职责
  7. 32位和64位系统区别及int字节数
  8. 他山之石:a16z 的 Web3 投资版图
  9. 魔兽服务端linux,在Ubuntu Linux系统下用Wine玩魔兽世界
  10. 全国计算机等级考试二级cpp试题,2017年全国计算机二级C++考试试题附答案