当给定点的点是三角形的顶点之一时,OpenCV的Subdiv2D / Delaunay是否被打破?

时间:2011-08-05 17:51:53

标签: c++ c opencv triangulation delaunay

构建三角测量的代码:

CvSubdiv2D *subdiv;
CvMemStorage *storage = cvCreateMemStorage(0);
CvRect rectangle = cvRect(0, 0, 100, 100);
subdiv = cvCreateSubdivDelaunay2D(rectangle, storage);
CvPoint2D32f p1 = cvPoint2D32f(10, 10);
CvPoint2D32f p2 = cvPoint2D32f(50, 10);
CvPoint2D32f p3 = cvPoint2D32f(10, 50);
cvSubdivDelaunay2DInsert(subdiv, p1);
cvSubdivDelaunay2DInsert(subdiv, p2);
cvSubdivDelaunay2DInsert(subdiv, p3);

之后,使用其中一个点进行查询:

CvSubdiv2DEdge edge;
CvSubdiv2DPoint *pp;
CvSubdiv2DPointLocation loc = cvSubdiv2DLocate(subdiv, p1, &edge, &pp);

获得结果后,您必须检查该点是否落在:

  • facet
  • edge
  • vertex
  • 在定义的三角剖分/矩形之外

在这种情况下,它是一个顶点:

if(loc == CV_PTLOC_VERTEX) {
//        CvSubdiv2DPoint *tp = cvSubdiv2DEdgeOrg(edge);
//        CvPoint2D32f point = tp->pt;
//        std::cout << point.x << ", " << point.y << std::endl;

//        CvSubdiv2DPoint *tp = cvSubdiv2DEdgeOrg(pp->first);
//        CvPoint2D32f point = tp->pt;
//        std::cout << point.x << ", " << point.y << std::endl;
}

然而,我的两种方法都失败了。在前3行中,我尝试查看locate是否在参数上放置了正确的边缘。它没有,我得到了一个分段错误。在第二个块上,我尝试访问first结构中的CvSubdiv2DPoint元素,但它也不起作用 - 分段错误。我无法找到first上的点,也无法使用它迭代其他边缘。

CvSubdiv2DPoint无用的原因是因为,为了遍历结构并实际找到三角形,我需要CvSubdiv2DEdge,但因为我无法从一个点转换为一个边缘,该功能的结果是无用的。

我可能忽略了一些东西,但对我来说它似乎已经被打破了。 Here's the documentation.有什么想法吗?

1 个答案:

答案 0 :(得分:0)

可以使用序列功能迭代边缘,这里是代码:

CvMemStorage* storage = cvCreateMemStorage();
CvSubdiv2D* subdivision = cvCreateSubdivDelaunay2D(rect, storage);
for (int i = 0; i < points.size(); ++i)
{
    cvSubdivDelaunay2DInsert(subdivision, points[i]);
}

cvCalcSubdivVoronoi2D(subdivision);
CvSeqReader reader;
CvSeq* seq = (CvSeq*) subdivision->edges;
cvStartReadSeq(seq, &reader);
for (int i = 0; i < seq->total; ++i)
{
    CvQuadEdge2D* edge = (CvQuadEdge2D*)reader.ptr;
    if (CV_IS_SET_ELEM(edge))
    {
               //Do something...
    }
    CV_NEXT_SEQ_ELEM(seq->elem_size, reader);
}

if (storage != 0)
{
    cvReleaseMemStorage(&storage);
}

虽然我没有找到迭代连接到某个顶点的边的方法,但是使用细分本身作为序列以相同的方式迭代顶点。