Нахождение пустых регионов в изображении

Этот вопрос является несколько агностическим языком, но мой предпочтительный инструмент, оказывается, массив numpy.

То, что я делаю, берет различие двух изображений через PIL:

img = ImageChops.difference(img1, img2)

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

Например, рассмотрите следующее где o ненулевой пиксель:

______________________
|o            ooo    |
|      oooo   ooo    |
|      o             |
|      o  o          |
|                    |
|     oo       o     |
|    o  o     ooo    |
|     oo     ooooo   |
|             ooo    |
|              o     |
|____________________|

Я хотел бы получить 4x4-кортежи, содержащие ограничительные рамки для каждого ненулевого региона. Для пограничного случая

oooo
o
o  o

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

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

Моя версия psuedocode-выхода проходит примерно так:

for line in image:
   started = False
   for pixel in line:
      if pixel and not started:
         started = True
         save start coords
      elif started and not pixel:
         started = False
         save end coords (x - 1 of course)

Это должно дать мне список координат, но затем я должен определить, непрерывны ли регионы. Я мог сделать это с поиском типа графика? (Мы сделали много DFS и BFS в Алгоритмах в прошлом семестре), Конечно, я предполагаю, что мог сделать это вместо этого/в сочетании с мои предыдущие циклы?

Я не буду делать этого на "больших" изображениях - их вытягивают от веб-камеры и лучшей, которую я в настоящее время имею, делает 640x480. Самое большее я сделал бы 720 пунктов или 1 080 пунктов, но это достаточно далеко в будущее, что это не реальное беспокойство.

Так мой вопрос (вопросы): я направляюсь на правильном пути или являюсь мной путь прочь? И более важный, там какие-либо встроенные функции, которые препятствуют тому, чтобы я изобрел велосипед? И наконец, там какие-либо хорошие ресурсы, на которые я должен посмотреть (учебные руководства, бумаги, и т.д.), который поможет здесь?

Спасибо!

10
задан Wayne Werner 22 July 2010 в 15:43
поделиться

3 ответа

Я считаю, что модуль ndimage от scipy имеет все, что вам нужно. ..

Вот быстрый пример

import numpy as np
import scipy as sp
import scipy.ndimage.morphology

# The array you gave above
data = np.array( 
        [
           [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], 
        ])


# Fill holes to make sure we get nice clusters
filled = sp.ndimage.morphology.binary_fill_holes(data)

# Now seperate each group of contigous ones into a distinct value
# This will be an array of values from 1 - num_objects, with zeros
# outside of any contigous object
objects, num_objects = sp.ndimage.label(filled)

# Now return a list of slices around each object
#  (This is effectively the tuple that you wanted)
object_slices =  sp.ndimage.find_objects(objects)

# Just to illustrate using the object_slices
for obj_slice in object_slices:
    print data[obj_slice]

Это выводит:

[[1]]
[[1 1 1]
 [1 1 1]]
[[1 1 1 1]
 [1 0 0 0]
 [1 0 0 1]]
[[1]]
[[0 1 1 0]
 [1 0 0 1]
 [0 1 1 0]]
[[0 0 1 0 0]
 [0 1 1 1 0]
 [1 1 1 1 1]
 [0 1 1 1 0]
 [0 0 1 0 0]]

Обратите внимание, что "object_slices" - это в основном то, что вы изначально просили, если вам нужны фактические признаки.

Редактирование: Просто хотел отметить, что несмотря на то, что кажется, что он правильно обрабатывает крайний случай

[[1 1 1 1]
 [1 0 0 0]
 [1 0 0 1]]

, на самом деле это не так (таким образом, лишняя одиночка [[1]]). Вы можете увидеть это, если распечатаете массив "objects" и посмотрите на объекты 3 и 4.

[[1 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 0 0 0 0]
 [0 0 0 0 0 0 3 3 3 3 0 0 0 2 2 2 0 0 0 0]
 [0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 3 0 0 4 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 5 5 0 0 0 0 0 0 0 6 0 0 0 0 0]
 [0 0 0 0 5 5 5 5 0 0 0 0 0 6 6 6 0 0 0 0]
 [0 0 0 0 0 5 5 0 0 0 0 0 6 6 6 6 6 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 6 6 6 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 0 0 0 0 0]]

Надеюсь, это поможет!

[1]

17
ответ дан 3 December 2019 в 20:02
поделиться

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

1
ответ дан 3 December 2019 в 20:02
поделиться

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

1
ответ дан 3 December 2019 в 20:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: