我试图基于从GLCM中提取的特征建立一个图像分类模型.我想对一些图像进行遮挡以改进模型,当然还有 我不想让GLCM把这些像素考虑进去。基于以下几点 岗位 我已经实施并开展了 测试以确保GLCM对蒙版图像的正确工作。:
1) 取一张图像并创建一个裁剪版和一个蒙版(与裁剪的像素相同)。
2) 将图像转换为int32类型,并做了如下操作。
#adding 1 to all pixels and setting masked pixels as zero.
mask_img+=1
crop_img+=1
mask_img[:,:,2][:,int(img.shape[1]/2):int(img.shape[1])] = 0
glcm_crop = greycomatrix(crop_img[:,:,2],
levels=257,
distances=1,
angles=0,
symmetric=True,
normed=True)
glcm_masked = greycomatrix(mask_img[:,:,2],
levels=257,
distances=1,
angles=0,
symmetric=True,
normed=True)
#discarding the first row and column that represent zero value pixels
glcm_masked =glcm_masked[1:, 1:, :, :]
glcm_crop = glcm_crop[1:, 1:, :, :]
所以在这个测试中, 如果GLCM不受蒙版像素的影响, 我希望蒙版和裁剪版图像的矩阵是一样的. 但实际上矩阵是不同的.
我对GLCM工作原理的理解是否正确?理论上这两个矩阵应该是相等的吗?
我们来慢慢看一下代码。首先我们导入必要的模块,加载一张类型为 np.int32
并将图像中所有像素的像素强度提高了 1
:
import numpy as np
from skimage import data
from skimage.feature import greycomatrix
img = data.astronaut().astype(np.int32) + 1
然后我们定义图像的形状和强度等级的数量。
rows, cols, _ = img.shape
levels = 256
现在我们对图像的蓝色通道进行裁剪,只保留左半部分。
crop_img = img[:, :cols//2, 2]
图像蓝色通道的右半部分就像这样被遮挡住了
mask_img = img[:, :, 2].copy()
mask_img[:, cols//2:] = 0
在这个例子中,我们可以很方便地将GLCM计算包起来。
def glcm_wrapper(arr):
glcm = greycomatrix(arr, levels=levels+1, distances=[1], angles=[0])
return np.squeeze(glcm)[1:, 1:]
我们已经准备好检查两种方法得到的GLCM是否相同。
glcm_crop = glcm_wrapper(crop_img)
glcm_mask = glcm_wrapper(mask_img)
print(np.array_equal(glcm_crop, glcm_mask))
如果你运行上面所有的代码,你会得到: True
.
需要注意的是,如果你把参数 normed=True
到 greycomatrix
,结果的GLCMs是不同的。如果你想让矩阵归一化,你就必须 去掉第一行和第一列后,对GLCMs进行标准化处理。. 试试这个来说服自己。
glcm_crop = glcm_crop/glcm_crop.sum()
glcm_mask = glcm_mask/glcm_mask.sum()
print(np.allclose(glcm_crop, glcm_mask))