opencv学习(二十四)圆/矩形/多边形逼近并画轮廓minEnclosingCircle()&Circle()/boundRect[i]&rectangle()/approxPolyDP()&画轮廓

  • Post author:
  • Post category:其他


多边形/矩形/圆将轮廓包围

1,

minEnclosingCircle()&Circle()

2,

boundRect[i]=boundRect()&rectangle()

3,

minEnclosingCircle()&Circle()

这里写图片描述

这里写图片描述


1,圆/矩形/凸包分别画出轮廓例子


#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main()
{
    //初始化变量和随机值
    Mat image(600, 600, CV_8UC3);
    RNG&rng = theRNG();

    //循环
    while (1)
    {
        char key;//键值
        //参数初始化
        int count = (unsigned)rng % 100 + 3;//随机生成点数量
        vector<Point> points;//点值

                             //随机生成坐标
        for (int i = 0; i < count; i++)
        {
            Point point;
            point.x = rng.uniform(image.cols / 4, image.cols * 3 / 4);
            point.y = rng.uniform(image.rows / 4, image.rows * 3 / 4);//注意X,y分别赋值

            points.push_back(point);

        }

        /*【1】凸包操作
        //检测凸包
        vector<int>hull;
        convexHull(Mat(points), hull, true);
        */

        /*【2】矩形包围操作
        //对于给定2D点,寻找最小面积的包围矩形
        RotatedRect box = minAreaRect(Mat(points));
        Point2f vertex[4];
        box.points(vertex);//把找到的点赋予vertex?
        */

        //【3】圆形包围操作
        //对于给定2D点,寻找最小面积的包围圆
        Point2f center;
        float radius = 0;
        minEnclosingCircle(Mat(points), center, radius);


        //绘制出随机颜色点
        image = Scalar::all(0);

        for (int i = 0; i < count; i++)//for后面不需要分号
        {
            circle(image, points[i], 3, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), FILLED, LINE_AA);
        }


        /*【1】凸包操作
        //准备参数
        int hullcount = (int)hull.size();
        Point point0 = points[hull[hullcount - 1]];//连接凸包边的坐标点
        */

        /*//绘凸包的边
        for (int i = 0; i < hullcount; i++)
        {
            Point point = points[hull[i]];
            line(image, point0, point, Scalar(255, 255, 255), 2, LINE_AA);
            point0 = point;

        }
        imshow("凸包检测实例", image);
        */

        /*【2】矩形包围操作
        //绘制出最小面积的包围矩形
        for (int i = 0; i < 4; i++)
            line(image, vertex[i], vertex[(i + 1) % 4], Scalar(100, 200, 211), 2, LINE_AA);
        imshow("矩形包围", image);
        */

        ///*【3】圆包围操作
        //绘制出最小面积的包围矩形
        circle(image, center, cvRound(radius), Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, LINE_AA);
        imshow("圆包围", image);

        //按下ESC或q退出
        key = (char)waitKey();
        if (key == 27 || key == 'q' || key == 'Q')
            break;
    }
    return 0;
}


2,圆/矩形/多边形同时画出轮廓




//---------------------------------【头文件、命名空间包含部分】----------------------------
//      描述:包含程序所使用的头文件和命名空间
//------------------------------------------------------------------------------------------------
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;

//-----------------------------------【宏定义部分】-------------------------------------------- 
//  描述:定义一些辅助宏 
//------------------------------------------------------------------------------------------------ 
#define WINDOW_NAME1 "【原始图窗口】"        //为窗口标题定义的宏 
#define WINDOW_NAME2 "【效果图窗口】"        //为窗口标题定义的宏 

//-----------------------------------【全局变量声明部分】--------------------------------------
//  描述:全局变量的声明
//-----------------------------------------------------------------------------------------------
Mat g_srcImage;
Mat g_grayImage;
int g_nThresh = 50;//阈值
int g_nMaxThresh = 255;//阈值最大值
RNG g_rng(12345);//随机数生成器

                 //-----------------------------------【全局函数声明部分】--------------------------------------
                 //   描述:全局函数的声明
                 //-----------------------------------------------------------------------------------------------
void on_ContoursChange(int, void*);
static void ShowHelpText();

//-----------------------------------【main( )函数】--------------------------------------------
//   描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main()
{
    //【0】改变console字体颜色
    system("color 1F");


    //【1】载入3通道的原图像
    g_srcImage = imread("D://1.jpg", 1);
    if (!g_srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }

    //【2】得到原图的灰度图像并进行平滑
    cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
    blur(g_grayImage, g_grayImage, Size(3, 3));

    //【3】创建原始图窗口并显示
    namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
    imshow(WINDOW_NAME1, g_srcImage);

    //【4】设置滚动条并调用一次回调函数
    createTrackbar(" 阈值:", WINDOW_NAME1, &g_nThresh, g_nMaxThresh, on_ContoursChange);
    on_ContoursChange(0, 0);

    waitKey(0);

    return(0);
}

//----------------------------【on_ContoursChange( )函数】---------------------------------
//      描述:回调函数
//-------------------------------------------------------------------------------------------------  
void on_ContoursChange(int, void*)
{
    //定义一些参数
    Mat threshold_output;
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;

    // 使用Threshold检测边缘
    threshold(g_grayImage, threshold_output, g_nThresh, 255, THRESH_BINARY);

    // 找出轮廓
    findContours(threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));

    // 多边形逼近轮廓 + 获取矩形和圆形边界框
    vector<vector<Point> > contours_poly(contours.size());
    vector<Rect> boundRect(contours.size());
    vector<Point2f>center(contours.size());
    vector<float>radius(contours.size());

    //一个循环,遍历所有部分,进行本程序最核心的操作
    for (unsigned int i = 0; i < contours.size(); i++)
    {
        approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true);//用指定精度逼近多边形曲线 
        boundRect[i] = boundingRect(Mat(contours_poly[i]));//计算点集的最外面(up-right)矩形边界
        minEnclosingCircle(contours_poly[i], center[i], radius[i]);//对给定的 2D点集,寻找最小面积的包围圆形 
    }

    // 绘制多边形轮廓 + 包围的矩形框 + 圆形框
    Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3);
    for (int unsigned i = 0; i<contours.size(); i++)
    {
        Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));//随机设置颜色
        drawContours(drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point());//绘制轮廓
        rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0);//绘制矩形
        circle(drawing, center[i], (int)radius[i], color, 2, 8, 0);//绘制圆
    }

    // 显示效果图窗口
    namedWindow(WINDOW_NAME2, WINDOW_AUTOSIZE);
    imshow(WINDOW_NAME2, drawing);
}



这里写图片描述



版权声明:本文为qq_41553038原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。