C++ 机器视觉—前景检测

什么是机器视觉?什么是前景检测?

机器视觉就是一门研究如何使机器“看”的学科(PS:大而空的话放到前面,来自维基百科)。

要理解前景检测这个词就需要从它的反义词“背景”理解,背景很好理解,我站到一个海蓝色的墙前面,我的背景就是墙,也可以说是海蓝色,那前景就是我了;前景检测就是找到我和背景不一样的地方。人一眼就可以看出来我站到墙前面,计算机可看不出来。

视觉

机器的视觉一般就是摄像机或视频文件,我们首先要从摄像拿到摄像机的画面,然后去对摄像机的画面进行处理。一般就是摄像机的帧率为21帧,就是一秒钟有多少张图,即21张图。

机器“眼中”的画面

机器眼中 所以东西都是01010101010101010这种东西,哈哈。经过一系列封装(如操作系统,文件格式、C++类库等等)最后可能我们可以在计算机内看到一个矩阵,以三通道BGR为例可能如下表(PS我猜的):

0xff(B) 0xff(G) 0xff(R)0xff(B) 0xff(G) 0xff(R)0xff(B) 0xff(G) 0xff(R)0xff(B) 0xff(G) 0xff(R)
0xff(B) 0xff(G) 0xff(R)0xff(B) 0xff(G) 0xff(R)0xff(B) 0xff(G) 0xff(R)0xff(B) 0xff(G) 0xff(R)
0xff(B) 0xff(G) 0xff(R)0xff(B) 0xff(G) 0xff(R)0xff(B) 0xff(G) 0xff(R)0xff(B) 0xff(G) 0xff(R)
0xff(B) 0xff(G) 0xff(R)0xff(B) 0xff(G) 0xff(R)0xff(B) 0xff(G) 0xff(R)0xff(B) 0xff(G) 0xff(R)

4*4的像素矩阵可能就是这样子的啦,这里也科普一下1920*1280就是有1920列1280行个这样的像素矩阵,计算机里面是什么样子的呢?先将16进制转成2进制

11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)
11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)
11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)
11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)

前景

假设我们的背景是白色的一个区域,我们前景是一个黑色到的点。那么这个矩阵会是什么样子的呢?

11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)
11111111(B) 11111111(G) 11111111(R)00000000(B) 00000000(G) 00000000(R)11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)
11111111(B) 11111111(G) 11111111(R)00000000(B) 00000000(G) 00000000(R)11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)
11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)11111111(B) 11111111(G) 11111111(R)

如何从背景中找到黑色的点呢?可能说循环一下找到三个0x00就不是一个黑点吗?那如果这个矩阵背景不是全部是1呢?如果我们不知道前景是黑色呢?这里就需要检测出前景了。

样本

如果背景是固定不变的,我们可以找到一张背景图做样本,如果背景会有变化,可以从码流选择一个我们认为可行的背景,来作为样本。例如后一帧和前一帧比较的前景是什么?或者后30帧和前一帧比较前景是什么。这样我们就可以在动态的码流中找到一些变化。

帧差法检测前景

因为最近项目用到了,我就写下来记录一下过程,其中用到的类库是Opencv,编程语言则是C++。

前面解释了那么多,好了直接上代码吧

cv::Mat src1,src2; //假设这两个是两个合适时段的原图片
				   //我们要从这两个原图中找到前景
cv::Mat dst1,dst2;

//首先做一个灰度处理
cv::cvtColor(src1,dst1,CV_BGR2GRAY);
cv::cvtColor(src2,dst2,CV_BGR2GRAY);

//高斯滤波
cv::GaussianBlur(dst1,dst1,cv::Size(3,3),0);
cv::GaussianBlur(dst2,dst2,cv::Size(3,3),0);

//两张图做差
cv::Mat diff_image;
cv::absdiff(dst1,dst2,diff_image);

//给帧差后的图做一个阈值限定,如下超过35阈值的即R+G+B>35的像素改为255,其他改为0
//这一操作为最后一个参数控制 cv::THRESH_BINART
cv::threshold(diff_image,diff_image,35,255,cv::THRESH_BINARY);

//创建一个28*28的核 
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE,cv::Size(28,28));
cv::erode(diff_image,diff_image,(3,3),cv::Point(-1,-1),2);	//腐蚀
cv::dilate(diff_image,diff_image,kernel,cv::Pint(-1,-1),2);	//膨胀

//将我们处理好的图片的边界找到,会形成多个不规则的点集
std::vector<std::vector<cv::Point>> contours;
cv::findContours(roi_diff,contours,cv::RETR_EXTERNAL,cv::CHAIN_APPROX_SIMPLE);

//其实这里已经找到了前景的区域了,只需要你去区分一下这些点集围成的区域哪个是前景。
//可以使用boundingRect来将点集使用一个最小矩型来框出来
cv::Rect rect = cv::boundingRect(contours[0]);

总结

具体用什么方式来处理图片这个就需要因地制宜来,上面流程也是我们项目的一个小处理流程,当然为什么要用高斯滤波不用其他的,为什么要把腐蚀的核设为3*3,膨胀的核设为28*28,这个其实我也不知道。233333

下面说一下对于这个图像处理我自己的理解:

1、为什么要做灰度处理,灰度首先比BGR少了很多信息,运算速度就会快很多,而且灰度可以更专注于像素间的梯度,也就是边界等问题。

2、滤波:应该是让像素的特征更为相近,这样更好找出一个合适的特征,因为没有做滤波可能画面比较清晰,像素的差异比较大,这样很难找到规律吧。与之相反的操作应该就是锐化了。让图片更具加有差异边界更加清晰。

3、做差:这个就不多做解释了,有对比才有伤害嘛。我记得看李飞飞的一个视频里说过说这样做有一个缺点,就是错位后做差会导致误差变得无限大,导致识别失败。具体大家可以去网易云课堂上自己看,可能我收了网易云音乐的“钱”(音乐)吧。

4、阈值化:做差之后相近的像素相减几乎就是很接近与零0,所以可以设立一个阈值来将背景设置为0,把你感兴趣的位置增大或者不变都可以。

5、腐蚀很膨胀,后面是先腐蚀后膨胀,原理大概是,腐蚀掉一些可以忽略的奇异点,然后再膨胀大将大面积且邻近的区域连接起来,形成一个区域。

6、最后就是把边界画出来,到这里基本就找到了我们想要的前景,只需要将前景和一些不必要的区分开即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值