Контуры OpenCV не закрываются - PullRequest
0 голосов
/ 02 мая 2018

Добрый день всем!

У меня возникла проблема с созданием контуров. Я перепробовал все конфигурации и, к сожалению, я не могу получить один большой контур объекта. Первый файл загружается в растровое изображение, а в конце растровое изображение загружается в файл. (Не показано здесь, поскольку это ничего не дает).

Изображение до:

img1

Изображение после:

img2

Эффект, который я хотел бы получить, это просто внешний контур всего автомобиля или, по крайней мере, некоторое его приближение. Код, который у меня есть (после просмотра везде), таков:

bitmap = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(filePath), 500, 500);
    Mat src = new Mat();
    Utils.bitmapToMat(bitmap, src);
    Mat gray = new Mat();
    Imgproc.cvtColor(src, gray, Imgproc.COLOR_RGBA2GRAY);
    Imgproc.Canny(gray, gray, 0, 1000);
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Mat hierarchy = new Mat();
    Imgproc.findContours(gray, contours, hierarchy, Imgproc.CV_RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
    for (int contourIdx = 0; contourIdx < contours.size(); contourIdx++) {
        Imgproc.drawContours(src, contours, contourIdx, new Scalar(0, 0, 255), -1);
    }
    Utils.matToBitmap(gray, bitmap);

1 Ответ

0 голосов
/ 02 мая 2018

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

В приведенном примере я преобразовал изображение в различные цветовые пространства, такие как HSV, LAB и YCrCb (для получения дополнительной информации обратитесь к Google. Оттенок канала в изображении HSV оказался заметным для сегментации.

Вот мой результат:

enter image description here

псевдокод:

  1. Получено пороговое изображение оттенка канала изображения
  2. Выполнено расширение на инвертированном изображении канала оттенка.
  3. Нашел контур с наибольшим охватом области и отметил его

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()
...