轮廓的最小外接矩形、最小外接圆、三角形、椭圆等

OpenCV官网

#include 
#include 


using namespace cv;
using namespace std;


Mat src_gray;
int thresh = 100;
RNG rng(12345);

void thresh_callback(int, void*);

int main(void)
{
	
    Mat src = imread("../res/balloon.png");
    if(src.empty())
    {
	cout << "can't load image" << endl;
	return -1;
    }


    cvtColor(src, src_gray, cv::COLOR_BGR2GRAY);
    blur(src_gray, src_gray, Size(3,3));

    const char* source_window = "Source";
    namedWindow(source_window);
    imshow(source_window, src);

    const int max_thresh =255;
    createTrackbar("canny thresh:", source_window, &thresh, max_thresh, thresh_callback);
    thresh_callback(0,0);

    waitKey();

	return 0;
};



void thresh_callback(int, void*)
{
    Mat canny_output;
    Canny(src_gray, canny_output, thresh, thresh*2);


    vector<vector<Point>> contours;
    findContours(canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE);  //从canny输出得到轮廓图

    vector<vector<Point>> contours_poly(contours.size());   //近似轮廓的多边形
    vector<Rect> boundRect (contours.size());     //矩形
    vector<Point2f> centers(contours.size());   // 圆的中心
    vector<float> radius(contours.size());      //圆的半径


    for(size_t i=0; i<contours.size();i++)  //对于每个轮廓都进行以下操作
    {
	cv::approxPolyDP(contours[i], contours_poly[i], 3, true); //将轮廓近似到多边形,最大距离不大于3
	boundRect[i] = cv::boundingRect(contours_poly[i]);     //得到  能包围多边形的最小矩形
	cv::minEnclosingCircle(contours_poly[i], centers[i], radius[i]); //得到能包围多边形的最小圆
    }


//开始画图, 多边形、圆、矩形
    Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);

    for(size_t i=0; i<contours.size(); i++)
    {
	Scalar color = Scalar(rng.uniform(0,256), rng.uniform(0, 256), rng.uniform(0,256));
	drawContours(drawing, contours_poly, (int)i, color); 
	cv::rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color,2);
	cv::circle(drawing, centers[i], (int)radius[i], color, 2);
    }	

    imshow("Contours", drawing);

}

结果:

轮廓的最小外接矩形、最小外接圆、三角形、椭圆等_第1张图片


OpenCV API


  1. 得到轮廓近似的多边形, 轮廓也是有一系列点组成,但是近似到多边行,点会变少,也会存在指定近似误差的问题(多边形和轮廓之间最大距离)

void cv::approxPolyDP

( 	    InputArray  	curve,    //输入的轮廓,存在std::vector 或者Mat
		OutputArray  	approxCurve, // 输出的近似, 和输入类型一样
		double  	epsilon, // 指定近似的误差, 近似的多边行和轮廓之间最大距离
		bool  	closed   // true: 近似多边形是closed,第一个点和最后一个点连起来的, false: not closed
) 	




  1. 计算能 包含一组点 的最小外接矩形(up-right boundidng:正的,没有旋转的矩形)
    Rect cv::boundingRect ( InputArray array )
    输入灰度图 或者2D 一组点, 存在std::vector 或者 Mat.




  1. 找到 包含一组点 的最小圆
    void cv::minEnclosingCircle
( 	    InputArray  	points,  //输入点, 存在std::vector<> or Mat
		Point2f &  	center,   //圆心
		float &  	radius   //半径
) 	



延伸

  1. 找到一组点的最小外接三角形

double cv::minEnclosingTriangle

(
InputArray  	points,   //Input vector of 2D points with depth CV_32S or CV_32F, stored in std::vector<> or Mat
OutputArray  	//triangle Output vector of three 2D points defining the vertices of the triangle. The depth of the OutputArray must be CV_32F.
) 	

轮廓的最小外接矩形、最小外接圆、三角形、椭圆等_第2张图片




  1. 找到一组点的最小外接矩形(可能是旋转的)

RotatedRect cv::minAreaRect ( InputArray points )

值得注意的是, 当一组点的一部分接近边界的时候,所得到的矩形的顶点有可能是负数




  1. 找到一组点的外接椭圆

RotatedRect cv::fitEllipse ( InputArray points )
值得注意的是, 当一组点的一部分接近边界的时候,所得到的矩形的顶点有可能是负数,椭圆就是矩形内接椭圆

void thresh_callback(int, void* )
{
    Mat canny_output;
    Canny( src_gray, canny_output, thresh, thresh*2 );
    vector<vector<Point> > contours;
    findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );
    vector<RotatedRect> minRect( contours.size() );
    vector<RotatedRect> minEllipse( contours.size() );
    for( size_t i = 0; i < contours.size(); i++ )
    {
        minRect[i] = minAreaRect( contours[i] );
        if( contours[i].size() > 5 )
        {
            minEllipse[i] = fitEllipse( contours[i] );
        }
    }
    Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
    for( size_t i = 0; i< contours.size(); i++ )
    {
        Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );
        // contour
        drawContours( drawing, contours, (int)i, color );
        // ellipse
        ellipse( drawing, minEllipse[i], color, 2 );
        // rotated rectangle
        Point2f rect_points[4];
        minRect[i].points( rect_points );
        for ( int j = 0; j < 4; j++ )
        {
            line( drawing, rect_points[j], rect_points[(j+1)%4], color );
        }
    }
    imshow( "Contours", drawing );
}

轮廓的最小外接矩形、最小外接圆、三角形、椭圆等_第3张图片

你可能感兴趣的:(opencv)