ubuntu22.04@laptop OpenCV Get Started: 013_contour_detection-4. channel_experiments应用

时间:2024-02-18 09:20:21

在OpenCV中检测和绘制轮廓的步骤如下所示:

  1. 读取图像并将其转换为单通道:红色、绿色或蓝色
  2. 查找对象轮廓
  3. 绘制对象轮廓

4.1 读取图像并将其转换为单通道

C++:

    // read the image
    Mat image = imread("../../input/image_1.jpg");

    // B, G, R channel splitting
    Mat channels[3];
    split(image, channels);

Python:

# read the image
image = cv2.imread('../../input/image_1.jpg')

# B, G, R channel splitting
blue, green, red = cv2.split(image)

4.2 查找对象轮廓

C++:

    // detect contours using blue channel and without thresholding
    vector<vector<Point>> contours1;
    vector<Vec4i> hierarchy1;
    findContours(channels[0], contours1, hierarchy1, RETR_TREE, CHAIN_APPROX_NONE);

    // detect contours using green channel and without thresholding
    vector<vector<Point>> contours2;
    vector<Vec4i> hierarchy2;
    findContours(channels[1], contours2, hierarchy2, RETR_TREE, CHAIN_APPROX_NONE);

    // detect contours using red channel and without thresholding
    vector<vector<Point>> contours3;
    vector<Vec4i> hierarchy3;
    findContours(channels[2], contours3, hierarchy3, RETR_TREE, CHAIN_APPROX_NONE);

Python:

# detect contours using blue channel and without thresholding
contours1, hierarchy1 = cv2.findContours(image=blue, mode=cv2.RETR_TREE, 
                                       method=cv2.CHAIN_APPROX_NONE)

# detect contours using green channel and without thresholding
contours2, hierarchy2 = cv2.findContours(image=green, mode=cv2.RETR_TREE, 
                                       method=cv2.CHAIN_APPROX_NONE)

# detect contours using red channel and without thresholding
contours3, hierarchy3 = cv2.findContours(image=red, mode=cv2.RETR_TREE, 
                                       method=cv2.CHAIN_APPROX_NONE)

4.3 绘制对象轮廓

C++:

    // draw contours on the original image
    Mat image_contour_blue = image.clone();
    drawContours(image_contour_blue, contours1, -1, Scalar(0, 255, 0), 2);
    imshow("Contour detection using blue channels only", image_contour_blue);

    // draw contours on the original image
    Mat image_contour_green = image.clone();
    drawContours(image_contour_green, contours2, -1, Scalar(0, 255, 0), 2);
    imshow("Contour detection using green channels only", image_contour_green);

    // draw contours on the original image
    Mat image_contour_red = image.clone();
    drawContours(image_contour_red, contours3, -1, Scalar(0, 255, 0), 2);
    imshow("Contour detection using red channels only", image_contour_red);

Python:

# draw contours on the original image
image_contour_blue = image.copy()
cv2.drawContours(image=image_contour_blue, contours=contours1, contourIdx=-1, 
                 color=(0, 255, 0), thickness=2, lineType=cv2.LINE_AA)
# see the results
cv2.imshow('Contour detection using blue channels only', image_contour_blue)

# draw contours on the original image
image_contour_green = image.copy()
cv2.drawContours(image=image_contour_green, contours=contours2, contourIdx=-1, 
                 color=(0, 255, 0), thickness=2, lineType=cv2.LINE_AA)
# see the results
cv2.imshow('Contour detection using green channels only', image_contour_green)

# draw contours on the original image
image_contour_red = image.copy()
cv2.drawContours(image=image_contour_red, contours=contours3, contourIdx=-1, 
                 color=(0, 255, 0), thickness=2, lineType=cv2.LINE_AA)
# see the results
cv2.imshow('Contour detection using red channels only', image_contour_red)

4.4 效果

在下面的图像中,我们可以看到轮廓检测算法不能正确地找到轮廓。这是因为它不能正确地检测对象的边界,而且像素之间的强度差也没有很好地定义。这就是我们更喜欢使用灰度和二进制阈值图像来检测轮廓的原因。

另外,CHAIN_APPROX_SIMPLECHAIN_APPROX_NONE并没有差异,同样无法找到轮廓。

在这里插入图片描述