co masz jest prawie poprawne. Jeśli przyjrzeć się obrazowi z progiem, przyczyną jego braku jest fakt, że obiekt butów ma luki na obrazie. W szczególności chodzi o to, że spodziewasz się, że but ma obwód, który ma być połączony wszystkie. Jeśli tak się stanie, to jeśli wyodrębnisz najbardziej zewnętrzny kontur (co robi twój kod), powinieneś mieć tylko jeden kontur, który reprezentuje zewnętrzny obwód obiektu. Po wypełnieniu konturu but powinien być całkowicie solidny.
Ponieważ obwód buta nie jest kompletny i zepsuty, powoduje to rozłączenie białych obszarów. Jeśli użyjesz findContours
, aby znaleźć wszystkie kontury, będzie on znajdował tylko kontury każdego z białych kształtów, a nie najbardziej zewnętrznego obwodu. W związku z tym, jeśli spróbujesz użyć wartości findContours
, uzyskasz taki sam efekt, jak oryginalny obraz, ponieważ po prostu znajdujesz obwód każdego białego obszaru wewnątrz obrazu, a następnie wypełniasz te obszary wartością findContours
.
Co trzeba zrobić, to upewnić się, że obraz jest całkowicie zamknięte. Polecam, aby użyć morphology, aby zamknąć wszystkie rozłączone regiony razem, a następnie uruchomić wywołanie findContours
na tym nowym obrazie. W szczególności wykonaj binarne zamknięcie morfologiczne. To, co to robi, polega na tym, że pobiera rozłączone białe obszary, które są blisko siebie i zapewnia, że są połączone. Użyj morfologicznego zamknięcia i być może użyj czegoś podobnego do kwadratowego elementu struktury 7 x 7, aby zamknąć but. Ten element strukturyzacji można uznać za minimalny podział między białymi regionami, aby uznać je za połączone.
Jako takie coś jak to zrobić:
import numpy as np
import cv2
image = cv2.imread('...') # Load your image in here
# Your code to threshold
image = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 45, 0)
# Perform morphology
se = np.ones((7,7), dtype='uint8')
image_close = cv2.morphologyEx(image, cv2.MORPH_CLOSE, se)
# Your code now applied to the closed image
cnt = cv2.findContours(image_close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
mask = np.zeros(image.shape[:2], np.uint8)
cv2.drawContours(mask, cnt, -1, 255, -1)
Ten kod zasadniczo bierze swój progowaniu obrazu morfologicznego i dotyczy zamknięcia do tego obrazu. Następnie odnajdujemy zewnętrzne kontury tego obrazu i wypełniamy je białym kolorem. FWIW, pobrałem twój obraz z progiem i spróbowałem tego na własną rękę. To co mam z obrazka:
To jest niesamowite, nie mogę uwierzyć, że to działa! Pewnego popołudnia udało mi się zamazać tło obrazu. Opencv jest całkiem fajny. – emschorsch
@emschorsch - dzięki za awans :) Tak, OpenCV to niesamowita platforma. Używam go codziennie do pracy. Baw się dobrze! – rayryeng
@rayryeng Próbowałem tego kodu, ale w ostatnim wierszu zgłasza następujący błąd 'drawing.cpp: 2380: error: (-215) npoints> 0 w funkcji cv :: drawContours' - Używam OpenCV 3.1 i Python 2.7 . Jakieś pomysły? – g491