Всякий раз, когда у вас есть куча сложных цветов на изображении, всегда преобразуйте его в другое цветовое пространство, прежде чем пытаться сегментировать интересующий вас объект.
В приведенном примере я преобразовал изображение в различные цветовые пространства, такие как HSV, LAB и YCrCb (для получения дополнительной информации обратитесь к Google. Оттенок канала в изображении HSV оказался заметным для сегментации.
Вот мой результат:
псевдокод:
- Получено пороговое изображение оттенка канала изображения
- Выполнено расширение на инвертированном изображении канала оттенка.
- Нашел контур с наибольшим охватом области и отметил его
EDIT
Вот код:
import cv2
path = 'C:/Users/Desktop/'
img = cv2.imread(path + 'car.jpg')
img = cv2.resize(img, (0,0), fx=0.25, fy=0.25) #-- image was too big hence I had to resize it
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #-- HSV conversion
h, s, v = cv2.split(hsv)
cv2.imshow('hsv Image', hsv)
cv2.imshow('h Image', h)
cv2.imshow('s Image', s)
cv2.imshow('v Image', v)
Я также пробовал с цветовым пространством LAB и YCrCb, но канал оттенка HSV, казалось, выглядел лучше, поэтому я застрял с ним.
ret, thresh = cv2.threshold(s, 87, 255, cv2.THRESH_BINARY) #-- I had to check which threshold would be the optimum one to best separate the car
cv2.imshow('hue_thresh', thresh)
kernel1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
dilation = cv2.dilate(cv2.bitwise_not(thresh), kernel1, iterations = 4) #-- performed dilation on the inverted image because the region of interest was not highlighted
cv2.imshow('dilation', dilation)
Теперь, имея возможную область интереса, я предположил контур с наибольшей областью, в которой находится автомобиль.
_, contours, hierarchy = cv2.findContours(dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
big_contour = 0 #-- contour with maximum area is stored here
max_area = 0 #-- to store maximum area
for cnt in contours:
if (cv2.contourArea(cnt) > max_area): #-- condition check to find contour with max area
max_area = cv2.contourArea(cnt)
big_contour = cnt
x, y, w, h = cv2.boundingRect(big_cnt) #-- store coordinates of contour with max area
cv2.rectangle(img, (x,y), (x+w,y+h), (0, 255, 0), 2)
cv2.imshow('rect_img', img)
cv2.imwrite(path + 'rect_img.jpg', img)
cv2.waitKey(0)
cv2.destroyAllWindows()