# -*- coding: UTF-8 -*- """ @Project :onestar @File :GLDM.py @Contact: scikit-image feature计算图像特征:https://blog.csdn.net/lyxleft/article/details/102904909 python如何在二维图像上进行卷积:https://www.xz577.com/j/281686.html 利用python的skimage计算灰度共生矩阵:https://zhuanlan.zhihu.com/p/147066037 @function :计算图像灰度共生矩阵 @Author :SHJ @Date :2021/11/10 14:42 @Version :1.0.0 """ import numpy as np import os from skimage.feature import greycomatrix, greycoprops import datetime from tool.algorithm.image.ImageHandle import ImageHandler class GLDM: def __init__(self,win_size = 15, step=2,levels=16,angles=[0,45,90,135], prop=['contrast', 'dissimilarity', 'homogeneity', 'energy', 'correlation', 'ASM']): self._win_size = win_size # 计算灰度共生矩阵窗口尺寸,为奇数 self._step = step # 步长 self._levels = levels # 灰度等级:例如16,256 self._angles = list(np.deg2rad(np.array(angles))) #角度,使用弧度制 """ 'contrast':对比度:反映了图像的清晰度和纹理沟纹深浅的程度 'dissimilarity':差异性 'homogeneity':同质性/逆差距:度量图像纹理局部变化的多少。其值大则说明图像纹理的不同区域间缺少变化,局部非常均匀。 'energy':能量:是灰度共生矩阵元素值的平方和,所以也称能量,反映了图像灰度分布均匀程度和纹理粗细度 'correlation':相关性:它度量空间灰度共生矩阵元素在行或列方向上的相似程度 'ASM':二阶距 """ self._prop = prop #纹理特征名称 def get_glcm_value(self,input): values_temp = [] # 统计得到glcm # 得到共生矩阵,参数:图像矩阵,距离,方向,灰度级别,是否对称,是否标准化 # para2: [0, np.pi / 4, np.pi / 2, np.pi * 3 / 4] 一共计算了四个方向,你也可以选择一个方向 glcm = greycomatrix(input, [self._step], self._angles, self._levels, symmetric=False, normed=True) # print(glcm.shape) # 循环计算表征纹理的参数 for prop in self._prop: temp = greycoprops(glcm, prop) # print(temp) values_temp.append(np.mean(temp)) return values_temp def get_glcm_array(self,inputs: np.ndarray, win_size): h, w = inputs.shape pad = (win_size - 1) // 2 inputs = np.pad(inputs, pad_width=[(pad, pad), (pad, pad)], mode="constant", constant_values=0) glcm_array ={} for name in self._prop: glcm_array.update({name:np.zeros(shape=(h, w),dtype=np.float32)}) for i in range(h): # 行号 for j in range(w): # 列号 window = inputs[i: i + win_size, j: j + win_size] value = self.get_glcm_value(window) print('i:%s,j:%s',i,j) # print(value) for n,array in zip(range(len(glcm_array)),glcm_array.values()): array[i,j] = value[n] return glcm_array @staticmethod def standardization(data, num=1): # 矩阵标准化到[0,1] data[np.isnan(data)] = np.min(data) # 异常值填充为0 _range = np.max(data) - np.min(data) return (data - np.min(data)) / _range * num def api_get_glcm_array(self,out_dir,in_tif_path,name=''): ih = ImageHandler() proj, geotrans, array = ih.read_img(in_tif_path) array[np.where(array > 500000)]=500000 #去除过大的值,避免标准化时,大部分的值都接近0 array = self.standardization(array,self._levels-1) #标准化到0~(self._levels-1) array = np.uint8(array) glcm_array = self.get_glcm_array(array, self._win_size) for key,value in glcm_array.items(): out_path = os.path.join(out_dir,name+'_'+key+'.tif') ih.write_img(out_path, proj, geotrans,value) if __name__ == '__main__': start = datetime.datetime.now() gldm = GLDM(win_size=9,levels=16,step=3,angles=[0,45,90,135]) gldm.api_get_glcm_array('D:\glcm','D:\glcm\src_img.tif',) end = datetime.datetime.now() msg = 'running use time: %s ' % (end - start) print(msg) # 666*720尺寸影像消耗的running use time: 0:04:23.155424