1、概述
案例:检测图像轮廓并绘制轮廓的外界矩形和圆
相关函数介绍:
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
2、代码示例
//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);
3、示例图片
(ps:在实际自己运行的时候需要调整阈值以达到最有效果)
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