opencv学习(四十二)之多边形包围图像轮廓
来源:互联网 发布:改变 知乎 编辑:程序博客网 时间:2024/05/22 18:23
首先介绍一个逼近多边形的函数approxPolyDP(),其定义如下:
void cv::approxPolyDP ( InputArray curve, OutputArray approxCurve, double epsilon, bool closed )
函数作用是用指定精度逼近多边形曲线
curve:输入的二维点集,可以是vector类型或Mat类型
approxCurve:多边形逼近的结果,其类型与输入的点集类型一致
epsilon:逼近的精度,为原始曲线和逼近曲线间的最大值
closed:如果为true,逼近的曲线为封闭曲线,如果为false则逼近曲线不封闭
1.使用矩形和最小圆包围图像
使用boundingRect()函数计算包围轮廓的矩形框,使用minEnclosingCircle()函数计算包围轮廓的最小圆包围
boundingRect()
函数计算并返回点集最外面的矩形边界,其函数定义如下:
cv::boundingRect ( InputArray points )
minEnclosingCircle()
利用迭代算法,对给定的二维点集寻找计算可包围点集的最小圆形,其定义如下
void cv::minEnclosingCircle ( InputArray points, Point2f & center, float & radius )
参数解释:
points:输入的二维点集,数据类型为vector<>或Mat类型
center:绘制圆的圆心坐标
radius:圆的半径
示例代码
#include <iostream>#include <opencv2\core\core.hpp>#include <opencv2\highgui\highgui.hpp>#include <opencv2\imgproc\imgproc.hpp>using namespace std;using namespace cv;//定义全局变量Mat srcImage, grayImage;int thresh = 100;const int threshMaxValue = 255;RNG rng(12345);//声明回调函数void thresh_callback(int, void*);int main(){ srcImage = imread("bundingRect_1.jpg"); //判断图像是否加载成功 if (srcImage.empty()) { cout << "图像加载失败!"; return -1; } else cout << "图像加载成功!" << endl << endl; cvtColor(srcImage, grayImage, COLOR_BGR2GRAY); blur(grayImage, grayImage, Size(3, 3)); namedWindow("原图像", WINDOW_AUTOSIZE); imshow("原图像", grayImage); //创建轨迹条 createTrackbar("Thresh:", "原图像", &thresh, threshMaxValue, thresh_callback); thresh_callback(thresh, 0); waitKey(0); return 0;}void thresh_callback(int, void*){ Mat threshold_output; vector<vector<Point>>contours; vector<Vec4i>hierarchy; //图像二值化检测边缘 threshold(grayImage, threshold_output, thresh, 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 (int i = 0; i < contours.size(); i++) { approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true); boundRect[i] = boundingRect(Mat(contours_poly[i])); minEnclosingCircle((Mat)contours_poly[i], center[i], radius[i]); } //绘制检测到的图像轮廓、矩形和最小包围圆 Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3); for (int i = 0; i < contours.size(); i++) { Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); drawContours(drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point()); /*Rect类中tl表示top_left即左上角的点,br表示bottom_right即右下方的点*/ 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_AUTOSIZE); imshow("轮廓图", drawing);}
运行结果:
2.使用旋转的矩形和椭圆包围图像轮廓
minAreaRect()
cv::minAreaRect ( InputArray points )
对于输入的二维点集,计算包围点集的最小矩形
fitEllipse()
cv::fitEllipse ( InputArray points )
根据输入的二维点集使用椭圆拟合方法包围二维点集
示例代码
#include <iostream>#include <opencv2\core\core.hpp>#include <opencv2\highgui\highgui.hpp>#include <opencv2\imgproc\imgproc.hpp>using namespace std;using namespace cv;//定义全局变量Mat srcImage, grayImage;int thresh = 100;const int threshMaxValue = 255;RNG rng(12345);//声明回调函数void thresh_callback(int, void*);int main(){ srcImage = imread("bundingRect_1.jpg"); //判断图像是否加载成功 if (srcImage.empty()) { cout << "图像加载失败!"; return -1; } else cout << "图像加载成功!" << endl << endl; cvtColor(srcImage, grayImage, COLOR_BGR2GRAY); blur(grayImage, grayImage, Size(3, 3)); namedWindow("原图像", WINDOW_AUTOSIZE); imshow("原图像", grayImage); //创建轨迹条 createTrackbar("Thresh:", "原图像", &thresh, threshMaxValue, thresh_callback); thresh_callback(thresh, 0); waitKey(0); return 0;}void thresh_callback(int, void*){ Mat threshold_output; vector<vector<Point>>contours; vector<Vec4i>hierarchy; //图像二值化检测边缘 threshold(grayImage, threshold_output, thresh, 255, THRESH_BINARY); //寻找图像轮廓 findContours(threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0)); //为每个轮廓寻找旋转的矩形和椭圆 vector<RotatedRect>minRect(contours.size()); vector<RotatedRect>minEllipse(contours.size()); //如果轮廓上的点大于5个则用椭圆填充 for (int i = 0; i < contours.size(); i++) { minRect[i] = minAreaRect(Mat(contours[i])); if (contours[i].size()>5) { minEllipse[i] = fitEllipse(Mat(contours[i])); } } //绘制检测到的图像轮廓、旋转矩形和椭圆 Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3); for (int i = 0; i < contours.size(); i++) { Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); drawContours(drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point()); ellipse(drawing, minEllipse[i], color, 2, 8); //旋转矩形 Point2f rect_points[4]; minRect[i].points(rect_points); for (int j = 0; j < 4; j++) { line(drawing, rect_points[j], rect_points[(j + 1) % 4], color, 1, 8); } } namedWindow("轮廓图", WINDOW_AUTOSIZE); imshow("轮廓图", drawing);}
运行结果:
此外还有最小三角包围轮廓函数minEnclosingTriangle(),请自行查阅
5 0
- opencv学习(四十二)之多边形包围图像轮廓
- opencv学习之寻找凸包,使用多边形包围轮廓
- Opencv学习之使用多边形将轮廓包围
- OpenCV学习之图像轮廓提取
- OpenCV之imgproc 模块. 图像处理(5)在图像中寻找轮廓 计算物体的凸包 创建包围轮廓的矩形和圆形边界框 为轮廓创建可倾斜的边界框和椭圆 轮廓矩 多边形测试
- opencv之图像轮廓提取
- C# OpenCV学习笔记五之图像轮廓
- opencv学习(四十)之寻找图像轮廓findContours()
- OpenCV轮廓---多边形逼近
- opencv中使用形状包围轮廓
- 【opencv练习34 - 轮廓包围圆,矩形】
- 图像轮廓获取opencv
- opencv-图像轮廓
- OpenCV图像的轮廓
- opencv 图像轮廓
- opencv图像轮廓
- OpenCV 查找图像轮廓
- OpenCV检测图像轮廓
- Error:Cannot change dependencies of configuration ':app:_debugAnnotationProcessor' after it has been
- Ceilometr: 3、Liberty版本的Ceilometer表结构介绍
- iOS开发中,按钮不能点击的几种情况
- 从一个通用加法程序看模板
- Leetcode 3. Restore IP Addresses
- opencv学习(四十二)之多边形包围图像轮廓
- 插件化开发——替换if-else和switch
- django Rest Framework 系列3
- Educational Codeforces Round 19-E. Array Queries(简单dp)
- Mybatis逆向工程
- Latex使用小结(3)
- 汇编指令ebp与esp的关系与作用
- 读书笔记《Unix编程艺术》六
- 实现自己SpringMVC的RequestMapping