Параметр уровней в greycomatrix scikit-image python

Я перемещаю свои алгоритмы обработки изображений Matlab на Python с помощью инструментов scikit-image и вычисляю матрицу совместной встречаемости уровней серого (GLCM), используя greycomatrix. У меня проблема, если параметр 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 или я не так думаю? Заранее спасибо.


person rpezoa    schedule 22.07.2014    source источник
comment
Я думаю, единственная причина в том, что раньше об этом никто не просил. Есть три варианта: 1) обсудить это в списке рассылки scikit-image 2) сообщить о проблеме с scikit-image на GitHub или 3) отправить запрос на перенос, который устраняет проблему.   -  person Stefan van der Walt    schedule 22.07.2014
comment
Хорошо, спасибо за ваши предложения!   -  person rpezoa    schedule 23.07.2014


Ответы (1)


Возможно, я опаздываю на вечеринку, но, надеюсь, мой ответ может быть полезен кому-то еще в будущем ...

Согласно документации Matlab 'NumLevels' может быть меньше max(image(:)), поскольку значения оттенков серого обрезано:

Значения шкалы серого, меньшие или равные low, масштабируются до 1. Значения шкалы серого больше или равные high масштабируются до 'NumLevels'.

Вы можете использовать тот же обходной путь в Python через _3 _ :

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)

Если вы хотите уменьшить размер матрицы совпадения уровней серого, я бы порекомендовал повторно проанализировать изображение, а не обрезать значения оттенков серого. Этот подход можно легко реализовать с помощью 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)
person Tonechas    schedule 18.05.2017