Заполните элементы близко к области изображения

У меня есть черно-белое изображение, в котором некоторые белые элементы касаются границы изображениявведите здесь описание изображения.

Я пытаюсь заполнить эти белые части (на этом изображении только одна часть, но их может быть несколько) черным цветом. Моя единственная идея состоит в том, чтобы перебирать пиксели на границе изображения, и всякий раз, когда я вижу белый пиксель, запускаю алгоритм, который рекурсивно заполняет все белые пиксели окружающих белых пикселей.

Хотя это явно приведет к желаемому результату, я надеюсь, что есть более простой способ добиться этого с помощью numpy/scipy/scikit-image.

При поиске в SO единственным связанным вопросом, который я нашел, был это. Вопрос звучит похоже на то, что я хочу, но на самом деле решает другую проблему. Есть ли надежда найти простое решение для меня?


person Salvador Dali    schedule 03.02.2016    source источник
comment
Концепция contours может довольно легко решить вашу проблему, можете ли вы использовать opencv? потому что я не уверен, есть ли у scipy или numpy API для поиска контуров на данном изображении.   -  person ZdaR    schedule 03.02.2016
comment
@ZdaR Я могу использовать все, что захочу. Дело в том, что я не так хорошо знаком с OpenCV. Но если вы можете дать хорошее объяснение, я был бы очень благодарен.   -  person Salvador Dali    schedule 03.02.2016
comment
Ваше входное изображение также имеет белую рамку вокруг него? Потому что в этом случае сначала вам нужно обрезать изображение, удалив и эту границу?   -  person ZdaR    schedule 03.02.2016
comment
@ZdaR да, иногда бывает (не всегда и не со всех сторон). Если бы я использовал свой рекурсивный подход, это не имело бы никакого значения, но я думаю, что в вашем случае это имеет значение.   -  person Salvador Dali    schedule 03.02.2016
comment
У вас есть информация о ширине границы с каждой стороны?   -  person ZdaR    schedule 03.02.2016
comment
@ZdaR нет, они могут быть разного размера от 0% до 20%   -  person Salvador Dali    schedule 03.02.2016


Ответы (2)


РЕДАКТИРОВАТЬ:

Извините за мое непонимание. Я думаю, вы ищете модуль clear_border.

Clear_border(image) заполняет все белые области, прикрепленные к границе, черным цветом (или другими значениями).

import numpy as np
from skimage import io

from skimage.segmentation import clear_border

image = np.array([[0, 0, 0, 0, 0, 0, 0, 1, 0],
                  [0, 0, 0, 0, 1, 0, 0, 1, 0],
                  [1, 0, 0, 1, 0, 1, 0, 0, 0],
                  [0, 0, 1, 1, 1, 1, 1, 0, 0],
                  [0, 1, 1, 1, 1, 1, 1, 1, 0],
                  [0, 0, 0, 0, 0, 0, 0, 0, 0]])


clear_border(image)

io.imshow(image)
io.show()

Для получения дополнительной информации посетите: http://scikit-image.org/docs/0.11.x/api/skimage.segmentation.html#clear-border

person tfv    schedule 03.02.2016
comment
Извините за непонимание, я добавил информацию о модуле clear_border, который вы, вероятно, ищете. - person tfv; 03.02.2016
comment
Да, да и еще раз да. Это именно то, что мне нужно. Спасибо. - person Salvador Dali; 03.02.2016
comment
Спасибо за второй шанс ;-) - person tfv; 03.02.2016

Дайте scipy.ndimage.label выстрел.

Вот скетч (непроверенный):

labeled_image, _ = scipy.ndimage.label(binarized_image)
for region in np.union1d(labeled_image[[0,-1]].flatten(),
                         labeled_image[:,[0,-1]].flatten()):
    binarized_image[labeled_image == region] = 0

Вышеприведенный код сегментирует изображение на связанные области одного цвета. Каждому из них присваивается целочисленное значение в некотором порядке. labeled_image[[0, -1]] и labeled_image[:, [0, -1]] — это верхняя и нижняя строки, а также левый и правый столбцы изображения соответственно. array.flatten() используется для придания им формы, пригодной для использования union1d, которая в этом контексте вернет все метки областей, соприкасающиеся с границей. Мы перебираем их и окрашиваем все эти области в черный цвет на бинарном изображении.

person castle-bravo    schedule 03.02.2016
comment
Я получил исходное изображение с помощью label. Как это поможет мне узнать, какая из отмеченных областей связана с границей? - person Salvador Dali; 03.02.2016
comment
В моем первоначальном ответе были некоторые синтаксические ошибки. label не должен давать вам исходное изображение, если только изображение не состоит только из двух областей, вместо этого оно должно быть другим целым числом в каждой связанной области. uinion1d и его аргументы дают вам массив, содержащий метки регионов, соединенных с границей. - person castle-bravo; 03.02.2016