【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;
}

运行结果:

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV中,轮廓外接多边形是一种常用的图像处理技术,它用于找到包围轮廓的最小外接多边形。下面是关于轮廓外接多边形的原理、作用和应用的简要介绍: 1. 原理: 轮廓外接多边形的原理是通过计算轮廓的凸包或最小包围矩形来确定外接多边形。凸包是包围所有轮廓点的最小凸多边形,而最小包围矩形是包围所有轮廓点的最小矩形。 2. 作用: 轮廓外接多边形在图像处理和计算机视觉中具有多种作用,包括: - 特征提取:通过外接多边形可以提取轮廓的形状特征,如面积、周长和几何形状等。 - 边界框定位:最小包围矩形可用于定位和包围物体轮廓,用于目标检测和跟踪任务。 - 区域分割:外接多边形可以帮助分割图像中的不同区域或物体。 - 物体识别和分类:根据外接多边形的特征,可以实现物体的识别和分类。 3. 应用轮廓外接多边形在各种计算机视觉和图像处理应用中广泛使用,包括但不限于以下领域: - 目标检测和识别:通过最小包围矩形或凸包,可以提取目标的外形特征,并进行分类和识别。 - 图像分析和处理:外接多边形可用于分割图像、提取边界、计算形状特征等。 - 视觉导航和机器人技术:外接多边形可以帮助机器人或自动导航系统识别和定位目标物体。 - 缺陷检测和质量控制:通过外接多边形可以检测产品的缺陷、判定质量。 总之,轮廓外接多边形是一种常用的图像处理技术,可以通过凸包或最小包围矩形来确定轮廓的外接多边形,用于特征提取、边界框定位、区域分割和物体识别等应用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值