运动检测是指检测物体相对于周围环境的位置是否发生了变化。接下来,让我们一起使用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…
郑州同济医院http://www.zzfkyy120.com/
郑州同济医院http://www.xasgnk.com/
docs.opencv.org
第七步:膨胀阈值帧并在其中找到轮廓像素

“我们的眼睛总是被光线吸引,但阴影处有更多内容。”—格雷戈里·马奎尔
对象的每个部分都会在背景或自身的其他部分留下一定的阴影。这似乎总是让我们感到很困惑。例如,鼻子投射在嘴唇上的阴影,较大的静止物体在旁边的小物体上投射的阴影。飘动的光源,不同发光强度的多个光源,你房间的窗帘,光源的方向和视角等等都会对阴影造成一定的影响。
以下是在实时捕获的帧中发现的一些干扰。因此,为了使这些噪声最小化,我们需要对图像进行滤波。在膨胀函数Dilate中,我们可以通过设置迭代次数来设置平滑度。迭代次数越多,平滑度越高,处理时间也就越长。因此,建议保持标准化设置为3。膨胀函数中的“None”参数表示我们的应用中不需要元素结构。