Параметр уровней в Python Greycomatrix Scikit-изображения
Я перевожу свои алгоритмы обработки изображений Matlab на Python, используя инструменты scikit-image, и вычисляю матрицу совпадений уровней серого ( GLCM) с использованием серой матрицы. У меня проблема, если параметр levels
меньше максимального значения интенсивности изображения (image.max()
). Например:
import numpy as np
from skimage.feature import greycomatrix
image = np.array([[0, 0, 1, 1],[0, 0, 1, 1],[0, 2, 2, 2],[2, 2, 3, 3]], dtype=np.uint8)
result = greycomatrix(image, distances = [1], angles = [0], levels = 4, symmetric=True)
Выход:
glcm = result[:,:,0,0]
array([[4, 2, 1, 0],
[2, 4, 0, 0],
[1, 0, 6, 1],
[0, 0, 1, 2]], dtype=uint32)
что правильно, матрица 4х4. Но если levels=3
Я не могу рассчитать GLCM, и ошибка:
result = greycomatrix(image, distances = [1], angles = [0], levels = 3, symmetric=True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.4/site-packages/skimage/feature/texture.py", line 97, in greycomatrix
assert image.max() < levels
AssertionError
И конечно... Я получаю ошибку, но я должен быть в состоянии рассчитать GLCM (матрица 3x3) с уровнями меньше, чем image.max()
, Например, для:
result = greycomatrix(image, distances = [1], angles = [0], levels = 3, symmetric=True)
Я должен получить следующий GLCM (я могу сделать это в Matlab):
4 3 0
3 10 1
0 1 2
Когда я работаю с огромными изображениями, я уменьшаю уровни GLCM, чтобы сократить время вычислений. Есть ли проблемы с greycomatrix
или я ошибаюсь? Заранее спасибо.
1 ответ
Возможно, я опаздываю на вечеринку, но, надеюсь, мой ответ может пригодиться кому-то еще в будущем...
Согласно документации Matlab 'NumLevels'
может быть меньше чем max(image(:))
потому что значения в градациях серого обрезаются:
Значения градаций серого, меньшие или равные низкому, масштабируются до 1. Значения серого, превышающие или равные максимальному, масштабируются до "NumLevels".
Вы можете использовать тот же обходной путь в Python через NumPy's clip
:
In [11]: import numpy as np
In [12]: from skimage.feature import greycomatrix
In [13]: image = np.array([[0, 0, 1, 1],
...: [0, 0, 1, 1],
...: [0, 2, 2, 2],
...: [2, 2, 3, 3]], dtype=np.uint8)
...:
In [14]: clipped = np.clip(image, a_min=0, a_max=2)
In [15]: clipped
Out[15]:
array([[0, 0, 1, 1],
[0, 0, 1, 1],
[0, 2, 2, 2],
[2, 2, 2, 2]], dtype=uint8)
In [16]: result = greycomatrix(clipped,
...: distances=[1],
...: angles=[0],
...: levels=3,
...: symmetric=True)
...:
In [17]: result[:, :, 0, 0]
Out[17]:
array([[ 4, 2, 1],
[ 2, 4, 0],
[ 1, 0, 10]], dtype=uint32)
Если вы хотите уменьшить размер матрицы сопутствующих явлений уровня серого, я бы порекомендовал сделать рекантирование изображения, а не обрезать значения в градациях серого. Этот подход может быть легко реализован с помощью NumPy digitize
:
In [59]: nlevels = 256
In [60]: nbins = 64
In [61]: arr = np.arange(nlevels).reshape((16, 16)).astype(np.uint8).T
In [62]: np.set_printoptions(threshold=300, linewidth=100)
In [63]: arr
Out[63]:
array([[ 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240],
[ 1, 17, 33, 49, 65, 81, 97, 113, 129, 145, 161, 177, 193, 209, 225, 241],
[ 2, 18, 34, 50, 66, 82, 98, 114, 130, 146, 162, 178, 194, 210, 226, 242],
[ 3, 19, 35, 51, 67, 83, 99, 115, 131, 147, 163, 179, 195, 211, 227, 243],
[ 4, 20, 36, 52, 68, 84, 100, 116, 132, 148, 164, 180, 196, 212, 228, 244],
[ 5, 21, 37, 53, 69, 85, 101, 117, 133, 149, 165, 181, 197, 213, 229, 245],
[ 6, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166, 182, 198, 214, 230, 246],
[ 7, 23, 39, 55, 71, 87, 103, 119, 135, 151, 167, 183, 199, 215, 231, 247],
[ 8, 24, 40, 56, 72, 88, 104, 120, 136, 152, 168, 184, 200, 216, 232, 248],
[ 9, 25, 41, 57, 73, 89, 105, 121, 137, 153, 169, 185, 201, 217, 233, 249],
[ 10, 26, 42, 58, 74, 90, 106, 122, 138, 154, 170, 186, 202, 218, 234, 250],
[ 11, 27, 43, 59, 75, 91, 107, 123, 139, 155, 171, 187, 203, 219, 235, 251],
[ 12, 28, 44, 60, 76, 92, 108, 124, 140, 156, 172, 188, 204, 220, 236, 252],
[ 13, 29, 45, 61, 77, 93, 109, 125, 141, 157, 173, 189, 205, 221, 237, 253],
[ 14, 30, 46, 62, 78, 94, 110, 126, 142, 158, 174, 190, 206, 222, 238, 254],
[ 15, 31, 47, 63, 79, 95, 111, 127, 143, 159, 175, 191, 207, 223, 239, 255]], dtype=uint8)
In [64]: binned = np.uint8(np.digitize(arr, np.arange(0, nlevels, nbins))) - 1
In [65]: binned
Out[65]:
array([[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]], dtype=uint8)
In [66]: glcm = greycomatrix(binned,
...: distances=[1],
...: angles=[0],
...: levels=binned.max()+1,
...: symmetric=True)
...:
In [67]: glcm[:, :, 0, 0]
Out[67]:
array([[96, 16, 0, 0],
[16, 96, 16, 0],
[ 0, 16, 96, 16],
[ 0, 0, 16, 96]], dtype=uint32)