В вашем коде есть ошибка. Вам нужно изменить инициализацию матрицы вхождения уровня серого на glcm = np.zeros((256, 256), dtype=int)
, в противном случае, если обрабатываемое изображение содержит несколько пикселей с уровнем интенсивности 255
, функция getGLCM
выдаст ошибку.
Вот чистая реализация NumPy, которая повышает производительность за счет векторизации:
def vectorized_glcm(image, distance, direction):
img = np.array(image)
glcm = np.zeros((256, 256), dtype=int)
if direction == 1:
first = img[distance:, :]
second = img[:-distance, :]
elif direction == 2:
first = img[distance:, :-distance]
second = img[:-distance, distance:]
elif direction == 3:
first = img[:, :-distance]
second = img[:, distance:]
elif direction == 4:
first = img[:-distance, :-distance]
second = img[distance:, distance:]
for i, j in zip(first.ravel(), second.ravel()):
glcm[i, j] += 1
return glcm
Если вы открыты для использования других пакетов, я настоятельно рекомендую вам использовать greycomatrix scikit-image. Как показано ниже, это ускоряет вычисления на два порядка.
Демо
In [93]: from skimage import data
In [94]: from skimage.feature import greycomatrix
In [95]: img = data.camera()
In [96]: a = getGLCM(img, 1, 1)
In [97]: b = vectorized_glcm(img, 1, 1)
In [98]: c = greycomatrix(img, distances=[1], angles=[-np.pi/2], levels=256)
In [99]: np.array_equal(a, b)
Out[99]: True
In [100]: np.array_equal(a, c[:, :, 0, 0])
Out[100]: True
In [101]: %timeit getGLCM(img, 1, 1)
240 ms ± 1.16 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [102]: %timeit vectorized_glcm(img, 1, 1)
203 ms ± 3.11 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [103]: %timeit greycomatrix(img, distances=[1], angles=[-np.pi/2], levels=256)
1.46 ms ± 15.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)