OpenCV C++计算多边形的最大内切圆
这个程序使用OpenCV计算出多边形的最大内切圆。最大内切圆检测在工业检测、形状分析中很实用例如检测零件内部的最大可用空间。左边是输入图片是程序生成的六边形。右边是输出图片是对输入图片进行处理的结果。程序先对输入图片上的每个像素执行点多边形测试pointPolygonTest。点多边形测试计算点到多边形轮廓的最小距离。如果距离是正值(红色)表示点(x,y)在多边形的内部。如果距离是负值(蓝色)表示点(x,y)在多边形的外部。如果距离为0(白色)表示点(x,y)在多边形的轮廓上。颜色深浅表示距离边界的远近越靠近边界颜色越亮/白越远离边界颜色越暗/黑。然后寻找出这些距离里的最大值这个最大值就是六边形的最大内切圆的半径。这个最大值对应的点(x,y)就是内切圆的圆心。有了圆心和半径就可以绘制出这个内切圆。代码#include opencv2/highgui.hpp #include opencv2/imgproc.hpp #include iostream using namespace cv; using namespace std; int main( void ) { const int r 100; Mat src Mat::zeros( Size( 4*r, 4*r ), CV_8U ); vectorPoint2f vert(6); vert[0] Point( 3*r/2, static_castint(1.34*r) ); vert[1] Point( 1*r, 2*r ); vert[2] Point( 3*r/2, static_castint(2.866*r) ); vert[3] Point( 5*r/2, static_castint(2.866*r) ); vert[4] Point( 3*r, 2*r ); vert[5] Point( 5*r/2, static_castint(1.34*r) ); for( int i 0; i 6; i ) { line( src, vert[i], vert[(i1)%6], Scalar( 255 ), 3 ); } vectorvectorPoint contours; findContours( src, contours, RETR_TREE, CHAIN_APPROX_SIMPLE); Mat raw_dist( src.size(), CV_32F ); for( int i 0; i src.rows; i ) { for( int j 0; j src.cols; j ) { raw_dist.atfloat(i,j) (float)pointPolygonTest( contours[0], Point2f((float)j, (float)i), true ); } } double minVal, maxVal; Point maxDistPt; minMaxLoc(raw_dist, minVal, maxVal, NULL, maxDistPt); minVal abs(minVal); maxVal abs(maxVal); Mat drawing Mat::zeros( src.size(), CV_8UC3 ); for( int i 0; i src.rows; i ) { for( int j 0; j src.cols; j ) { if( raw_dist.atfloat(i,j) 0 ) { drawing.atVec3b(i,j)[0] (uchar)(255 - abs(raw_dist.atfloat(i,j)) * 255 / minVal); } else if( raw_dist.atfloat(i,j) 0 ) { drawing.atVec3b(i,j)[2] (uchar)(255 - raw_dist.atfloat(i,j) * 255 / maxVal); } else { drawing.atVec3b(i,j)[0] 255; drawing.atVec3b(i,j)[1] 255; drawing.atVec3b(i,j)[2] 255; } } } circle(drawing, maxDistPt, (int)maxVal, Scalar(255,255,255)); imshow( src, src ); imshow( dst, drawing ); waitKey(); return 0; }