OpenCv学习笔记1-轮廓检测

OpenCv学习笔记1-轮廓检测


一、轮廓检测的基本原理

实现思路:通过找出在一张图片中满足特定像素值的像素点,实现轮廓绘制。

实验流程:
(1)颜色空间转换
(2)二值化处理
(3)腐蚀膨胀
(4)轮廓绘制

二、实验流程

1.颜色空间转换

实验第一步需要将RGB颜色空间转成HSV颜色空间,RGB对硬件友好,而HSV则对我们人眼友好,根据下面的表格我们可以得出需要的结果
在这里插入图片描述
例如我们如果想要框出这两车的车牌号,我们就可以直接用微信截图里的框(bushi),我们就可以把颜色为蓝色的点集寻找出来,使用阈值处理得到二值图

在这里插入图片描述

2.二值化处理

代码如下(示例):

// 转颜色空间

// 转颜色空间
	
	cvtColor(img, dst, CV_BGR2HSV);



	Mat dstImage;

	//二值化,+90为调整过后的参数,可以自行修改得到最佳值
	inRange(dst, Scalar(105, 53+90, 46), Scalar(114, 255, 255), dstImage);

3.腐蚀膨胀

腐蚀膨胀的主要作用就是去除噪声

腐蚀:遍历一个点周围的8个点,将当前点修改为周围点中的最小值
膨胀:遍历一个点周围的8个点,将当前点修改为周围点中的最大值
直接使用opencv中的现成库!

代码如下(示例):

// 转颜色空间


	//腐蚀膨胀
	Mat dstImage1_5;
	Mat element = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
	erode(dstImage, dstImage1_5, element, Point(-1, -1), 1, 0);

	Mat dstImage1_75;
	dilate(dstImage1_5, dstImage1_75, element, Point(-1, -1), 1);

前后效果图:
可以看出,左侧的噪声明显减少
在这里插入图片描述

4.轮廓绘制

第一步,找点集
我们在上面得到了二值图,即得到了想要部分(白色)和不想要部分,那么第二步,我们则需要找出边界的点集,使用以下函数即可

findContours(dstImage, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

第二步,找点集的外接矩形
在上面的函数处理后,返回的contours是一个点集,我们对这些点集直接使用下面函数寻找其外接矩形

  boundRect[i] = boundingRect(Mat(contours[i]));

对返回的多个矩形通过长宽进行筛选,最终得到正确结果

double wh = boundRect[i].width / boundRect[i].height;
				
			if(wh>2&& boundRect[i].height>20)

完整代码

#include<iostream>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#include<cstdlib>
#include<ctime>

using namespace std;
using namespace cv;


int main() {




	//定义变量
	
	Mat img;
	Mat dst;

	Mat result;

	//载入图片  

	img = imread("C:\\Users\\EDZ\\Desktop\\1.jpg");

	// 转颜色空间
	
	cvtColor(img, dst, CV_BGR2HSV);



	Mat dstImage;

	//二值化
	inRange(dst, Scalar(105, 53+90, 46), Scalar(114, 255, 255), dstImage);
	
	//腐蚀膨胀
	Mat dstImage1_5;
	Mat element = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
	erode(dstImage, dstImage1_5, element, Point(-1, -1), 1, 0);

	Mat dstImage1_75;
	dilate(dstImage1_5, dstImage1_75, element, Point(-1, -1), 1);



	//轮廓绘制
	

	vector<vector<Point>> contours;
	vector<Vec4i> hierarcy;
	findContours(dstImage, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
	vector<Rect> boundRect(contours.size());  //定义外接矩形集合
	vector<RotatedRect> box(contours.size()); //定义最小外接矩形集合
	Point2f rect[4];
	for (int i = 0; i < contours.size(); i++)
		{
		    box[i] = minAreaRect(Mat(contours[i]));  //计算每个轮廓最小外接矩形
		    boundRect[i] = boundingRect(Mat(contours[i]));
		       
		    box[i].points(rect);  //把最小外接矩形四个端点复制给rect数组

				

			double wh = boundRect[i].width / boundRect[i].height;
				
			if(wh>2&& boundRect[i].height>20){

		    rectangle(img, Point(boundRect[i].x, boundRect[i].y), Point(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height), Scalar(0, 255, 0), 2, 8);
				for (int j = 0; j < 4; j++)
					{
						line(img, rect[j], rect[(j + 1) % 4], Scalar(0, 255, 0), 2, 8);  //绘制最小外接矩形每条边
					}
				}
				imshow("结果图", img);
		}


	/*通道统一
	Mat dstImage2;
	//cvtColor(dstImage1_75, dstImage2, COLOR_GRAY2BGR);
	cvtColor(dstImage, dstImage2, COLOR_GRAY2BGR);
	
	//掩码
	Mat r;
	bitwise_and(img2, dstImage2, r);*/


	//显示原图  

	namedWindow("Image");

	imshow("Image", img);

	// 显示二值图 

	namedWindow("二值化后的图像1");

	imshow("二值化后的图像1", dstImage);

	//腐蚀膨胀图
	namedWindow("腐蚀膨胀后的图像1");

	imshow("腐蚀膨胀后的图像1", dstImage1_75);

	//掩码图

	//namedWindow("掩码图");

	//imshow("掩码图", r);

	waitKey(0);






	
	

	return 0;
}

效果图:

在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值