Нарезка изображения с помощью findContours (cv2)

Я не могу опубликовать изображение из-за репутации, поэтому вот ссылка на изображение, которое я скачал:

https://www.amvplaygrounds.co.uk/pub/media/catalog/product/a/m/amv_f4-pm-017-shapes-circle-square-rectangle-star-triangle-200mm-2-sq-3d.jpg

import cv2
import numpy as np
import matplotlib.pyplot as plt 
image = cv2.imread(r'C:\Users\User\Desktop\shapes.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 200, 255, 0)
contours, hier = cv2.findContours(thresh, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
    x,y,w,h = cv2.boundingRect(cnt)
    shape = thresh[y:y+h,x:x+w]
    plt.imshow(shape)

Он возвращает только один контур вместо 6, как вы можете видеть на картинке.

Что я делаю неправильно ?


person J.Doe    schedule 25.01.2019    source источник
comment
Я всегда с подозрением отношусь к тому, что люди публикуют JPEG, но их код открывает PNG ...   -  person Mark Setchell    schedule 25.01.2019
comment
... и на их изображении есть 6 объектов, но они ожидают найти только 5   -  person Mark Setchell    schedule 25.01.2019
comment
Попробуйте использовать cv2.drawContours   -  person Nuzhny    schedule 25.01.2019
comment
Я сохранил его как png, потому что по какой-то причине у меня проблемы с чтением файлов jpeg, как вы могли видеть в моем предыдущем посте.   -  person J.Doe    schedule 25.01.2019
comment
порог 200 может быть немного высоким: попробуйте уменьшить его или начать со 127. еще лучше, сделайте другую матрицу только для отладки, используйте цикл while, чтобы получить копию исходного изображения и примените порог, играя со значением (достаточно просто, чтобы добавить ползунок). как предлагает Нужный, для отладки тоже используйте drawContours.   -  person George Profenza    schedule 25.01.2019
comment
Ну, по какой-то причине, когда я делаю цикл, чтобы показать изображение в jupyter, отображается только последнее изображение ... В любом случае спасибо за помощь   -  person J.Doe    schedule 25.01.2019


Ответы (1)


findContours() ищет белые объекты на черном фоне, поэтому вам необходимо установить порог следующим образом:

ret, thresh = cv2.threshold(gray, 225, 255, cv2.THRESH_BINARY_INV)  

и вам нужно найти такие контуры:

im2, contours, hier = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 
person Mark Setchell    schedule 25.01.2019