使用 GLCM [Python] 减少 运行 纹理分析时间

Reduce running time in Texture analysis using GLCM [Python]

我正在处理 6641x2720 图像以使用移动的 GLCM(灰度共生矩阵)window 生成其特征图像(Haralick 特征,如对比度、二阶矩等)。但是 运行 需要很长时间。 代码工作正常,因为我已经在较小的图像上对其进行了测试。但是,我需要使其 运行 更快。将尺寸缩小到 25% (1661x680) 需要 30 分钟 到 运行。我怎样才能让它 运行 更快?这是代码:

from skimage.feature import greycomatrix, greycoprops
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
import time
start_time = time.time()
img = Image.open('/home/student/python/test50.jpg').convert('L')
y=np.asarray(img, dtype=np.uint8)
#plt.imshow(y, cmap = plt.get_cmap('gray'), vmin = 0, vmax = 255)
contrast = np.zeros((y.shape[0], y.shape[1]), dtype = float)

for i in range(0,y.shape[0]):
    for j in range(0,y.shape[1]):
        if i < 2 or i > (y.shape[0]-3) or j < 2 or j > (y.shape[1]-3):
            continue
        else:
            s = y[(i-2):(i+3), (j-2):(j+3)]
            glcm = greycomatrix(s, [1], [0],  symmetric = True, normed = True )
            contrast[i,j] = greycoprops(glcm, 'contrast')
print("--- %s seconds ---" % (time.time() - start_time))
plt.imshow(contrast, cmap = plt.get_cmap('gray'), vmin = 0, vmax = 255)

填充 GLCM 是一个线性操作:您只需遍历 image/window 上的所有像素,然后填充匹配矩阵的情况。您的问题是您对每个像素执行操作,而不仅仅是图像。因此,在您的情况下,如果图像尺寸为宽度 x 高度并且 window 尺寸为 NxN,则总复杂度为宽度 x 高度 x (NxN + FeaturesComplexity),这非常糟糕。

有一个更快的解决方案,但实施起来更棘手。目标是减少矩阵填充操作。这个想法是逐行使用 Forward Front 和 Backward Front(原理已经用于获得快速的数学形态学运算符,请参阅 here and here)。当你为两个连续的像素填充矩阵时,你复用了大部分像素,实际上只有左边和右边的不同,所以分别是backward front和forward front。

这是尺寸为 3x3 的 GLCM window 的插图:

x1 x2 x3 x4

x5 p1 p2 x6

x7 x8 x9 x10

当 window 以 p1 为中心时,您使用像素:x1、x2、x3、x5、p2、x7、x8、x9。当 window 以 p2 为中心时,您使用像素:x2、x3、4、p1、x6、x8、x9、x10。所以对于p1,你使用x1,x5和x7,但你不使用它们用于p2,但所有其他像素都是相同的。

该算法的思想是正常计算 p1 的矩阵,但是当您移动到 ​​p2 时,您删除了后向前沿 (x1, x2, x5) 并添加了前向前沿 (x4, x6, x10 ).这显着减少了计算时间(数学形态学操作是线性的而不是二次的)。这是算法:

  1. 每一行:
  2. ----- 为行中的第一个像素填充矩阵(通常),然后计算特征
  3. ----- 对于以下每个像素
  4. ----- ----- 添加前锋(window中的新像素)
  5. ----- -----去掉后面的前面(像素不再在window)
  6. ----- ----- 计算特征