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) が欠落しており、少なくとも 1 つの三角形が重複しています。

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

次のエッジを使用CV_NEXT_AROUND_LEFTすると、指定したエッジの LEFT ファセットにあるエッジが選択されます。ここで、たとえば、頂点V1V2およびによって形成されV3、辺がEdge1Edge2およびである三角形を考えてみましょうEdge3

V1さらに、が の Org Point でありEdge1V2が の Org Point でEdge2あり、V3がの Org Point であると想像してくださいEdge3(時計回りに接続されたベクトルのように)。この場合、左側のファセットは常に指定された三角形の外側にあるため、コードではこの三角形が欠落します。

記録される重複した三角形を組み合わせCV_NEXT_AROUND_LEFTて削除する以外に、これを防ぐ別の方法を実現できませんでした。CV_NEXT_AROUND_RIGHT

于 2013-06-05T04:33:12.773 に答える
0

私も同じ問題を抱えていました。私の解決策は、チェックすることでした

cvSubdiv2DGetEdge( t, CV_NEXT_AROUND_RIGHT );

そして見て!これにより、欠落しているものが見つかりましたが、他のいくつかが欠落しています。したがって、私の解決策は、今のところ両方の結果を組み合わせることです。

于 2013-03-14T21:35:35.660 に答える