【问题标题】:How to detect contour self-intersection with C++ and OpenCV?如何检测与 C++ 和 OpenCV 的轮廓自相交?
【发布时间】:2015-12-17 11:41:01
【问题描述】:

我需要在自相交上测试轮廓,但我不知道它是如何实现的。或者我如何在 cv::Mat 中只检测没有自相交的轮廓?

F.ex.左轮廓必须匹配,右轮廓不匹配

【问题讨论】:

  • 你能发布一个具有预期结果的示例图像吗?
  • 你对这些轮廓了解多少?你知道有序的顶点吗?还是需要从二值图像中找出来?
  • 我知道从 cv::findContours(...) 获得的点集​​合,std::vector<:point>。我想要一些函数来告诉我是否有轮廓相交。

标签: c++ opencv image-processing geometry opencv-contour


【解决方案1】:

这里有一个解决方案:

  1. 骨架 + 修剪 => 将轮廓缩小到单个像素宽度
  2. 对于每个像素,计算相邻像素的数量
  3. 如果一个像素有两个以上的邻居,那么它就在一个交叉点的中间。
  4. (可选)连接组件标签以区分不同的形状。

您也可以使用霍夫变换。

【讨论】:

    【解决方案2】:

    如果线条由多边形表示(您知道角点),您可以在累积矩阵上绘制线条。

    声明一个CV_8UC1 类型的新空白cv::Mat 并将其初始化为零值。对于两条线之间的每个像素,将矩阵增加1

    如果使用cv::line 方法是完成此任务的最佳方式,我不是(您可以为每一行创建一个新图像并将所有图像汇总为最后一步)。我能想到的最好方法是使用直线方程来增加点数。

    当您绘制相交的线时,在累积矩阵中您将获得2 的值。如果你找到它们,你就会知道轮廓有自相交,你也知道它们在哪里。

    如果您将图像作为输入,那么前面提到的解决方案可能会起作用。

    最好的问候!

    【讨论】:

    • 你能更准确一点吗?那会很有帮助
    【解决方案3】:

    我尽力实现它,但由于缺乏编码逻辑而无法实现。我试过的逻辑是你有一组轮廓点。现在检查每个点的出现,即每个点出现了多少次,如果出现超过一次,则表示交叉点。

    如果我错了,请告诉我。

    我尝试的代码不适用于此逻辑,也许有人可以帮助您。

    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <iostream>
    #include "opencv2/imgproc/imgproc.hpp"
    using namespace cv;
    using namespace std;
    RNG rng(12345);
    int main( )
    {
    
    
        Mat image;
        image = imread("0.png", CV_LOAD_IMAGE_COLOR);   // Read the file
    
        if(! image.data )                              // Check for invalid input
        {
            cout <<  "Could not open or find the image" << std::endl ;
            return -1;
        }
    
        cvtColor(  image,  image, CV_BGR2GRAY );
        namedWindow( "Display window12", WINDOW_AUTOSIZE );// Create a window for display.
        imshow( "Display window12", image );   
        Mat drawing;
        vector<vector<Point> > contours;
        vector<Vec4i> hierarchy;
        findContours( image, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
        int m = 1;
        vector<Point> contours1;
    
    for(int i= 0; i < contours.size(); i++)
    {
        for(int j= 0; j < contours[i].size();j++) // run until j < contours[i].size();
        {
    
            contours1.push_back(Point (contours[i][j]));
    
         //   cout << contours[i][j] << "contours1"<<contours1<<endl; //do whatever
        }
    }
    cout<<contours.size();
    // Finding the occrence of each point it has appeared 
    
    //for(int i=0;i<contours.size();i++)
    //{
    //    for(int j=0; j<contours[i].size();j++) // run until j < contours[i].size();
    //    {
    //      //contours1.push_back(Point (contours[i][j]));
    //      //if (contours[i][j] == contours[i][j])
    //           if( contours[i] ==contours1.at(i).x)
    //          //   if( posX ==points.at(p).x)
    //          cout<<"hi";
    //     //   cout << contours[i][j] << "contours1"<<contours1<<endl; //do whatever
    //   }
    //}
    
        namedWindow( "Display window", WINDOW_AUTOSIZE );// Create a window for display.
        imshow( "Display window", image );   
        waitKey(0);                                          // Wait for a keystroke in the window
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-27
      • 1970-01-01
      • 1970-01-01
      • 2016-10-24
      相关资源
      最近更新 更多