4

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

在此处输入图像描述

前任 左轮廓必须匹配,右轮廓不匹配

4

3 回答 3

2

这是一个解决方案:

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

您还可以使用霍夫变换。

于 2015-09-21T00:03:29.400 回答
1

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

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

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

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

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

此致!

于 2015-09-21T09:48:41.690 回答
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;
}
于 2015-09-21T10:12:53.990 回答