OpenCv-C++下的轮廓周围绘制矩形框和圆形框
目前我正在学习OpenCv下的轮廓周围绘制矩形框和圆形框,将个人学习记录放到这里。
参考链接:https://blog.****.net/lanyuelvyun/article/details/76614872
https://blog.****.net/qq_31647835/article/details/81055711
下面介绍几个相关函数:
findContours():不用说了,找到图像的轮廓点
approxPolyDP():减少轮廓点集里的个数
boundingRect():得到包覆此轮廓的最小正矩形
minEnclosingCircle():最小包围圆形
minAreaRect():带旋转的矩形
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace cv;
using namespace std;
Mat src, dst, gray_src;
void polyPD(int, void*);
int threshold_value = 100;
int threshold_max = 255;
int main(int argc, char** argv)
{
src = imread("D:/test/hot-ball.png");
if (!src.data)
{
cout << "图片未找到" << endl;
return -1;
}
cvtColor(src, gray_src, CV_BGR2GRAY);
namedWindow("output title", CV_WINDOW_AUTOSIZE);
createTrackbar("Move", "output title", &threshold_value, threshold_max, polyPD);
polyPD(0, 0);
imshow("input title", src);
waitKey(0);
return 0;
}
void polyPD(int, void *)
{
Mat bin_out;
vector<vector<Point>> contours;//定义图像轮廓点集
vector<Vec4i> hieracy;
//二值化操作
threshold(gray_src, bin_out, threshold_value, threshold_max, THRESH_BINARY);
//找到图像轮廓点
findContours(bin_out, contours, hieracy, RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(-1, -1));
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());
dst = Mat::zeros(src.size(), src.type());
RNG rng(12345);
for (size_t i = 0; i < contours.size(); i++)
{//对图像轮廓点进行多边形拟合
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
//绘制热气球轮廓
//drawContours(dst, contours,(int)i, color,1,8,hieracy,0,Point(-1,-1));
approxPolyDP(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]; //画直线需要4个点
for (size_t k = 0; k < contours.size(); k++)
{
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
//rectangle(drawImg, ploy_rects[t], color, 2, 8);
//circle(drawImg, ccs[t], radius[t], color, 2, 8);
if (contours_ploy[k].size() > 5) {
ellipse(dst,myellipse[k], color, 1, 8);//绘制椭圆
minRects[k].points(pts);
for (int r = 0; r < 4; r++) {
line(dst,pts[r], pts[(r + 1) % 4], color, 1, 8);
}
}
}
imshow("output title", dst);
return;
}
/*
approxPolyDP():
InputArray curve:一般是由图像的轮廓点组成的点集
OutputArray approxCurve:表示输出的多边形点集
double epsilon:主要表示输出的精度,就是两个轮廓点之间的最大距离数,5,6,7...
bool closed:表示输出的多边形是否封闭
*/
/*THRESH_TRIANGLE,THRESH_OTSU,自动寻找阈值
不清楚阈值使用哪些数字时,可以THRESH_OTSU||THRESH_BINARY这样写;
vector<Point2f> 圆心;
*/
/*
当得到对象的轮廓后,可用boundingRect()得到包覆此轮廓的最小正矩形boundingRect();
带旋转的矩形minAreaRect();
最小包围圆形 minEnclosingCircle()
*/
代码运行结果:
输入图片:
二值化后绘制的轮廓: