takminの書きっぱなし備忘録 @はてなブログ

主にコンピュータビジョンなど技術について、たまに自分自身のことや思いついたことなど

OpenCVの平面細分割用 C++クラス SubDiv2D

OpenCVのCインターフェースでは、平面細分割を作成してくれる関数が(現在はレガシーコードとして)用意されていましたが、C++版は長らく実装されていませんでした。


ところがサンプルコードを覗いたところ、"delauney2.cpp"というコードを発見。APIドキュメントはどこにも見当たりませんが、いつの間にやら(早くても2.3以前)実装されたみたいです。


というわけで、サンプルコードとヘッダーファイル、Cインターフェースのリファレンスを参照しながら、わかった範囲を自分用のメモとして書いておきます。使い方についてはサンプルコードを参照して下さい。
かなりテキトーに書いたので、内容には責任持ちません。

class SubDiv2D{
    //! コンストラクタ
    /*!
    \param[in] rect 空のドロネー細分割を行うためのパラメータ。例えば画像全体に対して行いたい場合はcv::Rect(0,0,width,height)とする
    */
    Subdiv2D();
    Subdiv2D(Rect rect);

    //! 初期化
    void initDelaunay(Rect rect);
    
    //! ドロネーの三角形に点を追加
    int insert(Point2f pt);
    void insert(const vector& ptvec);

    //! 与えられた点が属する三角形に関する情報を返す
    /*!
    \param[in] pt 入力点
    \param[out] edge 入力点が属する三角形の最初の辺ID
    \param[out] vertex 入力点が属する三角形の最初の頂点ID
    */
    int locate(Point2f pt, int& edge, int& vertex);
    
    //! 与えられた点に最も近い細分割の頂点を求める。
    /*!
    \param[in] pt 入力点
    \param[out] nearestPt 最も近い頂点
    */
    int findNearest(Point2f pt, Point2f* nearestPt=0);

    //! ドロネー辺のリストを取得
    /*!
    \param[out] edgeList 辺リスト。(始点のx座標とy座標、終点のx座標とy座標)
    */
    void getEdgeList(vector& edgeList) const;

    //! ドロネー三角形の頂点を取得
    /*!
    \param[out] traiangleList 三角形の頂点リスト。(3つの点のx座標とy座標が交互に格納されている)
    */
    void getTriangleList(vector& triangleList) const;

    //! ボロノイ領域を取得
    /*!
    \param[in] idx 取得するボロノイ領域のID
    \param[out] facetList ボロノイ領域を囲む頂点
    \param[out] facetCenters ボロノイ領域の母点
    */
    void getVoronoiFacetList(const vector& idx, vector >& facetList,
                                     vector& facetCenters);
    
    //! 頂点を取得
    /*!
    \param[in] vertex 頂点ID
    \param[out] firstEdge 頂点に接する最初の辺のID
    \return 頂点の座標
    */
    Point2f getVertex(int vertex, int* firstEdge=0) const;
    
    //! 与えられた辺に関連する辺を1つ返す
    /*!
    \param[in] edge エッジのID
    \param[in] nextEdgeType edgeとどのような関係にあるエッジを取得するか。
    \return 関連するエッジのID
    */
    int getEdge( int edge, int nextEdgeType ) const;

    int nextEdge(int edge) const;
    int rotateEdge(int edge, int rotate) const;
    int symEdge(int edge) const;

    //! エッジの始点を取得
    /*!
    \param[in] edge エッジのID
    \param[in] orgpt 始点座標。
    \return 正しく取得できた場合は0より大きい
    */
    int edgeOrg(int edge, Point2f* orgpt=0) const;

    //! エッジの終点を取得
    /*!
    \param[in] edge エッジのID
    \param[in] dstpt 終点座標。
    \return 正しく取得できた場合は0より大きい
    */
    int edgeDst(int edge, Point2f* dstpt=0) const;
}