前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用网络摄像头和Python中的OpenCV构建运动检测器(Translate)

使用网络摄像头和Python中的OpenCV构建运动检测器(Translate)

作者头像
小白学视觉
发布2020-07-15 11:45:37
2.7K0
发布2020-07-15 11:45:37
举报

本期我们将学习如何使用OpenCV实现运动检测

运动检测是指检测物体相对于周围环境的位置是否发生了变化。接下来,让我们一起使用Python实现一个运动检测器应用程序吧!

该运动检测器可以完成以下任务:

1)在家工作时在屏幕前查找时间

2) 监控孩子在屏幕前的时间

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上,并创造奇迹!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小白学视觉 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档