opencv学习笔记(三十一)轮廓周围绘制圆形和矩形框

1.相关API

(1)approxPolyDP(InputArray  curve, OutputArray approxCurve,  double  epsilon,  bool  closed),主要功能是把一个连续光滑曲线折线化,对图像轮廓点进行多边形拟合,减少轮廓点

curve:图像的轮廓点组成的点集

approxCurve:表示输出的多边形点集

epsilon:主要表示输出的精度,就是2个轮廓点之间最大距离数

closed:输出的多边形是否封闭

(2)矩形绘制API:cv::boundingRect(InputArray points)得到轮廓周围最小矩形左上交点坐标和右下角点坐标,绘制一个矩形。返回一个矩形RECT对象

cv::minAreaRect(InputArray  points)得到一个旋转的矩形,返回旋转矩形,返回4个点。

(3)绘制圆:cv::minEnclosingCircle(InputArray points, Point2f& center,float& radius)

center:返回的所有圆心放进容器

radius:返回的所有圆的半径放进容器

(4)绘制椭圆:cv::fitEllipse(InputArray  points)得到最小椭圆,返回一个椭圆对象

2.实现步骤

首先将图像变为二值图像

发现轮廓,找到图像轮廓

通过相关API在轮廓点上找到最小包含矩形和圆,旋转矩形与椭圆。

绘制

3.代码实现

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace std;
using namespace cv;

Mat src,srcGray ,dst;
char inputName[] = "input name";
char outputName[] = "output name";
int threshold_value = 100;
int threshold_max = 255;
RNG rng(12345);
void Contour_Demo(int, void *);
int main()
{
	src = imread("D:/VS project/Image/HotAirBalloon.jpg");
	if (src.empty())
	{
		cout << "找不到图像!" << endl;
		return -1;
	}
	namedWindow(inputName, CV_WINDOW_AUTOSIZE);
	namedWindow(outputName, CV_WINDOW_AUTOSIZE);
	imshow(inputName, src);
	cvtColor(src, srcGray, CV_BGR2GRAY);
	blur(srcGray, srcGray, Size(3, 3), Point(-1, -1));

	createTrackbar("Threshold Value", outputName, &threshold_value, threshold_max, Contour_Demo);
	Contour_Demo(0, 0);
	waitKey(0);
	return 0;
}
void Contour_Demo(int, void *)
{
	Mat binary_output;
	vector<vector<Point>> points;
	vector<Vec4i> hierachy;
	//threshold(srcGray, binary_output, threshold_value, 255, THRESH_BINARY);
	Canny(src, binary_output, threshold_value, threshold_value * 2, 3, false);
	imshow("1", binary_output);
	//找轮廓点
	findContours(binary_output, points, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));

	vector<vector<Point>> poly_points(points.size());//存放RDP处理后的轮廓点数
	vector<Rect>poly_rect(points.size());//存放Rect矩形对象
	vector<Point2f> cc(points.size());//存放圆心
	vector<float> radius(points.size());//存放半径

	vector<RotatedRect>min_rect(points.size());
	vector<RotatedRect>min_ellipse(points.size());

	for (size_t i = 0; i < points.size(); i++)
	{
		approxPolyDP(points[i], poly_points[i], 3, true);
		poly_rect[i] = boundingRect(poly_points[i]);
		minEnclosingCircle(poly_points[i], cc[i], radius[i]);//调用API存放圆心,半径

		min_rect[i] = minAreaRect(poly_points[i]);//返回4个点
		if (poly_points[i].size()>5)
		{
			min_ellipse[i] = fitEllipse(poly_points[i]);
		}
	}

	//绘制
	src.copyTo(dst);
	for (size_t i = 0; i < points.size(); i++)
	{
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
		rectangle(dst, poly_rect[i], color, 2, 8);
		circle(dst, cc[i], radius[i], color, 2, 8);
		ellipse(dst, min_ellipse[i], color, 2, 8);
		//旋转矩形
		Point2f rect_point[4];
		min_rect[i].points(rect_point);
		for (size_t i = 0; i < 4; i++)
		{
			line(dst, rect_point[i], rect_point[(i + 1) % 4], color, 2, 8);
		}

	}
	imshow(outputName, dst);

}

4.运行结果

发布了53 篇原创文章 · 获赞 9 · 访问量 3270

猜你喜欢

转载自blog.csdn.net/weixin_41039168/article/details/97104763