1

我正在尝试使用 python OpenCV 查找并分离边缘检测图像中的所有边缘。边缘可以是轮廓的形式,但不是必须的。我只想将所有连接的边缘像素组合在一起。所以从技术上讲,该算法在程序上可能听起来像这样:

  1. 对于每个边缘像素,找到一个相邻的(连接的)边缘像素并将其添加到图像的当前细分中,直到找不到一个为止。
  2. 然后移动到下一个未检查的边缘像素并开始新的细分并再次执行 1)。

我已经看过了,cv.findContours但结果并不令人满意,可能是因为它是用于轮廓(封闭边缘)而不是自由端的。结果如下:

检测到原始边缘:

轮廓处理后:

我预计这五个边缘将各自分组到其自己的图像细分中,但显然 cv2.findContours 函数将边缘中的 2 个甚至进一步细分为我不想要的细分。

这是我用来保存这两张图片的代码:

    def contourForming(imgData):
      cv2.imshow('Edge', imgData)
      cv2.imwrite('EdgeOriginal.png', imgData)
      contours = cv2.findContours(imgData, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
      cv2.imshow('Contours', imgData)
      cv2.imwrite('AfterFindContour.png', imgData)
      cv2.waitKey(0)
      pass

但是,我的实施有一些限制。我必须使用 Python 2.7 和 OpenCV2。除了这些,我不能使用任何其他版本或语言。我这样说是因为我知道 OpenCV 2 有一个使用 C++ 的 connectedComponent 函数。我本可以使用它,但问题是,由于某些限制,我无法使用它。

那么,知道我应该如何解决这个问题吗?

4

1 回答 1

2

使用findContours是正确的方法,你只是做错了。

仔细查看文档:

注意:源图像被此函数修改。

您的“轮廓处理后”图像实际上是来自findContours. 因此,如果您希望在调用 后原始图像完好无损findContours,通常的做法是将克隆的图像传递给函数。

有意义的结果findContours在 中contours。您需要使用 绘制它们drawContours,通常是在新图像上。

这是我得到的结果:

在此处输入图像描述

使用以下 C++ 代码:

#include <opencv2/opencv.hpp>
using namespace cv;

int main(int argc, char** argv)
{
    // Load the grayscale image
    Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);

    // Prepare the result image, 3 channel, same size as img, all black
    Mat3b res(img.rows, img.cols, Vec3b(0,0,0));

    // Call findContours
    vector<vector<Point>> contours;
    findContours(img.clone(), contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);

    // Draw each contour with a random color
    for (int i = 0; i < contours.size(); ++i)
    {
        drawContours(res, contours, i, Scalar(rand() & 255, rand() & 255, rand() & 255));
    }

    // Show results
    imshow("Result", res);
    waitKey();

    return 0;
}

移植到 Python 应该相当容易(对不起,我不能给你 Python 代码,因为我无法测试它)。您还可以查看特定的OpenCV-Python 教程以检查如何正确使用findContoursdrawContours.

于 2015-11-23T12:56:30.430 回答