Вы на правильном пути. После получения двоичного изображения вам необходимо выполнить морфологические операции , чтобы отфильтровать шум и изолировать объект. После этого мы можем найти контуры, затем отфильтровать их, используя аппроксимацию контура и площадь контура. Мы рисуем обнаруженную область на пустой маске, затем побитово - и с исходным изображением. Вот шаги:
Двоичное изображение
Морфологические операции
Обнаруженная область зеленого цвета
Изолированный результат после побитовых операций
Код
import numpy as np
import cv2
# Color threshold
image = cv2.imread('1.jpg')
original = image.copy()
blank = np.zeros(image.shape, dtype=np.uint8)
blur = cv2.GaussianBlur(image, (7,7), 0)
hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 0])
upper = np.array([179, 93, 97])
mask = cv2.inRange(hsv, lower, upper)
# Morph operations
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7,7))
opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel, iterations=1)
close = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel, iterations=2)
# Find contours and filter using contour approximation + contour area
cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.04 * peri, True)
area = cv2.contourArea(c)
if len(approx) > 3 and area > 1000:
cv2.drawContours(image, [c], -1, (36,255,12), -1)
cv2.drawContours(blank, [c], -1, (255,255,255), -1)
# Bitwise-and for result
blank = cv2.cvtColor(blank, cv2.COLOR_BGR2GRAY)
result = cv2.bitwise_and(original,original,mask=blank)
result[blank==0] = (255,255,255)
cv2.imshow('mask', mask)
cv2.imshow('opening', opening)
cv2.imshow('close', close)
cv2.imshow('result', result)
cv2.imshow('image', image)
cv2.waitKey()