草庐IT

机器学习图像特征提取—灰度共生矩阵(GLCM)纹理特征提取原理及代码实现

暂未成功人士! 2023-07-14 原文

 目录

1 灰度共生矩阵原理

2 灰度共生矩阵特征量

2.1 对比度

2.2 能量

2.3 熵

2.4 逆方差

2.5 相关性

3 灰度共生矩阵特征量提取代码


1 灰度共生矩阵原理

      灰度共生矩阵,指的是一种通过研究灰度的空间相关特性来描述纹理的常用方法。1973年Haralick等人提出了用灰度共生矩阵来描述纹理特征。

       由于纹理是由灰度分布在空间位置上反复出现而形成的,因而在图像空间中相隔某距离的两像素之间会存在一定的灰度关系,即图像中灰度的空间相关特性。

       灰度共生矩阵被定义为从灰度为 i 的像素点出发,离开某个固定位置(相隔距离为d,方位为0°/45°/90°/135°)的点上灰度值为的概率,即,所有估计的值可以表示成一个矩阵的形式,以此被称为灰度共生矩阵。对于纹理变化缓慢的图像,其灰度共生矩阵对角线上的数值较大;而对于纹理变化较快的图像,其灰度共生矩阵对角线上的数值较小,对角线两侧的值较大。由于灰度共生矩阵的数据量较大,一般不直接作为区分纹理的特征,而是基于它构建的一些统计量作为纹理分类特征。Haralick曾提出了14种基于灰度共生矩阵计算出来的统计量:即:能量、熵、对比度、均匀性、相关性、方差、和平均、和方差、和熵、差方差、差平均、差熵、相关信息测度以及最大相关系数。下图显示了如何求解灰度共生矩阵。看概念也是有点难理解,具体过程也可看B站视频讲解(影像组学之radiomics 提取特征的意义(2)_哔哩哔哩_bilibili

2 灰度共生矩阵特征量

2.1 对比度

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

2.2 能量

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

2.3 熵

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

2.4 逆方差

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

2.5 相关性

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

3 灰度共生矩阵特征量提取代码

以下代码提取了灰度共生矩阵的7个特征量:

# =============灰度共生矩阵========================
'''
灰度共生矩阵是像素距离和角度的矩阵函数,
它通过计算图像中一定距离和一定方向的两点灰度之间的相关性,
来反映图像在方向、间隔、变化幅度及快慢上的综合信息。
'''
import numpy as np
import cv2
import math
from matplotlib import pyplot as plt

#定义最大灰度级数
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

    if d_x >= 0 or d_y >= 0:
        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
    else:
        for j in range(height):
            for i in range(width):
                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):
    #mean:均值
    #con:对比度反应了图像的清晰度和纹理的沟纹深浅。纹理越清晰反差越大对比度也就越大。
    #eng:熵(Entropy, ENT)度量了图像包含信息量的随机性,表现了图像的复杂程度。当共生矩阵中所有值均相等或者像素值表现出最大的随机性时,熵最大。
    #agm:角二阶矩(能量),图像灰度分布均匀程度和纹理粗细的度量。当图像纹理均一规则时,能量值较大;反之灰度共生矩阵的元素值相近,能量值较小。
    #idm:反差分矩阵又称逆方差,反映了纹理的清晰程度和规则程度,纹理清晰、规律性较强、易于描述的,值较大。
    #Auto_correlation:相关性
    mean=0.0
    Con=0.0
    Eng=0.0
    Asm=0.0
    Idm=0.0
    Auto_correlation=0.0
    std2=0.0
    std=0.0
    for i in range(gray_level):
        for j in range(gray_level):
            mean+=p[i][j]*i/gray_level**2
            Con+=(i-j)*(i-j)*p[i][j]
            Asm+=p[i][j]*p[i][j]
            Idm+=p[i][j]/(1+(i-j)*(i-j))
            Auto_correlation+=p[i][j]*i*j
            if p[i][j]>0.0:
                Eng+=p[i][j]*math.log(p[i][j])
        for i in range(gray_level):
            for j in range(gray_level):
                std2+=(p[i][j]*i-mean)**2
        std=np.sqrt(std2)
    return mean,Asm,Con,-Eng,Idm,Auto_correlation,std

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 = cv2.resize(img, dsize=(1000, 1000))
    print(img.shape)
    img_gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    glcm_0=getGlcm(img_gray, 1,0)
    #glcm_1=getGlcm(img_gray, 0,1)
    #glcm_2=getGlcm(src_gray, 1,1)
    #glcm_3=getGlcm(src_gray, -1,1)
    #print(glcm_0)
    plt.imshow(glcm_0)
    plt.show()

    mean,asm,con,eng,idm,Auto_correlation,std=feature_computer(glcm_0)

    return [mean,asm,con,eng,idm,Auto_correlation,std]

if __name__=='__main__':
    result1_3=test("./photo/2-5-1250.bmp")

参考来源:影像组学之radiomics 提取特征的意义(2)_哔哩哔哩_bilibili

灰度共生矩阵(超简单理解)_hello~bye~的博客-CSDN博客_灰度共生矩阵

灰度共生矩阵(附python代码)_hello~bye~的博客-CSDN博客_python 灰度共生矩阵

有关机器学习图像特征提取—灰度共生矩阵(GLCM)纹理特征提取原理及代码实现的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  3. ruby-on-rails - 添加回形针新样式不影响旧上传的图像 - 2

    我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司

  4. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  5. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  6. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  7. ruby-on-rails - 在 Ruby (on Rails) 中使用 imgur API 获取图像 - 2

    我正在尝试使用Ruby2.0.0和Rails4.0.0提供的API从imgur中提取图像。我已尝试按照Ruby2.0.0文档中列出的各种方式构建http请求,但均无济于事。代码如下:require'net/http'require'net/https'defimgurheaders={"Authorization"=>"Client-ID"+my_client_id}path="/3/gallery/image/#{img_id}.json"uri=URI("https://api.imgur.com"+path)request,data=Net::HTTP::Get.new(path

  8. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

  9. ruby-on-rails - Rails - 从命名路由中提取 HTTP 动词 - 2

    Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba

  10. ruby-on-rails - Ruby - 如何从 ruby​​ 上的 .pfx 文件中提取公钥、rsa 私钥和 CA key - 2

    我有一个.pfx格式的证书,我需要使用ruby​​提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o

随机推荐