理想图像的外部和内部边缘检测

时间:2016-08-24 07:44:58

标签: c++ opencv edge-detection

我正在寻找一种算法,可以在仅包含两个不同RGB值的理想图像上进行外部和内部轮廓检测。

下面是我要处理的图像(第一个)的典型示例,下一个图像是我自己展示我期待的结果的图像。

最后一个是通过OpenCV demo Software提供的演示软件进行OpenCV Canny检测的结果。

canny算法并不令人满意,因为它会使形状(特别是角落)过于平滑。

是否有任何优雅的算法可以提供与第二张图像相同的结果?

Original Image
My own brain's contour detection and expected result
OpenCV -> Contour algorithm result

2 个答案:

答案 0 :(得分:4)

轮廓提取是最简单的方法:

int main(int argc, char* argv[])
{
    cv::Mat input = cv::imread("C:/StackOverflow/Input/ContourExtraction.png");

    cv::Mat mask;
    // create a perfect mask: Easy if you know the 2 colors present in your image:
    cv::inRange(input, cv::Scalar(100, 0, 0), cv::Scalar(255, 255, 255), mask);
    cv::imshow("mask", mask);

    std::vector<std::vector<cv::Point> > contours; // contour points
    std::vector<cv::Vec4i> hierarchy; // this will give you the information whether it is an internal or external conotour.

    // contour extraction: This will alter the input image, so if you need it later use mask.clone() instead
    findContours(mask, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, cv::Point(0, 0)); // use different CV_CHAIN_APPROX_ if you dont need ALL the points but only the ones that dont lie on a common line

    // output images:
    cv::Mat contoursExternal = input.clone();
    cv::Mat contoursInternal = input.clone();
    cv::Mat contoursAll = cv::Mat::zeros(input.size(), CV_8UC1);

    // draw contours
    for (unsigned int i = 0; i < contours.size(); ++i)
    {
        cv::drawContours(contoursAll, contours, i, cv::Scalar::all(255), 1);
        if (hierarchy[i][3] != -1) cv::drawContours(contoursInternal, contours, i, cv::Scalar::all(255), 1);
        else cv::drawContours(contoursExternal, contours, i, cv::Scalar::all(255), 1);
    }

    cv::imshow("internal", contoursInternal);
    cv::imshow("external", contoursExternal);
    cv::imshow("all", contoursAll);


    cv::imshow("input", input);
    cv::waitKey(0);
    return 0;
}

给出这些结果:

外部轮廓:

enter image description here

内部轮廓:

enter image description here

结果掩码:

enter image description here

答案 1 :(得分:1)

罗伯茨交叉算法是一种给边缘带来更多锯齿的东西。虽然在你的例子中它非常容易受到噪音的影响但我并不相信它会成为一个交易破坏者。

有一个很好的总结,它如何解释它比我自己Here好得多。基本上你采用2x2区域,执行x和y卷积并近似梯度幅度,因为平方根用于慢速旋转。