如何检测与C ++和OpenCV的轮廓自相交?

时间:2015-09-20 20:24:28

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

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

enter image description here

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

3 个答案:

答案 0 :(得分:1)

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

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

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

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

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

祝你好运!

答案 1 :(得分:0)

这是一个解决方案:

  1. Skeleton + pruning =>将轮廓减少到单个像素宽度
  2. 对于每个像素,计算邻居数
  3. 如果一个像素有两个以上的邻居,那么它就在十字路口的中间。
  4. (可选)连接组件标签,以便分离不同的形状。
  5. 您也可以使用Hough变换。

答案 2 :(得分:0)

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

如果我错了,请告诉我。

我试过的代码并不适合这种逻辑,也许有人可能会帮助你。

#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;
}