OpenCV绘制轮廓的外接矩形、圆

一、概述

  案例:检测图像轮廓并绘制轮廓的外界矩形和圆

  相关函数介绍:

approxPolyDP(contourMat, approxCurve, 10, true);//找出轮廓的多边形拟合曲线
第一个参数 InputArray curve:输入的点集
第二个参数OutputArray approxCurve:输出的点集,当前点集是能最小包容指定点集的。画出来即是一个多边形。
第三个参数double epsilon:指定的精度,也即是原始曲线与近似曲线之间的最大距离。
第四个参数bool closed:若为true,则说明近似曲线是闭合的;反之,若为false,则断开
boundingRect(InputArray points)得到轮廓周围最小矩形左上交点坐标和右下角点坐标,绘制一个矩形
minAreaRect(InputArray  points)得到一个旋转的矩形,返回旋转矩形
minEnclosingCircle(InputArray points, //得到最小区域圆形
    Point2f& center, // 圆心位置
    float& radius)// 圆的半径
fitEllipse(InputArray  points)得到最小椭圆  

  操作步骤:

  1.加载图像

  2.转灰度图像

  3.二值化图像

  4.发现轮廓

  5.准备轮廓数据approxPolyDP、boundingRect、minEnclosingCircle、fitEllipse、minAreaRect

  6.绘制轮廓rectangle、circle

二、代码示例

//1.载入图像
    Mat src  = imread(filePath);
    if(src.empty()){
        return;
    }
    Mat src_clone = src.clone();
    imshow("src",src);
    //转灰度图图像
    Mat gray;
    cvtColor(src,gray,COLOR_BGR2GRAY);
    //均值滤波轻微去噪声
    blur(gray,gray,Size(3,3),Point(-1,-1));
    //    imshow("gray",gray);
    //图像二值化
    threshold(gray,gray,100,200,THRESH_BINARY);
    //    imshow("threshold",gray);
    //发现轮廓
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(gray,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point(0,0));
    RNG rng(123456);
    //准备数据
    vector<vector<Point>> contours_ploy(contours.size());
    vector<Rect> ploy_rects(contours.size());
    vector<Point2f> ccs(contours.size());
    vector<float> radius(contours.size());
    vector<RotatedRect> minRects(contours.size());
    vector<RotatedRect> myellipse(contours.size());
    for(size_t i =0;i<contours.size();i++){
        approxPolyDP(Mat(contours[i]),contours_ploy[i],3,true);
        ploy_rects[i] = boundingRect(contours_ploy[i]);
        minEnclosingCircle(contours_ploy[i],ccs[i],radius[i]);
        if(contours_ploy[i].size()>5){
            myellipse[i] = fitEllipse(contours_ploy[i]);
            minRects[i] = minAreaRect(contours_ploy[i]);
        }
    }
    //绘制轮廓外界图形
    Point2f pts[4];
    for(size_t t =0;t<contours.size();t++){
        Scalar color = Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255));
        rectangle(src_clone,ploy_rects[t],color,2,LINE_4);
        circle(src_clone,ccs[t],radius[t],color,2,LINE_4);
        //        if (contours_ploy[t].size() > 5) {
        //                    ellipse(src_clone, myellipse[t], color, 1, 8);
        //                    minRects[t].points(pts);
        //                    for (int r = 0; r < 4; r++) {
        //                        line(src_clone, pts[r], pts[(r + 1) % 4], color, 1, 8);
        //                    }
        //                }
    }
    imshow("src_clone",src_clone);

 

三、示例图片(ps:在实际自己运行的时候需要调整阈值以达到最有效果)

 

posted on 2022-03-03 10:39  飘杨......  阅读(827)  评论(0编辑  收藏  举报