针对一张20*20的图像块,编程计算该图像块的灰度共生矩阵(d=1,θ=0°),
并将原始图像块和共生矩阵的数值显示出来。
首先查看一下计算原理:
乍一看我还以为需要四个参数计算。
看一下百科:
这样看是很清楚的,指定了a和b实际上就是指定了方向和距离。
比如 PPT里的例子,0° 1就是a=1,b=0,135° 1就是a=-1,b=-1
代码如下:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
class ComatrixCaler(object):
def __init__(self,mat,a=1,b=0) -> None:
self.mat = mat
self.a = a
self.b = b
self.countMatrix = None
self.probaMatrix = None
self.l = None
self.calComatrix()
@staticmethod
def getRange(a,b,r,c):
opa,opb = int(a/abs(a)) if a!=0 else 1,int(b/abs(b)) if b!=0 else 1
lb_r = 0 if opb>=0 else r-1
rb_r = r-b if opb>=0 else 0+b+1
lb_c = 0 if opa>=0 else c-1
rb_c = c-a if opa>=0 else 0+a+1
return range(lb_r,rb_r,opb),range(lb_c,rb_c,opa)
def calComatrix(self):
self.l = list(set(self.mat.flatten().tolist()))
self.l.sort()
counts = self.l.__len__()
m = {k:v for k,v in zip(self.l,range(counts))}
countMat = np.zeros([counts,counts])
r,c = self.mat.shape
borders = self.getRange(self.a,self.b,r,c)
for i in borders[0]:
for j in borders[1]:
countMat[m[self.mat[i,j]],m[self.mat[i+self.b,j+self.a]]]+=1
countMat[m[self.mat[r-i-1,c-j-1]],m[self.mat[r-1-i-self.b,c-1-j-self.a]]]+=1
self.countMatrix = countMat.astype('uint8')
self.probaMatrix = countMat/self.countMatrix.sum()
def setargs(self,a,b):
self.a = a
self.b = b
self.calComatrix()
egm = np.array([[0,0,1,1],[0,0,1,1],[0,2,2,2],[2,2,3,3]])
# 这里复现了一下PPT里的例子
eg = ComatrixCaler(egm)
print(eg.countMatrix,eg.probaMatrix)
eg.setargs(-1,-1)
print(eg.countMatrix,eg.probaMatrix)
理论上灰度共生矩阵应该是概率分布矩阵,这里的countMatrix
是计数矩阵,probaMatrix
是概率矩阵
显然的是,灰度共生矩阵的大小取决于图像中灰度值的种类,所以建议orange = orange - np.mod(orange,25)
来减少灰度值种类,共生矩阵图像也更明显
我自己的例子:
orange = cv.imread('./pics/orange.jpg',flags=cv.IMREAD_GRAYSCALE).astype(np.uint8)
orange = orange - np.mod(orange,25)
# orange = cv.resize(orange,(20,20))
print(list(set(orange.flatten().tolist())).__len__())
orange_com = ComatrixCaler(orange)
orange_float_gray = orange_com.probaMatrix
fig,axs = plt.subplots(1,3)
axs[0].imshow(orange,cmap='gray')
axs[1].imshow(orange_float_gray,cmap='gray')
axs[2].imshow(orange_com.countMatrix,cmap='gray')
效果: