OpenCV関数pointPolygonTest()の使い方
2830 ワード
今日は欠陥検出のプログラム設計を行う際に,一つの点が所定の輪郭にあるかどうかに基づいて物が汚れているかどうかを判断したい.Opencvにはこのような関数があるはずだと推定し、検索して記録した.
C++: double pointPolygonTest(InputArray contour, Point2f pt, bool measureDist)
パラメータ:contour---輪郭を入力
pt---輪郭に対してテストが必要な点
measure_dist---0でない場合、関数は輪郭の最も近いエッジまでの距離を推定します.
関数cvPointPolygonTestは、テストポイントが輪郭内にあるかどうか、輪郭外にあるかどうか、または輪郭のエッジ(または共辺の交点)にあるかどうかを決定し、その戻り値は正負ゼロであり、対応し、measure_dist=0の場合、戻り値は1,-1,0であり、同様にmeasure_dist≠0の場合、ポイントから最も近いエッジまでの符号付き距離である.
Opencvに付属する例:
C++: double pointPolygonTest(InputArray contour, Point2f pt, bool measureDist)
パラメータ:contour---輪郭を入力
pt---輪郭に対してテストが必要な点
measure_dist---0でない場合、関数は輪郭の最も近いエッジまでの距離を推定します.
関数cvPointPolygonTestは、テストポイントが輪郭内にあるかどうか、輪郭外にあるかどうか、または輪郭のエッジ(または共辺の交点)にあるかどうかを決定し、その戻り値は正負ゼロであり、対応し、measure_dist=0の場合、戻り値は1,-1,0であり、同様にmeasure_dist≠0の場合、ポイントから最も近いエッジまでの符号付き距離である.
Opencvに付属する例:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include
#include
#include
using namespace cv;
using namespace std;
/** @function main */
int main( int argc, char** argv )
{
/// const int r = 100;
Mat src = Mat::zeros( Size( 4*r, 4*r ), CV_8UC1 );
/// :
vector vert(6);
vert[0] = Point( 1.5*r, 1.34*r );
vert[1] = Point( 1*r, 2*r );
vert[2] = Point( 1.5*r, 2.866*r );
vert[3] = Point( 2.5*r, 2.866*r );
vert[4] = Point( 3*r, 2*r );
vert[5] = Point( 2.5*r, 1.34*r );
/// src
for( int j = 0; j < 6; j++ )
{ line( src, vert[j], vert[(j+1)%6], Scalar( 255 ), 3, 8 ); }
///
vector > contours; vector hierarchy;
Mat src_copy = src.clone();
findContours( src_copy, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
///
Mat raw_dist( src.size(), CV_32FC1 );
for( int j = 0; j < src.rows; j++ )
{ for( int i = 0; i < src.cols; i++ )
{ raw_dist.at(j,i) = pointPolygonTest( contours[0], Point2f(i,j), true ); }
}
double minVal; double maxVal;
minMaxLoc( raw_dist, &minVal, &maxVal, 0, 0, Mat() );
minVal = abs(minVal); maxVal = abs(maxVal);
///
Mat drawing = Mat::zeros( src.size(), CV_8UC3 );
for( int j = 0; j < src.rows; j++ )
{ for( int i = 0; i < src.cols; i++ )
{
if( raw_dist.at(j,i) < 0 )
{ drawing.at(j,i)[0] = 255 - (int) abs(raw_dist.at(j,i))*255/minVal; }
else if( raw_dist.at(j,i) > 0 )
{ drawing.at(j,i)[2] = 255 - (int) raw_dist.at(j,i)*255/maxVal; }
else
{ drawing.at(j,i)[0] = 255; drawing.at(j,i)[1] = 255; drawing.at(j,i)[2] = 255; }
}
}
///
char* source_window = "Source";
namedWindow( source_window, CV_WINDOW_AUTOSIZE );
imshow( source_window, src );
namedWindow( "Distance", CV_WINDOW_AUTOSIZE );
imshow( "Distance", drawing );
waitKey(0);
return(0);
}