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

重磅干货,第一时间送达

本期我们将学习如何使用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上,并创造奇迹!

如果本文对小伙伴有帮助,希望可以在文末来个“一键三连”。

交流群

(0)

相关推荐

  • (4条消息) 10分钟学会使用YOLO及Opencv实现目标检测(上)|附源码

    计算机视觉领域中,目标检测一直是工业应用上比较热门且成熟的应用领域,比如人脸识别.行人检测等,国内的旷视科技.商汤科技等公司在该领域占据行业领先地位.相对于图像分类任务而言,目标检测会更加复杂一些,不 ...

  • 2021年将主导Python的7大图像处理库

    有没有想过Python的哪个图像处理库将在2021年占据主导地位? 图像在提供关键信息方面起着重要作用.对于企业而言,图像和视频是重要的数据来源. 这就是原因,对于企业而言,有效地翻译和处理图像并获得 ...

  • OpenCV矩形检测

    矩形检测有什么用? 一个非常熟悉的例子是 拍摄的文本的预处理. 将文档定位出矩形,然后透视变换校正,方便后续的OCR. 虽然矩形检测看起来不难,好像是只要定位到四条边判断两两直线夹角就好了,但要做好也 ...

  • 使用Python中的OpenCV降噪功能增强图像的3个步骤

    重磅干货,第一时间送达 在本文中,我们将展示如何通过三个简单的步骤来实现降噪.我们将使用机器学习训练的降噪模型.这是我们找到的最好的降噪模型之一. 程序可以判断图像是否有噪点吗?这对于另一个项目可能是 ...

  • 如何使用OpenCV在Python中访问IP摄像头

    重磅干货,第一时间送达 capture = cv2.VideoCapture('rtsp://192.168.1.64/1') capture = cv2.VideoCapture('rtsp://[ ...

  • 陈根:网络摄像头背后,网络安全威胁正盛

    文/陈根 得益于物联网技术的发展,人类社会正在拥抱一个前所未有的互联世界.其中,随着物联网进程加快,作为传统摄像机与网络视频技术相结合的智能网络摄像头正不断向各个行业渗透. 显然,移动互联网的时代里, ...

  • Python 中的函数装饰器和闭包

    函数装饰器可以被用于增强方法的某些行为,如果想自己实现装饰器,则必须了解闭包的概念. 装饰器的基本概念 装饰器是一个可调用对象,它的参数是另一个函数,称为被装饰函数.装饰器可以修改这个函数再将其返回, ...

  • Python中tuple和list的区别?基础学习!

    想必大家都知道,Python数据类型有很多种,其中有两个对象的写法非常相似,它就是tuple元组和list列表,让人傻傻分不清楚.那么你知道Python中tuple和list有什么区别吗?我们来看看具 ...

  • Python中缩进是什么?入门分享!

    众所周知,Python是一门独特的编程语言,它语法清晰.简单易学,而且Python是通过缩进来识别代码块的,因为一般的语言都是通过{}或者end来作为代码块标记. Python中缩进是什么? 要求严格 ...

  • python中的内置函数

    前言 本人只在csdn写博客 内置函数 介绍 一. 数学运算 abs()求绝对值函数 round() 近似取值 pow()求指数 divmod()求商和余数 max()求最大值和min()求最小值 s ...

  • 【Python核心编程笔记】一、Python中一切皆对象

    Python中一切皆对象 本章节首先对比静态语言以及动态语言,然后介绍 python 中最底层也是面向对象最重要的几个概念-object.type和class之间的关系,以此来引出在python如何做 ...

  • 【青少年编程】Python中的分号

    今天有小朋友问我以下的选择题: 关于Python赋值语句,以下选项中不合法的是() A. x = (y=1) B. x, y = y, x C. x = y = 1 D. x = 1; y = 1 这 ...