0

我在 Ubuntu 11.04 上使用 NetBeans 7.1,并希望使用 OpenCV 从一组点中获取三角形。我按如下方式构建 Delaunay 三角剖分。

vector< Triangle > CTwoDTriangulation::delaunayDiv(const vector< Point_<T> > & vP,   cv::Rect boundRect, vector<Triangle>& triangles, int& numTriangles)
{
    CvSubdiv2D* subdiv;
    int numPts=vP.size();
    CvPoint newPoint;

    CvMemStorage *storage;
    storage = cvCreateMemStorage(0);
    subdiv =  cvCreateSubdivDelaunay2D( boundRect, storage );
    for (size_t e = 0; e<numPts; e++)
    {
        newPoint=vP.at(e);
        if (newPoint.x>=boundRect.y && newPoint.y>=boundRect.y && newPoint.x<boundRect.width &&  newPoint.y<boundRect.height)
                cvSubdivDelaunay2DInsert(subdiv, vP.at(e));
    }

    CvSeqReader  reader;
    int i, total = subdiv->edges->total;
    int elem_size = subdiv->edges->elem_size;

    triangles.resize(2*total-5);    // Maximum number of triangles for number of edges
    numTriangles=0;

    cvStartReadSeq( (CvSeq*)(subdiv->edges), &reader, 0 );

    Triangle V;

    for( i = 0; i < total; i++ )
    {
        CvQuadEdge2D* edge = (CvQuadEdge2D*)(reader.ptr);

        if( CV_IS_SET_ELEM( edge ))
        {
            CvSubdiv2DEdge e = (CvSubdiv2DEdge)edge;
            if (FindTriangleFromEdge(e, V)) 
        {
            triangles.at(numTriangles++)=V;
        }
    }
    CV_NEXT_SEQ_ELEM( elem_size, reader );
}
cvReleaseMemStorage(&storage);

return triangles;
}

FindTriangleFromEdge() 具有以下形式。

void CTwoDTriangulation::FindTriangleFromEdge(CvSubdiv2DEdge e, Triangle& V)
{
   CvSubdiv2DEdge t = e;    // Number of type size_t
   CvPoint buf[3];          // Triangle vertices
   int iPointNum = 3;
   int  j;
   CvPoint pts[3];

   for(j = 0; j < iPointNum; j++ )
   {
        CvSubdiv2DPoint* point = cvSubdiv2DEdgeOrg( t );
        if( !point ) break;
        pts[j].x=point->pt.x;
        pts[j].y=point->pt.y;
        buf[j] = cvPoint( cvRound(point->pt.x), cvRound(point->pt.y));
        t = cvSubdiv2DGetEdge( t, CV_NEXT_AROUND_LEFT );
   }
  AddTriangle(buf, pts, V);
}

这让我得到了大部分的三角形,但有些不见了。例如,我设置了一组近似矩形网格的点。我得到以下 (5,1);(103,101);(1,101)
(106,1);(103,101);(5,1)
(5,1);(106,1);(103,101)
(204,101) ;(106,1);(208,1)
(208,1);(307,101);(204,101)
(309,1);(307,101);(204,101)

所以 (106,1);(204,1);(103,101) 缺失并且至少有一个三角形被复制。

4

3 回答 3

1

您的 if 语句似乎有错误?为什么将 newPoint.x 与 boundRect.y 进行比较?

if (newPoint.x>=boundRect.y && newPoint.y>=boundRect.y && newPoint.x<boundRect.width &&  newPoint.y<boundRect.height)
            cvSubdivDelaunay2DInsert(subdiv, vP.at(e));
于 2012-05-12T23:42:03.167 回答
0

When you use CV_NEXT_AROUND_LEFT the next edge to be chosen will be the one on LEFT facet of the specified edge. Now consider, for example, a triangle formed by vertices V1, V2 and V3, whose sides are Edge1, Edge2 and Edge3.

Additionally, imagine that V1 is the Org Point of Edge1, V2 is the Org Point of Edge2 and V3 is the Org Point of Edge3 (like vectors connected in a clockwise orientation). In this case, the left facets are always outside the given triangle so, in your code, this triangle will be missing.

I could not realize another way of preventing this except by combining CV_NEXT_AROUND_LEFT with CV_NEXT_AROUND_RIGHT and removing the duplicate triangles that will be recorded.

于 2013-06-05T04:33:12.773 回答
0

我有同样的问题。我的解决方案是检查

cvSubdiv2DGetEdge(t, CV_NEXT_AROUND_RIGHT);

看!有了这个,它找到了丢失的,但错过了其他一些。所以我的解决方案是暂时结合这两个结果。

于 2013-03-14T21:35:35.660 回答