【OpenCV学习笔记】二十九、轮廓特征属性及应用(六)——外接圆等

轮廓特征属性及应用(六)

1.轮廓最小外接圆——minEnclosingCircle()

2.轮廓的椭圆拟合——fitEllipse()

3.轮廓的多边形逼近——approxPolyDP()

4.计算轮廓面积——contourArea();计算轮廓长度——arcLength()

5.提取不规则轮廓 

先上ppt:

代码:1.轮廓最小外接圆

///轮廓最小外接圆
#include "opencv2/opencv.hpp"
using namespace cv;
#include <iostream>
using namespace std;
int main()
{
	//1.查找轮廓的预处理
	Mat srcImg = imread("10.png",CV_LOAD_IMAGE_COLOR);
	Mat copyImg = srcImg.clone();
	cvtColor(srcImg,srcImg,CV_BGR2GRAY);
	threshold(srcImg,srcImg,100,255,CV_THRESH_BINARY);
	imshow("threshold",srcImg);
	//2.查找轮廓并绘制所有轮廓
	vector < vector<Point> > contours;
	findContours(srcImg,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);//最外层轮廓
	drawContours(copyImg,contours,-1,Scalar(0,0,255),2,8);
	//3.查找最小外接圆
	Point2f center;//存储最小外接圆的圆心
	float radius;//存储最小外接圆的半径
	for (int i = 0; i < contours.size();i++)//遍历每个轮廓
	{
	minEnclosingCircle(contours[i],center,radius);//查找最小外接圆
	circle(copyImg,center,radius,Scalar(255,0,0),2,8);//用circle方法绘制最小外接圆
	}
	imshow("minEnclosingCircle", copyImg);
	waitKey(0);
	return 0;
}

运行结果:

代码:2.轮廓的椭圆拟合

///轮廓的椭圆拟合
#include "opencv2/opencv.hpp"
using namespace cv;
#include <iostream>
using namespace std;
int main()
{
	//1.查找轮廓的预处理
	Mat srcImg = imread("10.png", CV_LOAD_IMAGE_COLOR);
	Mat copyImg = srcImg.clone();
	cvtColor(srcImg, srcImg, CV_BGR2GRAY);
	threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY);
	imshow("threshold", srcImg);
	//2.查找轮廓并绘制所有轮廓
	vector < vector<Point> > contours;
	findContours(srcImg, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);//最外层轮廓
	drawContours(copyImg, contours, -1, Scalar(0, 0, 255), 2, 8);
	//3.进行轮廓的椭圆拟合
	RotatedRect roRect;//旋转矩形变量,来接收椭圆拟合函数的返回值
	for (int i = 0; i < contours.size(); i++)//遍历每个轮廓
	{
		roRect=fitEllipse(contours[i]);//进行椭圆拟合
		ellipse(copyImg,roRect,Scalar(255,0,0),2,8);//用ellipse()方法绘制椭圆,可用旋转矩形直接绘制
	}
	imshow("fitEllipse", copyImg);
	waitKey(0);
	return 0;
}

运行结果:

代码:3.轮廓的多边形逼近

///轮廓的多边形逼近
#include "opencv2/opencv.hpp"
using namespace cv;
#include <iostream>
using namespace std;
int main()
{
	//1.查找轮廓的预处理
	Mat srcImg = imread("02.jpg", CV_LOAD_IMAGE_COLOR);
	Mat copyImg = srcImg.clone();
	cvtColor(srcImg, srcImg, CV_BGR2GRAY);
	threshold(srcImg, srcImg, 200, 255, CV_THRESH_BINARY_INV);
	imshow("threshold", srcImg);
	//2.查找轮廓并绘制所有轮廓
	vector < vector<Point> > contours;
	findContours(srcImg, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);//所有轮廓
	drawContours(copyImg, contours, -1, Scalar(0, 0, 255), 2, 8);
	//3.进行轮廓的多边形逼近
	vector<vector<Point>> approxCurve(contours.size());//存储轮廓的多边形逼近的结果
	Mat drawImg(srcImg.size(), CV_8UC3, Scalar(0,0,0));//定义一个纯黑的图像,来画上轮廓的多边形逼近
	for (int i = 0; i < contours.size(); i++)//遍历每个轮廓
	{
		approxPolyDP(contours[i],approxCurve[i],4,true);//轮廓的多边形逼近
		drawContours(drawImg, approxCurve, i, Scalar(0, 0, 255), 2, 8);//在drawImg上绘制轮廓的多边形逼近
	}
	imshow("approxPolyDP", drawImg);
	waitKey(0);
	return 0;
}

