点击上方“小白学视觉”,选择加"星标"或“置顶”算法
重磅干货,第一时间送达编程
本期咱们将学习如何使用OpenCV实现运动检测服务器
运动检测是指检测物体相对于周围环境的位置是否发生了变化。接下来,让咱们一块儿使用Python实现一个运动检测器应用程序吧!微信
该运动检测器能够完成如下任务:网络
1)在家工做时在屏幕前查找时间app
2) 监控孩子在屏幕前的时间ide
3) 在你的后院发现非法侵入函数
4) 在你的房间/房子/小巷周围找到不须要的公共/动物活动……。学习
想要实现该运动检测器程序咱们须要具有如下条件:优化
1)硬件要求:装有网络摄像机或任何类型摄像机的计算机。
2)软件需求:Pyhton3或者更高版本。
3)附加要求:对运动检测有必定的兴趣。
接下来咱们将一步步的完成该应用程序的构建。
首先,咱们将经过网络摄像头捕获第一帧,并将它视为基准帧,以下图所示。经过计算该基准帧中的对象与新帧对象之间的相位差来检测运动。咱们也将获得的结果称为Delta帧。
接下来,咱们将使用像素强度来优化Delta帧,优化后的帧称为阈值帧。而且,咱们将应用一些复杂的图像处理技术,例如阴影消除、扩张轮廓等,以完成在阈值帧上提取对象物体。如下是您要实现的目标:
被探测对象
当这个对象进入帧和退出帧时,咱们可以很容易的捕获这两帧的时间戳。所以,将可以准确的在视频中找到相关片断。
咱们但愿小伙伴都能本身实现这个程序,所以咱们就不直接嵌入代码了。
从最基本的安装开始,咱们须要安装Python3或更高版本,并使用pip安装pandas和OpenCV这两个库。这些工做作好,咱们的准备工做就完成了。
第一步:导入须要的库:
第二步:初始化变量,列表,data frame:
在下面的代码中,咱们将会了解到在何时须要使用上面涉及到的每一项。
第三步:使用网络摄像机捕获视频帧:
在OpenCV中有可以打开相机并捕获视频帧的内置函数。其中输入参数“0”表示计算机硬件端口号为0的摄像机。若是咱们拥有了多个摄像头或闭路电视等设置,能够经过该参数提供相应的端口号。
第四步:将捕捉到的帧转换为灰度图像,并应用高斯模糊去除噪声:
因为彩色图片中每一个像素均具备三个颜色通道,实际上咱们并不须要使用这么多的信息,所以首先将彩色帧转换成灰度帧。再利用高斯模糊对图像进行平滑处理,进而提升检测精度。在高斯模糊函数中,咱们利用第2个参数定义了高斯核的宽度和高度;利用第3个参数,定义了标准误差值。在这里咱们可使用核大小为(21,21),标准误差为0的标准值。想要了解有关高斯平滑的更多信息,请参考:
Smoothing Images - OpenCV 2.4.13.7 documentation In an analogous way as the Gaussian filter, the bilateral filter also considers the neighboring pixels with weights…
docs.opencv.org
第五步:捕获第一个灰度帧
第一帧是整个处理过程当中的基准帧。经过计算此基准帧与新帧之间特定对象的相位差来检测运动。在拍摄第一帧时,特定对象相机前不该有任何移动。可是获得的第一帧并不须要后续处理,所以咱们能够用continue语句跳事后续过程。
第六步:建立Delta帧和阈值帧
如今,咱们须要找出第一帧和当前帧之间的区别。所以,咱们使用absdiff函数并将获得的结果称为delta帧。对于咱们的用例来讲,仅仅找到一个差别是不够的,因此咱们须要定义一个像素阈值,它能够被视为真实的对象。
咱们能够选择30像素做为标准阈值,并将标准阈值的颜色定义为白色(颜色代码:255). 二元阈值函数THRESH_BINARY返回一个元组值,其中只有第二项([0]是第一项,[1]是第二项)包含生成的阈值帧。二元阈值函数用于处理含有2个离散值的非连续函数:如0或1。若是摄影机前面没有对象,咱们将当前帧的状态视为0;若是摄影机前面存在对象,则将当前帧的状态视为1。
更多阈值图像处理相关知识,请参考:
Miscellaneous Image Transformations - OpenCV 2.4.13.7 documentation Performs a marker-based image segmentation using the watershed algorithm. The function implements one of the variants…
docs.opencv.org
第七步:膨胀阈值帧并在其中找到轮廓像素
“咱们的眼睛老是被光线吸引,但阴影处有更多内容。”—格雷戈里·马奎尔
对象的每一个部分都会在背景或自身的其余部分留下必定的阴影。这彷佛老是让咱们感到很困惑。例如,鼻子投射在嘴唇上的阴影,较大的静止物体在旁边的小物体上投射的阴影。飘动的光源,不一样发光强度的多个光源,你房间的窗帘,光源的方向和视角等等都会对阴影形成必定的影响。
如下是在实时捕获的帧中发现的一些干扰。所以,为了使这些噪声最小化,咱们须要对图像进行滤波。在膨胀函数Dilate中,咱们能够经过设置迭代次数来设置平滑度。迭代次数越多,平滑度越高,处理时间也就越长。所以,建议保持标准化设置为3。膨胀函数中的“None”参数表示咱们的应用中不须要元素结构。
关于膨胀的更多知识,你能够参考:
Image Filtering - OpenCV 2.4.13.7 documentation Functions and classes described in this section are used to perform various linear or non-linear filtering operations…
docs.opencv.org
完成过滤之后,咱们须要在该帧中找到对象轮廓。咱们用当前帧中的轮廓来识别对象的大小和位置。为了实现这一点,咱们将该帧的一个副本传递到findCounters方法中,使用这个副原本查找轮廓。使用副本的缘由是,咱们不但愿轮廓识别影响到原始过滤帧。
这里有个麻烦,由于咱们必须将轮廓存储在一个元组中,而且只须要使用该元组的第一个值。请参阅Python3中声明元组的语法:(name,_)。
如今,咱们只须要在过滤层上找到对象的外部轮廓。对于咱们的用例来讲,除了极端外部轮廓之外的其余轮廓都是无用的。所以咱们必须使用一些近似方法来优化轮廓的提取过程。例如使用曲线近似或曲线插值,也可使用简单链近似规则,即压缩水平、垂直和对角线线段,只保留其端点。所以,咱们可以很快获得最佳拟合轮廓。
第八步:找到轮廓区域,并在矩形中造成端点:
实际上咱们并不想捕捉像昆虫这样的小物体,而是要捕捉像人或动物这样的大物体。所以咱们采用轮廓区域的概念,即跳过那些面积小于10000像素的对象。对于大于此区域的轮廓,咱们将状态设置为1,即检测到对象。
想知道关于图像处理中的轮廓,能够参考:
Structural Analysis and Shape Descriptors - OpenCV 2.4.13.7 documentation Draws contours outlines or filled contours. The function draws contour outlines in the image if or fills the area…
docs.opencv.org
如今咱们使用boundingRect函数捕捉轮廓的坐标。而后,咱们使用这些坐标在彩色帧上绘制一个特定颜色、特定厚度的矩形。此矩形描述了实际检测到的对象。
第九步:捕获对象进入帧(场景)和退出帧(场景)时的时间戳
“状态”列表status_list存储值0:表明未检测到对象,1:表明检测到对象。此状态值从0更改成1的时刻就是对象进入帧的那一时刻。一样,此状态值从1变为0的时刻就是对象从帧中消失的那一时刻。所以,咱们从状态列表的最后两个值能够得到这两个切换事件的时间戳。
第十步:显示全部不一样的画面(帧)
使用imshow()方法,咱们将在一个独立的窗口中显示每一个帧并进行比较。
咱们使用waitKey函数来延迟进程,直到按下某个键。在这里,咱们使用waitKey(1)从摄像机得到连续的实时反馈。想中止拍摄视频时,只需按键盘上的“Q”键便可。
咱们同时须要在按下“Q”的同时捕获最后一个时间戳,由于这将帮助程序结束从摄像机捕获视频的过程,并生成时间数据。
下面是使用该应用程序生成的实际图像输出。第一个图像表示基准帧的4个帧类型,第二个图像表示带有对象的帧的4种类型的帧。你能比较一下区别吗?
Baseline First Frame
Frame with a detected object
第十一步:生成时间数据
到目前为止,全部的时间戳都存储在pandas的data-frame变量中。为了从生成的数据中得到更多信息,咱们将把data-frame变量导出到本地磁盘的csv文件中。
请不要忘记释放视频变量,由于它在内存中占用了很多空间。同时销毁全部窗口以免出现没必要要的错误
这就是生成的csv的样子。正如咱们所看到的那样,在程序结束以前,这个对象已经被检测了3次。您能够查看开始时间和结束时间,并计算对象在摄影机前面的时间。
这个应用程序还不够使人兴奋吗?这个应用程序是否是远离了典型的无聊编程?物联网爱好者甚至能够把这个程序部署到树莓派服务器Raspberry Pi上,并创造奇迹!
若是本文对小伙伴有帮助,但愿能够在文末来个“一键三连”。
交流群
欢迎加入公众号读者群一块儿和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(之后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,不然不予经过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,不然会请出群,谢谢理解~
本文分享自微信公众号 - 小白学视觉(NoobCV)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。