我是靠谱客的博主 失眠芒果,这篇文章主要介绍opencv之轮廓周围绘制矩形框和圆形框,现在分享给大家,希望可以做个参考。

轮廓周围绘制矩形框和圆形框

在图片轮廓之外,绘制标准矩形或圆形进行标注


相关函数API

多边拟合函数API

复制代码
1
2
3
4
5
void approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed)

函数功能

基于RDP算法实现,目的是减少多边形轮廓的点数,加快运算效率,对图像轮廓点拟合多边形;
该函数用另一条曲线或具有较少顶点的多边形逼近曲线或多边形,使它们之间的距离小于或等于指定的精度;

参数介绍

  • 第一个参数,InputArray curve,一般是由图像的轮廓点组成的点集;
  • 第二个参数,OutputArray approxCurve,表示输出的多边形点集;
  • 第一个参数,double epsilon,主要表示输出的精度;这是原始曲线与其近似之间的最大距离;
  • 第二个参数,bool closed,表示输出的多边形是否封闭;true表示封闭,false表示不封闭;

boundingRect函数API
Rect boundingRect( InputArray array );
函数功能
得到轮廓周围最小矩形左上角坐标和右下角点坐标,绘制一个矩形
参数介绍

  • 第一个参数,InputArray array,一般为findContours函数查找的轮廓,包含轮廓的点集或者Mat
  • 返回值,Rect,返回值为最小外接矩形的Rect,即左上点与矩形的宽度和高度;

minAreaRect函数API
RotatedRect minAreaRect(InputArray points)
函数功能
主要求得包含点集最小面积的矩形,,这个矩形是可以有偏转角度的,可以与图像的边界不平行
参数介绍

  • InputArray points:表示输入的点集,一般为findContours函数查找的轮廓,包含轮廓的点集或者Mat
  • 返回值RotatedRect输出是矩形的四个点坐标

minEnclosingCircle函数API

复制代码
1
2
3
4
5
6
void cv::minEnclosingCircle( InputArray _points, Point2f& center, float& radius )

函数功能
求最小包围圆
参数介绍

  • 第一个参数InputArray _points,轮廓点集
  • 第二个参数Point2f& center,圆的中心坐标
  • 第三个参数float& radius,圆的半径

fitEllipse函数API
RotatedRect fitEllipse(InputArray points)
函数功能

参数介绍

  • 参数:InputArray 类型二维点集,要求拟合的点至少为6个点。存储在std::vector<> or Mat
    处理:该函数使用的是最小二乘的方法进行拟合的。参考论文:《Direct least square fitting of ellipses》
  • 返回值:RotatedRect 类型的矩形,是拟合出椭圆的最小外接矩形。

图像处理步骤

  • 首先将图像变为二值图(阈值操作、边缘处理等均可)
  • 发现轮廓,找到图像轮廓
  • 通过相关API在轮廓点上找到最小包含矩形和圆,旋转矩形与椭圆
  • 绘制它们

代码演示

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <opencv2/opencv.hpp> #include <iostream> #include <math.h> #define PIC_PATH "C:\pic\" #define PIC_NAME "2.jpg" using namespace cv; using namespace std; Mat src, gray_src,dst; int threshold_value = 200; int threshold_max = 255; void Draw_Demo(int, void*); int main(void) { string pic = string(PIC_PATH) + string(PIC_NAME); cout << "原始图片为:" << pic << endl; src = imread(pic); if (src.empty()) { cout << "图片不存在" << endl; return -1; } namedWindow("原始图片", WINDOW_AUTOSIZE); imshow("原始图片", src); cvtColor(src, gray_src, CV_BGR2GRAY); //图片转化为灰度图 namedWindow("灰度图片", WINDOW_AUTOSIZE); imshow("灰度图片", gray_src); //均值模糊去除噪点干扰 blur(gray_src, gray_src, Size(3, 3), Point(-1, -1)); namedWindow("绘制图片", WINDOW_AUTOSIZE); namedWindow("阈值操作", WINDOW_AUTOSIZE); //创建滑动条 用来动态调整阈值范围 createTrackbar("阈值调整", "阈值操作", &threshold_value, threshold_max, Draw_Demo); Draw_Demo(0, 0); //什么也不做 保证回调函数 程序一运行就显示 waitKey(0); cvDestroyAllWindows(); } void Draw_Demo(int, void*) { Mat threshold_dst; threshold(gray_src, threshold_dst, threshold_value, threshold_max, CV_THRESH_BINARY); imshow("阈值操作", threshold_dst); vector<vector<Point>> contours_points; vector<Vec4i> hierarchy; findContours(threshold_dst, contours_points, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); //namedWindow("轮廓图片", WINDOW_AUTOSIZE); vector<vector<Point>> contours_ploy(contours_points.size()); //定义精简过后的轮廓点集合 vector<Rect> ploy_rects(contours_points.size()); //定义矩形集合 vector<Point2f> ccs(contours_points.size()); //定义圆心坐标集合 vector<float> radius(contours_points.size()); //定义半径集合 vector<RotatedRect> rotated_rect(contours_points.size()); //定义最小矩形集合 带旋转角度的 vector<RotatedRect> cir_rotated_rect(contours_points.size()); //定义椭圆所在最小矩形 带旋转角度 for (size_t i = 0; i < contours_points.size(); i++) { approxPolyDP(contours_points[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) //这两个函数对输入参数点的数量有要求 这里需要预处理 { rotated_rect[i] = minAreaRect(contours_ploy[i]); //获取最小矩形集合 cir_rotated_rect[i] = fitEllipse(contours_ploy[i]); //获取最小椭圆所在矩形集合 } } src.copyTo(dst); //复制图片 RNG rng(123456); //定义随机数 Point2f p[4]; //四个角的坐标集合 for (size_t j = 0; j < contours_points.size(); j++) { Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); //随机颜色 rectangle(dst, ploy_rects[j], color, 2, 8); //绘制平行边界的矩形 circle(dst, ccs[j], radius[j], color, 2, 8); //绘制圆形 if (contours_ploy[j].size() > 5) { rotated_rect[j].points(p); //返回四个角的列表 ellipse(dst, cir_rotated_rect[j], color, 2, 8); //绘制椭圆 for(int k=0;k<4;k++) line(dst, p[k], p[(k + 1) % 4], color, 2, 8); //绘制带角度的最小的矩形 (k+1)%4防止数组越界 } } imshow("绘制图片", dst); }

程序执行效果

在这里插入图片描述

最后

以上就是失眠芒果最近收集整理的关于opencv之轮廓周围绘制矩形框和圆形框的全部内容,更多相关opencv之轮廓周围绘制矩形框和圆形框内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部