运行结果:

代码:4.计算轮廓面积和长度

///计算轮廓面积和长度
#include "opencv2/opencv.hpp"
using namespace cv;
#include <iostream>
using namespace std;
int main()
{
	//1.查找轮廓的预处理
	Mat srcImg = imread("10.png", CV_LOAD_IMAGE_COLOR);
	Mat copyImg = srcImg.clone();
	cvtColor(srcImg, srcImg, CV_BGR2GRAY);
	threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY);//确保黑中找白
	imshow("threshold", srcImg);
	//2.查找轮廓并绘制所有轮廓
	vector < vector<Point> > contours;
	findContours(srcImg, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);//最外层轮廓
	drawContours(copyImg, contours, -1, Scalar(0, 0, 255), 2, 8);
	//3.输出每个轮廓的面积和长度
	double area;
	double length;
	for (int i = 0; i < contours.size(); i++)//遍历每个轮廓
	{
		area = contourArea(contours[i]);//计算轮廓面积
		length = arcLength(contours[i],true);//计算曲线或轮廓的周长,当bool变量closed为true时计算轮廓周长
		cout << "contour: " << i << " area: " << area << " perimeter: " << length << endl;
	}
	imshow("contours", copyImg);
	waitKey(0);
	return 0;
}

运行结果:

代码:5.提取不规则轮廓

///提取不规则轮廓
#include "opencv2/opencv.hpp"
using namespace cv;
#include <iostream>
using namespace std;
int main()
{
	//1.查找轮廓的预处理
	Mat srcImg = imread("220.jpg", CV_LOAD_IMAGE_COLOR);
	Mat copyImg = srcImg.clone();
	GaussianBlur(srcImg,srcImg,Size(5,5),0,0);//高斯滤波,滤去噪声
	cvtColor(srcImg, srcImg, CV_BGR2GRAY);
	threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY_INV);//确保黑中找白
	imshow("threshold", srcImg);
	//2.查找轮廓
	vector < vector<Point> > contours;
	findContours(srcImg, contours, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);//所有轮廓
	//3.遍历轮廓,找出正外接矩形
	Mat mask = Mat::zeros(srcImg.size(),CV_8UC3);//同原图一样大小,纯黑的mask图像
	Mat draw = Mat::zeros(srcImg.size(), CV_8UC3);//将原图copyTo到draw上,加上mask操作
	Mat temp = Mat::zeros(srcImg.size(), CV_8UC3);//每次循环,重置mask和draw
	Rect boundRect;//存储轮廓的正外接矩形
	for (int i = 0; i < contours.size(); i++)//遍历每个轮廓
	{
		temp.copyTo(mask);//重置mask
		temp.copyTo(draw);//重置draw
		drawContours(mask,contours,i,Scalar(255,255,255),-1);//在mask上用白色绘制轮廓,-1向内填充
		imshow("mask",mask);
		cvWaitKey(0);//等待按键
		boundRect=boundingRect(contours[i]);//获得第i个轮廓的正外接矩形
		copyImg.copyTo(draw,mask);//将原图copyTo到draw上,加上mask操作
		imshow("draw", draw);
		Mat ROI = draw(boundRect);//定义ROI,即为draw上的boundRect区域
		char name[20] = { 0 };
		sprintf(name,"E:\\temp\\%d.jpg",i);//格式化ROI文件名
		imwrite(name,ROI);//写ROI到本地
	}
	waitKey(0);
	return 0;
}

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值