Вычисление матрицы совпадения части изображения по маске

У меня есть следующий код, в котором я пытаюсь получить часть изображения, соответствующую маске, которую мне дали. Затем я хотел бы применить к этой части skimage.feature.glcm. Но я получаю сообщение об ошибке:

glcm = greycomatrix(mancha, [2], [0], levels=None, symmetric = True, normed = True)
File "D:\WinPython-64bit-2.7.13.1ZeroNew\python-2.7.13.amd64\lib\site-packages\skimage\feature\texture.py", line 101, in greycomatrix
assert_nD(image, 2)
File "D:\WinPython-64bit-2.7.13.1ZeroNew\python-2.7.13.amd64\lib\site-packages\skimage\_shared\utils.py", line 178, in assert_nD
raise ValueError(msg_incorrect_dim % (arg_name, '-or-'.join([str(n) for n in ndim])))
ValueError: The parameter `image` must be a 2-dimensional array

Код:

mask = cv2.imread(pathMask, 0)
cruda = cv2.imread(pathCruda, 0)
imaskc = mask > 0
mancha = cruda[imaskc]

glcm = greycomatrix(mancha, [2], [0], levels=None, symmetric = True, normed = True)
energy = greycoprops(glcm, 'energy')
homogeneity = greycoprops(glcm, 'homogeneity')

Я также безуспешно пытался:

labeled_image, nb_labels = ndimage.label(mascara)
blobs = ndimage.find_objects(labeled_image)

glcm = greycomatrix(cruda[blobs[0]]

Любые идеи, как это сделать?

Спасибо!


person Adrián Arroyo Perez    schedule 01.12.2017    source источник
comment
Индексирование массива numpy с маской возвращает линейный массив. Хотя это и не удивительно, если подумать. Если a = [[1, 2], [3, 4]], а у вас маска b = [[1, 0], [1, 1]], то результат a[b] = [1, 3, 4]. Так что это не двумерный массив. Он не может вернуть 2D-массив, если в каждой строке есть разное количество замаскированных элементов, поэтому он никогда этого не делает. Однако, если вы просто хотите сделать все за пределами маски черным, вы можете легко сделать это с помощью cruda[~imaskc] = 0.   -  person alkasm    schedule 01.12.2017
comment
Спасибо за ответ, но я хотел бы получить часть изображения, чтобы передать ее функции glcm.   -  person Adrián Arroyo Perez    schedule 01.12.2017
comment
Подумайте, чего вы на самом деле хотите здесь. Посмотрите на мой пример выше, где 1 — это True, а 0 — это False. Как должно выглядеть возвращение a[b] в этом примере?   -  person alkasm    schedule 02.12.2017
comment
Извините, я действительно не понимаю, что вы имеете в виду. Вы только что сказали, что возврат a[b] = [1,2,3]   -  person Adrián Arroyo Perez    schedule 04.12.2017
comment
Точно... и сколько измерений у этого массива? Только один. glcm требует двумерного ввода. Индексация с маской просто дает все элементы, соответствующие маске, линейно. Другими словами: если a = np.array([[1, 2], [3, 4]]) и b = np.array([[1, 0], [1, 1]]), то a[b] = np.array([1, 3, 4]), но то, что вы, вероятно, хотите, это a[~b] = 0, таким образом, a = np.array([[1, 0], [3, 4]]), который является двумерным.   -  person alkasm    schedule 04.12.2017
comment
Если вы просто хотите получить интересующую область, указанную маской, найдите минимальный и максимальный индексы строк и столбцов белых частей маски и проиндексируйте свой массив cruda[min_row:max_row, min_col:max_col]. Но вам все равно нужно заранее замаскировать, если вы хотите, чтобы значения были удалены.   -  person alkasm    schedule 04.12.2017
comment
Итак, если я просто сделаю cruda[~mask]=0, а затем greycomatrix(cruda,...), это сработает, вы это имеете в виду? Или результат не будет таким, как хотелось бы, поскольку изображение cruda черное везде, кроме области внутри маски? Или я должен передать cruda[mask==255] после применения cruda[~mask]=0??   -  person Adrián Arroyo Perez    schedule 04.12.2017
comment
cruda[~mask]=0 установит черный цвет везде, кроме замаскированной области --- это правильно. Опять же, вы не можете передать cruda[mask==255] в функцию, так как эта маскированная индексация всегда возвращает линейный массив и никогда не возвращает двумерный массив. Я даже не знаю, что такое glcm, поэтому я не знаю, каков правильный вывод. Я просто указываю разные способы маскировать или индексировать изображение, чтобы получить то, что вы хотите.   -  person alkasm    schedule 04.12.2017
comment
как насчет второй части кода? blobs[0] должен быть срезом, будет ли он работать как индекс, возвращающий 2D-элементы?   -  person Adrián Arroyo Perez    schedule 04.12.2017
comment
Это дает минимальное и максимальное расположение маски, как я упоминал ранее. Так что да, это сработает. Он создает интересующую область вокруг значений маски. Обратите внимание, что вы также можете выполнить np.where() и найти минимальные/максимальные значения x, y, полученные таким же образом. Но обратите внимание, опять же — это даст вам только подмножество вашего изображения в виде прямоугольника, а не в форме маски, поскольку это невозможно сделать.   -  person alkasm    schedule 04.12.2017
comment
Взгляните на этот ответ для решения вашей проблемы на основе mahotas   -  person Tonechas    schedule 04.12.2017


Ответы (1)


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

Основная идея состоит в сохранении уровня серого, скажем, 0, чтобы отметить те пиксели изображения, которые выходят за пределы интересующей области (ROI). Чтобы этот подход работал должным образом, вам необходимо изменить интенсивность тех пикселей внутри ROI, исходная интенсивность которых была 0, на другое (но похожее) значение, например 1. Обратите внимание, что изменение изображения таким образом неизбежно вносит неточности в матрицу совпадений, но пока ваше изображение достаточно велико и имеет гладкую гистограмму, вы можете с уверенностью предположить, что полученные признаки являются довольно хорошим приближением к точным значениям. . Также важно отметить, что вы должны избавиться от 0th строки и 0th столбца матрицы совпадений, чтобы не учитывать уровень серого, используемый для пометки пикселей, не относящихся к области интереса.

Чтобы реализовать описанный выше обходной путь, вам просто нужно изменить следующие две строки:

mancha = cruda[imaskc]
glcm = greycomatrix(mancha, [2], [0], levels=None, symmetric=True, normed=True)

to:

mancha = cruda.copy()
mancha[mancha == 0] = 1
mancha[~imaskc] = 0
glcm = greycomatrix(mancha, [2], [0], levels=None, symmetric=True, normed=True)[1:, 1:, :, :]
person Tonechas    schedule 07.02.2018