отдельные подключенные компоненты к нескольким изображениям - PullRequest
1 голос
/ 17 апреля 2019

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

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

img = imread('shapes.png', IMREAD_GRAYSCALE)
_ , img = threshold(img,120,255,THRESH_BINARY)
n_labals, labels, stats, centroids = connectedComponentsWithStats(img)
for label in range(1,n_labals):
    width = stats[label, CC_STAT_WIDTH]
    height = stats[label, CC_STAT_HEIGHT]
    x = stats[label, CC_STAT_LEFT]
    y = stats[label, CC_STAT_TOP]
    roi = img[y-5:y + height+5, x-5:x + width+5]
    pyplot.imshow(roi,cmap='gray')
    pyplot.show()

Однако, таким образом, у меня есть некоторые пересечения между фигурами, как показано здесь

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


ОБНОВЛЕНИЕ

Я взял прямоугольник с областью интереса, а затем оммотал другие метки

img = imread('shapes.png', IMREAD_GRAYSCALE)
_ , img = threshold(img,120,255,THRESH_BINARY)
n_labals, labels, stats, centroids = connectedComponentsWithStats(img)
for label in range(1,n_labals):
    width = stats[label, CC_STAT_WIDTH]
    height = stats[label, CC_STAT_HEIGHT]
    x = stats[label, CC_STAT_LEFT]
    y = stats[label, CC_STAT_TOP]
    roi = labels[y-1:y + height+1, x-1:x + width+1].copy() # create a copy of the interest region from the labeled image
    roi[ roi != label] = 0  # set the other labels to 0 to eliminate untersections with other labels
    roi[ roi == label] = 255 # set the interest region to white
    pyplot.imshow(roi,cmap='gray')
    pyplot.show()

1 Ответ

1 голос
/ 17 апреля 2019

Из принятого ответа этого поста с подробным описанием функции connectedComponentsWithStats:

Labels - это матрица размера входного изображения, где каждый элемент имеет значение, равное его метке.

Таким образом, это означает, что все пиксели объекта 1 имеют значение 1, все пиксели объекта 2 имеют значение 2 и т. Д.

Моя рекомендация по решению вашей проблемы: regionprops Это реализовано в skimage (отлично подходит для обработки изображений в python)

Вы можете установить его с помощью pipили conda, как подробно здесь

Итак, вызов regionprops для массива целых чисел вернет список генераторов, которые вычисляют практически все основные свойства объекта, которые вы можете пожелать.В частности, к изображениям, которые вы хотите создать, можно получить доступ через 'fill_image':

import numpy as np
from skimage.measure import regionprops

# generate dummy image:
labels = np.zeros((100,100), dtype=np.int) # this does not work on floats
# adding two rectangles, similar to output of your label function
labels[10:20, 10:20] = 1
labels[40:50, 40:60] = 2

props = regionprops(labels)
print(type(props))

Теперь мы можем просмотреть каждый элемент в списке:

for prop in props:
   print(prop['label']) # individual properties can be accessed via square brackets
   cropped_shape = prop['filled_image'] # this gives you the content of the bounding box as an array of bool.
   cropped_shape = 1 * cropped_shape # convert to integer
   # save image with your favourite imsave. Data conversion might be neccessary if you use cv2
...