97 lines
4.3 KiB
Python
97 lines
4.3 KiB
Python
# -*- 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 |