实现顺序
彩色图转灰度图
滤波处理(高斯滤波/均值滤波)
二值化处理
发现轮廓,找到图形轮廓
通过api在轮廓点上找到最小包含矩形和圆,旋转矩形与椭圆
进行绘制
RDP算法API
approxPolyDP
InputArray curve 输入点集
OutputArray approxCurve 输出点集
double epsilon 点之间的步长
bool closed 形成的多边形是不是闭合曲线
轮廓周围绘制矩形
cv::boundingRect(InputArray points) 绘制最小矩形
cv::minAreaRect(InputArray points) 得到旋转矩形
cv::minEnclosingCircle() 得到最小圆形区域
InputArray points 最小圆点集
Point2f& center 圆心位置
float& radius 圆的半径
cv::fitEllipse()
InputArray points得到最小椭圆
#include"pch.h" #include<iostream> #include<math.h> #include<opencv2/opencv.hpp> using namespace std; using namespace cv; Mat gray_pic; Mat src, dst; int threshold_value = 170; int threshold_max = 255; void Contours(int, void*); int main(int argc, char**argv) { src = imread("2.jpg"); namedWindow("output window", CV_WINDOW_AUTOSIZE); imshow("input window", src); cvtColor(src, gray_pic, COLOR_BGR2GRAY); blur(gray_pic, gray_pic, Size(3, 3), Point(-1, -1)); createTrackbar("Threshold value", "output window", &threshold_value, threshold_max, Contours); Contours(0, 0); waitKey(0); return 0; } void Contours(int, void*) { Mat binary_output; vector<vector<Point>> points; vector<Vec4i>hierachy; threshold(gray_pic, binary_output, threshold_value, threshold_max, THRESH_BINARY); findContours(binary_output, points, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(-1,-1)); imshow("binray", binary_output); vector<vector<Point>> contours_ploy(points.size()); vector<Rect> ploy_Rect(points.size());//矩形 vector<Point2f>ccs(points.size());//圆心 vector<float>radius(points.size());//半径 vector<RotatedRect> minRects(points.size());//旋转矩形 vector<RotatedRect> myellipse(points.size());//旋转椭圆 for (size_t i = 0; i < contours_ploy.size(); ++i) { approxPolyDP(Mat(points[i]), contours_ploy[i], 3, true); ploy_Rect[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]); } } src.copyTo(dst); Point2f pts[4]; //================================================================ //矩形 /* for (size_t t = 0; t < points.size(); ++t) { rectangle(src, ploy_Rect[t], Scalar(0, 0, 255),2, 8); //circle(src, ccs[t], radius[t], Scalar(0, 255, 0), 2, 8); } //imshow("output img", dst); imshow("output window", dst); */ //==================================================================== //圆形 /* for (size_t t = 0; t < points.size(); ++t) { //rectangle(src, ploy_Rect[t], Scalar(0, 0, 255), 2, 8); circle(src, ccs[t], radius[t], Scalar(0, 255, 0), 2, 8); } //imshow("output img", dst); imshow("output window", dst); */ //========================================= //使用API绘制 for (size_t t = 0; t < points.size(); ++t) { if (contours_ploy[t].size() > 5) { ellipse(src, myellipse[t], Scalar(0, 0, 255), 1, 8); minRects[t].points(pts); for (int r = 0; r < 4; ++r) { line(src, pts[r], pts[(r + 1) % 4], Scalar(0, 255, 0), 1, 8); } } } //imshow("output img", dst); imshow("output window", dst); }
注意vector不给size会报错