2

三角測量を構築するためのコード:

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);

その後、ポイントの 1 つを使用してクエリを作成します。

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

結果が得られたら、ポイントが該当するかどうかを確認する必要があります。

  • ファセット
  • バーテックス
  • 定義された三角測量/長方形の外側

この場合、それは頂点です。

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、パラメーターに正しいエッジが設定されているかどうかを確認してみました。そうではなく、セグメンテーション違反が発生しました。first2 番目のブロックで、構造体の要素にアクセスしようとしましたCvSubdiv2DPointが、これも機能しません。セグメンテーション違反です。ポイントを見つけることができずfirst、他のエッジで反復して使用することもできません。

役に立たない理由CvSubdiv2DPointは、構造を反復処理して実際に三角形を見つけるために が必要CvSubdiv2DEdgeだからですが、ポイントからエッジに変換できないため、関数の結果は役に立たないからです。

私は何かを見落としているかもしれませんが、私には壊れているようです。これがドキュメントです。何かご意見は?

4

1 に答える 1

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

ある頂点に接続されているエッジを反復する方法は見つかりませんでしたが、頂点は、サブディビジョン自体をシーケンスとして使用して同じ方法で反復されます。

于 2012-02-16T22:44:37.773 に答える