OpenCv-C++下的轮廓周围绘制矩形框和圆形框

目前我正在学习OpenCv下的轮廓周围绘制矩形框和圆形框,将个人学习记录放到这里。

参考链接:https://blog.csdn.net/lanyuelvyun/article/details/76614872
https://blog.csdn.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()

*/

代码运行结果:
输入图片:
在这里插入图片描述
二值化后绘制的轮廓:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Daker_Huang/article/details/83826674