OpenCV 轮廓不闭合

OpenCV contours not closing

大家好!

我在创建轮廓方面遇到了问题。我尝试了所有配置,不幸的是,我无法获得物体的大轮廓。 第一个文件被加载到位图中,最后位图被加载到文件中。 (此处未显示,因为它什么也没给出)。

之前的图片:

之后的图像:

我想要的效果只是整车的外轮廓,或者至少是它的一些近似值。我目前拥有的代码(在到处寻找之后)是这样的:

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);

每当您的图像中有一堆复杂的颜色时,请务必先将其转换为另一种颜色space,然后再尝试分割您感兴趣的对象。

在提供的示例中,我将图像转换为各种颜色 space,例如 HSV、LAB 和 YCrCb(google 它们以获取更多信息)。 HSV 图像中的色调通道原来是为了分割而突出。

这是我的结果:

伪代码:

  1. 得到了色相通道图像的阈值图像
  2. 对色调通道的倒置图像进行膨胀。
  3. 找到面积覆盖最大的等高线并标记出来

编辑

代码如下:

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 颜色 space,但是 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()