凸包とは
任意の 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 上にすべてのバンプ コレクションを描画します。最終結果は次のようになります。