【OpenCV画像処理】凸包(Convex Hull)コード実装事例

凸包とは

任意の 2 点を結ぶ線は多角形の境界に含まれますが、その多角形が最小であるという制約条件もあります。

凸包アプリケーション

オブジェクトの凸包検出は、オブジェクト認識、ジェスチャ認識、境界検出でよく使用されます。
凸包検出は、輪郭解析の後によく使用されます。バイナリ画像の輪郭分析後、各輪郭の凸包を構築でき、構築完了後に凸包に含まれる点セットが返されます。返された凸包点セットに従って、輪郭の対応する凸包を描画できます。一般に、凸曲線は常に凸であるか、少なくとも平坦です。凹んでいる箇所がある場合、それを凸欠陥といいます。

convexHull関数の説明

convexHull関数の呼び出し形式

    void convexHull(InputArray points,OutputArray hull,bool clockwise =  false,

                                 bool returnPoints = true)

パラメータの詳細な説明:

  • InputArray ポイント: 取得された点セット、通常は画像輪郭関数によって取得された輪郭点

  • OutputArray hull: 出力は、輪郭ごとに形成される凸包の 2 次元 xy 点の座標値です。

  • bool Clockwise = false: 凸包の方向を時計回りまたは反時計回りに示します。

  • bool returnPoint = true: ポイントを返すか、ポイント アドレスのインデックスを返すかを示します。

コード例

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>

using namespace cv;
using namespace std;

static void help(char** argv)
{
    
    
    cout << "\nThis sample program demonstrates the use of the convexHull() function\n"
         << "Call:\n"
         << argv[0] << endl;
}

int main( int argc, char** argv )
{
    
    
    CommandLineParser parser(argc, argv, "{help h||}");
    if (parser.has("help"))
    {
    
    
        help(argv);
        return 0;
    }
    Mat img(500, 500, CV_8UC3);
    RNG& rng = theRNG();

    for(;;)
    {
    
    
        int i, count = (unsigned)rng%100 + 1;

        vector<Point> points;

        for( i = 0; i < count; i++ )
        {
    
    
            Point pt;
            pt.x = rng.uniform(img.cols/4, img.cols*3/4);
            pt.y = rng.uniform(img.rows/4, img.rows*3/4);

            points.push_back(pt);
        }

        vector<Point> hull;
        convexHull(points, hull, true);

        img = Scalar::all(0);
        for( i = 0; i < count; i++ )
            circle(img, points[i], 3, Scalar(0, 0, 255), FILLED, LINE_AA);

        polylines(img, hull, true, Scalar(0, 255, 0), 1, LINE_AA);
        imshow("hull", img);

        char key = (char)waitKey();
        if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC'
            break;
    }

    return 0;
}

コードの説明:

 int i, count = (unsigned)rng%100 + 1;

        vector<Point> points;

        for( i = 0; i < count; i++ )
        {
    
    
            Point pt;
            pt.x = rng.uniform(img.cols/4, img.cols*3/4);
            pt.y = rng.uniform(img.rows/4, img.rows*3/4);

            points.push_back(pt);
        }

カウント ポイントをランダムに生成します。ランダムに生成されたポイントの範囲は x(img.cols/4, img.cols 3/4)、y(img.rows/4, img.rows 3/4)です。ポイントは画像固有の領域にあります。


convexHull(points, hull, true);

ランダムに生成された点セット点を入力として、ハルを出力として使用して convexHull を呼び出します。


 for( i = 0; i < count; i++ )
            circle(img, points[i], 3, Scalar(0, 0, 255), FILLED, LINE_AA);

        polylines(img, hull, true, Scalar(0, 255, 0), 1, LINE_AA);
        imshow("hull", img);

ランダムに生成されたすべての点を img 上に描画します。polylines()img 上にすべてのバンプ コレクションを描画します最終結果は次のようになります。

演算結果

画像の説明を追加してください

画像の説明を追加してください

画像の説明を追加してください

おすすめ

転載: blog.csdn.net/m0_49302377/article/details/130426640