概述
步骤:先将图像转为灰度,然后进行Canny边缘检测,然后找到轮廓,得到二值边缘图像。轮廓由一系列点组成。要获得轮廓的最小外矩形,必须首先获得轮廓的近似多边形。使用 Douglas-Puck 细化 (DP) 算法和 Douglas-Puck 细化算法。它是一种将曲线近似为一系列点并减少点数的算法。
该算法的细化过程如下:
1)虚构连接一条直线到曲线的首末点,求出曲线上各点与直线的距离,求出最大距离值dmax。将 Dmax 与预先给定的阈值 D 进行比较:
2) 如果 Dmax < D,则曲线上的所有中间点将被删除;则将直线段视为曲线的近似,对曲线进行处理。
如果Dmax大于等于D,则保留Dmax对应的坐标点,以该点为边界将曲线分成两部分。对这两部分重复该方法,即重复1、2步,直到所有的Dmax都<D,即完成曲线细化。
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int value = 60;
RNG rng(1);
Mat src,gray_img,canny_img,dst;
void callback(int, void*);
int main(int arc, char** argv){
src = imread("2.jpg");
namedWindow("input",CV_WINDOW_AUTOSIZE);
imshow("input", src);
cvtColor(src, gray_img, CV_BGR2GRAY);
namedWindow("output", CV_WINDOW_AUTOSIZE);
createTrackbar("threshold", "output", &value, 255, callback);
callback(0, 0);
waitKey(0);
return 0;
}
void callback(int, void*) {
Canny(gray_img, canny_img, value, 2 * value);
vector<vector<Point>>contours;
vector<Vec4i> hierarchy;
findContours(canny_img, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
vector<vector<Point>> contours_poly(contours.size());
vector<Rect>poly_rects(contours.size());
vector<Point2f>ccs(contours.size());
vector<float>radius(contours.size());
vector<RotatedRect> minRects(contours.size());
vector<RotatedRect> myellipse(contours.size());
for (int i = 0; i < contours.size(); i++) {
ApproxPolyDP (contours [i], contours_poly [i], 20, true); // Get approximate polygons with fewer points
Poly_rects [i] = boundingRect (contours_poly [i]); //Get the smallest outer rectangle from an approximate polygon
MinEnclosing Circle (contours_poly[i], ccs[i], radius [i]); //Get the minimum circumscribed circle from an approximate polygon
// The minimum rectangle and ellipse with direction can be drawn only when the number of polygon points is more than 5.
if (contours_poly[i].size() > 5) {
MinRects [i] = minAreaRect (contours_poly [i]); //Get the smallest outer rectangle with direction from an approximate polygon
Myellipse [i] = fitEllipse (contours_poly [i]); // Obtain minimal circumscribed ellipse with direction from approximate polygon
}
}
// Drawing
src.copyTo(dst);
Point2f pts[4];
for (int j = 0; j < contours.size(); j++) {
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
rectangle(dst, poly_rects[j], color, 2,8);
circle(dst, ccs[j], (int)radius[j], color, 2,8);
// Drawing带方向的最小外接矩形和椭圆
if (contours_poly[j].size() > 5) {
ellipse(dst, myellipse[j], color, 2);
minRects[j].points(pts);
for (int k = 0; k < 4; k++) {
line(dst, pts[k], pts[(k + 1)%4], color, 2);
}
}
}
imshow("output", dst);
}
最后
以上就是靓丽信封为你收集整理的opencv实现最小外接矩形和圆的全部内容,希望文章能够帮你解决opencv实现最小外接矩形和圆所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复