【opencv学习之三十四】轮廓特征应用:最小外接矩形和圆

时间:2022-12-26 12:51:28

opencv轮廓特征中有外接矩形和圆,其中外接矩形又分为平行窗口矩形和不平行窗口矩形;外接圆也分为正圆和椭圆两种;基本调用方法类似,都是contours中的一个属性,调用就可获取最小特征参数;话不多说直接代码:

最小外接矩形:

void imgminRect()//轮廓最小外接矩形
{
    Mat img=imread("D:/ImageTest/convex.png");//加载图片
    Mat dst;
    cv::cvtColor(img,img,COLOR_RGB2GRAY);//进行,灰度处理
    //阈值分割
    threshold( img,                 //输入图像,原始数组 (单通道 , 8-bit of 32-bit 浮点数).
               dst,                          //输出图像,输出数组,必须与 src 的类型一致,或者为 8-bit.
               200,                           //分割值
               255,                         // 使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值.
               THRESH_BINARY_INV ); //阈值类型,opencv认为白色部分为被分割出来的部分
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(dst,contours,hierarchy,RETR_CCOMP, CHAIN_APPROX_SIMPLE,Point());//所有轮廓CV_CHAIN_APPROX_SIMPLE
    Mat drawing = Mat::zeros( img.size(), CV_8UC3 );
    vector<Rect> boundRect(contours.size());
    for( size_t i = 0; i< contours.size(); i++ )
    {
        Scalar color( (rand()&255), (rand()&255), (rand()&255) );//随机产生颜色 rand()产生随机数
        drawContours( drawing, contours, (int)i, color, 1, 8, vector<Vec4i>(), 0, Point() );
        //绘制轮廓的最小外结矩形
        RotatedRect rect=minAreaRect(contours[i]);
        Point2f P[4];
        rect.points(P);
        for(int j=0;j<=3;j++)
        {
            line(drawing,P[j],P[(j+1)%4],color,1);
        }
        boundRect[i] = boundingRect(Mat(contours[i]));//由轮廓(点集)确定出正外接矩形
        //获得正外接矩形的左上角坐标及宽高
        int width = boundRect[i].width;
        int  height = boundRect[i].height;
        int x = boundRect[i].x;
        int y = boundRect[i].y;
        //用画矩形方法绘制正外接矩形
        rectangle(drawing,Rect(x,y,width,height),Scalar(0,0,255),1,8);
    }
    imshow("srcImg", img);
    imshow("rect",drawing);
    waitKey(0);
}
效果:

【opencv学习之三十四】轮廓特征应用:最小外接矩形和圆

最小外接圆:

void imgCircle()//轮廓最小外接圆
{
    Mat img=imread("D:/ImageTest/convex.png");//加载图片
    Mat dst;
    cv::cvtColor(img,img,COLOR_RGB2GRAY);//进行,灰度处理
    //阈值分割
    threshold( img,                 //输入图像,原始数组 (单通道 , 8-bit of 32-bit 浮点数).
               dst,                          //输出图像,输出数组,必须与 src 的类型一致,或者为 8-bit.
               200,                           //分割值
               255,                         // 使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值.
               THRESH_BINARY_INV ); //阈值类型,opencv认为白色部分为被分割出来的部分
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(dst,contours,hierarchy,RETR_CCOMP, CHAIN_APPROX_SIMPLE,Point());//所有轮廓CV_CHAIN_APPROX_SIMPLE
    Mat drawing = Mat::zeros( img.size(), CV_8UC3 );
    //最小外接圆
    for( size_t i = 0; i< contours.size(); i++ )
    {
        Scalar color( (rand()&255), (rand()&255), (rand()&255) );//随机产生颜色 rand()产生随机数
        drawContours( drawing, contours, (int)i, color, 1, 8, vector<Vec4i>(), 0, Point() );
        //绘制轮廓的最小外结圆
        Point2f center; float radius;
        minEnclosingCircle(contours[i],center,radius);
        circle(drawing,center,radius,Scalar(0,0,255),2);
    }

    //最小椭圆
    vector<RotatedRect> minEllipse(contours.size());//存储椭圆点
    for (int i = 0; i < contours.size(); i++)
    {
        if (contours[i].size() > 5)//四个点确定一个椭圆
        {
            minEllipse[i] = fitEllipse(Mat(contours[i]));
        }
    }
    for (int i = 0; i< contours.size(); i++)
    {
        ellipse(drawing, minEllipse[i], Scalar(0,255,255), 1, 8);
    }
    imshow("srcImg", img);
    imshow("circle",drawing);
    waitKey(0);
}
效果:

【opencv学习之三十四】轮廓特征应用:最小外接矩形和圆