Маркировка подключенных компонентов в python

Как реализовать маркировку связанных компонентов в python с открытым cv? Это пример изображения:

Мне нужна маркировка подключенных компонентов для разделения объектов на черно-белом изображении.

1 ответ

Решение

OpenCV connectedComponents() документы не упоминают Python, но на самом деле он реализован. Посмотрите, например, на этот ТАК вопрос.

Вызов функции прост: retval, labels = cv2.connectedComponents(img) и вы можете указать параметр connectivity проверить 4- или 8-стороннее (по умолчанию) подключение. Разница заключается в том, что 4-стороннее соединение просто проверяет верхний, нижний, левый и правый пиксели и определяет, соединяются ли они; 8-сторонняя проверка, подключается ли какой-либо из восьми соседних пикселей. Если у вас есть диагональные связи (как у вас здесь), вы должны указать connectivity=8, Обратите внимание, что он просто нумерует каждый компонент и дает им увеличивающиеся целочисленные метки, начиная с 0. Таким образом, все нули связаны, все они связаны и т. Д. Если вы хотите визуализировать их, вы можете сопоставить эти числа с определенными цветами. Мне нравится отображать их в разные оттенки, объединять их в изображение HSV, а затем преобразовывать в BGR для отображения. Вот пример с вашим изображением:

import cv2
import numpy as np

img = cv2.imread('eGaIy.jpg', 0)
img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)[1]  # ensure binary
ret, labels = cv2.connectedComponents(img)

# Map component labels to hue val
label_hue = np.uint8(179*labels/np.max(labels))
blank_ch = 255*np.ones_like(label_hue)
labeled_img = cv2.merge([label_hue, blank_ch, blank_ch])

# cvt to BGR for display
labeled_img = cv2.cvtColor(labeled_img, cv2.COLOR_HSV2BGR)

# set bg label to black
labeled_img[label_hue==0] = 0

cv2.imshow('labeled.png', labeled_img)
cv2.waitKey()

Помеченное изображение

Моя адаптация CCL в 2D:

1) Преобразуйте изображение в изображение 1/0, где 1 - пиксели объекта, а 0 - пиксели фона.

2) Сделайте двухпроходный алгоритм CCL, реализовав алгоритм Union-Find с проходным сжатием. Вы можете увидеть больше здесь.

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

2) На втором проходе вы просматриваете все пиксели и меняете их предыдущую метку на метку родительской метки, просто просматривая эквивалентную таблицу, хранящуюся в вашем классе Union-Find.

3) Я реализовал дополнительный проход, чтобы метки следовали в последовательном порядке (1,2,3,4....) вместо случайного (23,45,1,...). Это включает изменение ярлыка "имя" только в эстетических целях.

Другие вопросы по тегам