OpenCV-轮廓周围绘制矩形框以及圆形框

步骤:

在这里插入图片描述

API:
功能:近似于曲线的或与另一曲线/多边形的多边形用更少的顶点,使得它们之间的距离是小于或等于指定的精度
approxCurve=cv.approxPolyDP(curve, epsilon, closed[, approxCurve])
在这里插入图片描述
矩形:
BoundingRect是说,用一个最小的矩形,把找到的形状包起来。还有一个带旋转的矩形,面积会更小
minAreaRect函数返回矩形的中心点坐标,长宽,旋转角度[-90,0),当矩形水平或竖直时均返回-90
在这里插入图片描述
圆:
在这里插入图片描述

#include <opencv2/opencv.hpp>
#include <iostream>
#include <opencv2/highgui/highgui_c.h>

using namespace std;
using namespace cv;

Mat src, gray_src, dst;
const char* output_title = "绘制结果";
const char* gray_title = "灰度图像";
int threshold_value = 50;
int threshold_max = 255;

void threshold_Demo(int, void*);

//在轮廓周围绘制矩形和圆形
int main(int argc, char ** argv)
{
	src = imread("E://VS-pro//images//text.bmp");
	if (!src.data)
	{
		printf("can not find .. \n");
		return -1;
	}
	imshow("原图", src);

	//变灰度
	cvtColor(src, gray_src, COLOR_BGR2GRAY);
	blur(gray_src, gray_src, Size(3, 3), Point(-1, -1));
	imshow(gray_title, gray_src);

	createTrackbar("threshold value: ", gray_title, &threshold_value, threshold_max, threshold_Demo);
	threshold_Demo(0, 0);



	waitKey(0);

	return 0;
}

void threshold_Demo(int, void*) 
{
	Mat bin_src;
	//转换为二值图像
	threshold(gray_src, bin_src, threshold_value, threshold_max, THRESH_BINARY);
	imshow("二值图像", bin_src);


	vector<vector<Point>> contours; //放轮廓点
	vector<Vec4i> hierachy;          //图像的拓扑结构
	//找轮廓
	findContours(bin_src, contours, hierachy, RETR_TREE, 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());

	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]);
		}

	}

	//绘制
	Mat drawImg;
	RNG rng(12345);
	// draw it
	drawImg = Mat::zeros(src.size(), src.type());
	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(drawImg, ploy_rects[t], color, 2, 8);
		//circle(drawImg, ccs[t], radius[t], color, 2, 8);
		if (contours_ploy[t].size() > 5) {
			ellipse(drawImg, myellipse[t], color, 1, 8);//画圆
			minRects[t].points(pts);
			for (int r = 0; r < 4; r++) {
				line(drawImg, pts[r], pts[(r + 1) % 4], color, 1, 8);//画矩形四条边
			}
		}
	}

	imshow(output_title, drawImg);

}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/just_tree/article/details/89298573