zoukankan      html  css  js  c++  java
  • 图像轮廓的最小外接矩形和圆检测绘制

     

     

     

     代码:

    #include <opencv2/opencv.hpp>
    #include <iostream>
    #include <math.h>
    
    using namespace std;
    using namespace cv;
    Mat src, gray_src, drawImg;
    int threshold_v = 170;         //阈值二值化的初始值为170
    int threshold_max = 255;       //最大值为255
    const char* output_win = "rectangle-demo";
    RNG rng(12345);
    void Contours_Callback(int, void*);
    int main(int argc, char** argv) {
        src = imread("L:/13.jpg");
        if (!src.data) {
            printf("could not load image...
    ");
            return -1;
        }
        cvtColor(src, gray_src, CV_BGR2GRAY);
        blur(gray_src, gray_src, Size(3, 3), Point(-1, -1));
    
        const char* source_win = "input image";
        namedWindow(source_win, CV_WINDOW_AUTOSIZE);
        namedWindow(output_win, CV_WINDOW_AUTOSIZE);
        imshow(source_win, src);
    
        createTrackbar("Threshold Value:", output_win, &threshold_v, threshold_max, Contours_Callback);
        //创建阈值拖动窗口,回调Contours_Callback函数
        Contours_Callback(0, 0);
    
        waitKey(0);
        return 0;
    }
    
    void Contours_Callback(int, void*) {
        Mat binary_output;                 //定义一个二值化的输出矩阵
        vector<vector<Point>> contours;    //point点集的二维数组,数组的个数和每个数的长度都是可变
        vector<Vec4i> hierachy;            //4i四维的整数,个数可变
        threshold(gray_src, binary_output, threshold_v, threshold_max, THRESH_BINARY); //二值化
        imshow("binary image", binary_output);
        findContours(binary_output, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(-1, -1));//找出轮廓
    
        vector<vector<Point>> contours_ploy(contours.size());  //定义一个输出轮廓的点集,与contours一样的
        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);
    //多边形拟合:approxPolyDP函数参数:1.图像轮廓点集  2.输出多边形点集 3.两个轮廓之间最大距离 4.是否为封闭图形
            ploy_rects[i] = boundingRect(contours_ploy[i]);
            //boundingRect函数:计算出轮廓的垂直边界最小矩形赋给ploy_rects[i]
            minEnclosingCircle(contours_ploy[i], ccs[i], radius[i]);
            //minEnclosingCircle函数参数:1.输入点集  2.输出圆心坐标 3.输出圆半径
            if (contours_ploy[i].size() > 5) {          //绘制图形时边界不能低于5个像素
                myellipse[i] = fitEllipse(contours_ploy[i]);
                minRects[i] = minAreaRect(contours_ploy[i]);
            }
        }
    
        // draw it
        drawImg = Mat::zeros(src.size(), src.type());  //定义一个src大小和类型的矩阵给drawImg
        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(drawImg, ploy_rects[t], color, 2, 8);
            //circle(drawImg, ccs[t], radius[t], color, 2, 8);
            if (contours_ploy[t].size() > 5) {
                ellipse(drawImg, myellipse[t], color, 1, 8);
                minRects[t].points(pts);
                for (int r = 0; r < 4; r++) {
                    line(drawImg, pts[r], pts[(r + 1) % 4], color, 1, 8);  
                    //找每个矩形的四个点连线,第四个点过界取模4运算回到pts[0]
                }
            }
        }
    
        imshow(output_win, drawImg);
        return;
    }

    结果:

         

     

  • 相关阅读:
    在线教育项目-day07【添加分类前端】
    在线教育项目-day07【课程分类显示接口】
    在线教育项目-day05【实现EasyExcel对Excel操作】
    在线教育项目-day05【上传头像实现】
    在线教育项目-day05【nginx】
    在线教育项目-day05【Swagger问题】
    在线教育项目-day05【上传头像功能】
    在线教育项目-day04【路由问题】
    在线教育项目-day04【后台讲师修改功能】
    在线教育项目-day04【后台讲师添加模块】
  • 原文地址:https://www.cnblogs.com/Jack-Elvis/p/11552829.html
Copyright © 2011-2022 走看看