Get超炫技能:如何使用 Python 执行运动检测?

只需要笔记本电脑就能完成的超酷技能!

微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩

在本文中,我们将专门研究使用笔记本电脑或计算机的网络摄像头进行运动检测,并将创建一个代码脚本以在我们的计算机上运行并查看其实时示例。

概述

由于 Python 编程语言提供了多个开源库,因此使用 Python 进行运动检测很容易。运动检测有许多实际应用。例如,它可用于在线考试的监考或商店、银行等的安全目的。

介绍

Python 编程语言是一种开源库丰富的语言,它为用户提供了大量的应用程序并拥有大量用户。因此,它在市场上快速增长。由于其简单的语法、易于发现的错误和快速的调试过程使其更加用户友好,因此 Python 语言的优点是无穷无尽的。

为什么要学习 Python?图示:

Python 设计于 1991 年,由 Python 软件基金会开发。发布了许多版本的python。其中,python2 和 python3 是最著名的。目前主要使用python3,python3的用户增长很快。在这个项目或脚本中,我们将使用 python3。

什么是运动检测?

根据物理学,当一个物体静止不动并且没有速度时,它被认为是静止的,而恰恰相反,当一个物体没有完全静止并且在某个方向上有一些运动或速度时,或者向左-右、前后或上下,则认为它处于运动状态。在本文中,我们将尝试检测它。

运动检测有许多现实生活中的实现或用途,可以证明其价值,例如使用网络摄像头监考在线考试(我们将在本文中实现),作为保安等。

在本文中,我们将尝试实现一个脚本,通过该脚本我们将使用台式机或笔记本电脑的网络摄像头检测运动。我们的想法是我们将拍摄两帧视频并尝试找出它们之间的差异。如果两帧之间存在某种差异,那么很明显,相机前面的物体发生了某种运动,从而产生了差异。

重要图书馆

在开始代码实现之前,让我们看一下我们将通过代码使用网络摄像头进行运动检测的一些模块或库。正如我们已经讨论过库在 python 的名声中扮演着重要角色,让我们看看我们需要什么:

  • OpenCV

  • Pandas

上述两个库,OpenCV 和 Pandas 都是纯粹基于 Python 的、免费的开源库,我们将在 Python3 版本的 Python 编程语言中使用它们。

1.OpenCV

OpenCV 是一个开源库,可与 C++、Python 等多种编程语言一起使用。它用于处理图像和视频,通过使用或与 python 的 panda/NumPy 库集成,我们可以充分利用OpenCV 的特性。

2.Pandas

正如我们所讨论的,“pandas”是 Python 的一个开源库,并提供了丰富的内置数据分析工具,因此它被广泛用于数据科学和数据分析流中。我们在 pandas 中以数据结构的形式提供数据帧,这有助于将表格数据操作和存储到二维数据结构中。

上面讨论的两个模块都不是python内置的,我们必须在使用前先安装它们。除此之外,我们将在项目中使用另外两个模块。

  • Python 日期时间模块

  • Python 时间模块

这两个模块都是python内置的,以后不需要安装。这些模块分别处理与日期和时间相关的功能。

代码实现

到目前为止,我们已经看到了我们将在代码中使用的库,让我们从视频只是许多静态图像或帧的组合开始它的实现,所有这些帧组合起来创建一个视频:

导入所需的库

在本节中,我们将导入所有库,例如 pandas 和 panda。然后我们从 DateTime 模块中导入 cv2、time 和 DateTime 函数。

# Importing the Pandas libraries  
import pandas as panda  

# Importing the OpenCV libraries  
import cv2  

# Importing the time module  
import time  

# Importing the datetime function of the datetime module  
from datetime import datetime 

初始化我们的数据变量

在本节中,我们初始化了一些我们将在代码中进一步使用的变量。我们将初始状态定义为“无”,并将跟踪的运动存储在另一个变量 motionTrackList 中。

我们定义了一个列表“motionTime”来存储发现运动的时间,并使用 panda 的模块初始化 dataFrame 列表。

# Assigning our initial state in the form of variable initialState as None for initial frames  
initialState = None  

# List of all the tracks when there is any detected of motion in the frames  
motionTrackList= [ None, None ]  

# A new list ‘time’ for storing the time when movement detected  
motionTime = []  

# Initialising DataFrame variable ‘dataFrame’ using pandas libraries panda with Initial and Final column  
dataFrame = panda.DataFrame(columns = ["Initial", "Final"])  

主要捕获过程

在本节中,我们将执行主要的运动检测步骤。让我们逐步理解它们:

  1. 首先,我们将开始使用 cv2 模块捕获视频并将其存储在 video 变量中。

  2. 然后我们将使用无限循环来捕获视频中的每一帧。

  3. 我们将使用 read() 方法读取每一帧并将它们存储到各自的变量中。

  4. 我们定义了一个可变运动并将其初始化为零。

  5. 我们使用 cv2 函数 cvtColor 和 GaussianBlur 创建了另外两个变量 grayImage 和 grayFrame 来查找运动的变化。

  6. 如果我们的 initialState 是 None 那么我们将当前的 grayFrame 分配给 initialState 否则并使用“continue”关键字停止下一个进程。

  7. 在下一节中,我们计算了我们在当前迭代中创建的初始帧和灰度帧之间的差异。

  8. 然后我们将使用 cv2 阈值和扩张函数突出显示初始帧和当前帧之间的变化。

  9. 我们将从当前图像或帧中的移动对象中找到轮廓,并通过使用矩形函数在其周围创建绿色边界来指示移动对象。

  10. 在此之后,我们将通过添加当前检测到的元素来附加我们的motionTrackList。

  11. 我们使用imshow方法显示了所有的帧,如灰度和原始帧等。

  12. 此外,我们使用 cv2 模块的 witkey() 方法创建了一个键来结束进程,我们可以使用“m”键来结束我们的进程。

# starting the webCam to capture the video using cv2 module  
video = cv2.VideoCapture(0)  

# using infinite loop to capture the frames from the video 
while True:  

   # Reading each image or frame from the video using read function 

   check, cur_frame = video.read()  

   

   # Defining 'motion' variable equal to zero as initial frame 

   var_motion = 0  

   

   # From colour images creating a gray frame 

   gray_image = cv2.cvtColor(cur_frame, cv2.COLOR_BGR2GRAY)  

   

   # To find the changes creating a GaussianBlur from the gray scale image  

   gray_frame = cv2.GaussianBlur(gray_image, (21, 21), 0)  

   

   # For the first iteration checking the condition

   # we will assign grayFrame to initalState if is none  

   if initialState is None:  

       initialState = gray_frame  

       continue  

       

   # Calculation of difference between static or initial and gray frame we created  

   differ_frame = cv2.absdiff(initialState, gray_frame)  

   

   # the change between static or initial background and current gray frame are highlighted 

   

   thresh_frame = cv2.threshold(differ_frame, 30, 255, cv2.THRESH_BINARY)[1]  

   thresh_frame = cv2.dilate(thresh_frame, None, iterations = 2)  

   

   # For the moving object in the frame finding the coutours 

   cont,_ = cv2.findContours(thresh_frame.copy(),   

                      cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  

   

   for cur in cont:  

       if cv2.contourArea(cur) < 10000:  

           continue  

       var_motion = 1  

       (cur_x, cur_y,cur_w, cur_h) = cv2.boundingRect(cur)  

       

       # To create a rectangle of green color around the moving object  

       cv2.rectangle(cur_frame, (cur_x, cur_y), (cur_x + cur_w, cur_y + cur_h), (0, 255, 0), 3)  

       

  # from the frame adding the motion status   

   motionTrackList.append(var_motion)  

   motionTrackList = motionTrackList[-2:]  

   

   # Adding the Start time of the motion 

   if motionTrackList[-1] == 1 and motionTrackList[-2] == 0:  

       motionTime.append(datetime.now())  

       

  # Adding the End time of the motion 

   if motionTrackList[-1] == 0 and motionTrackList[-2] == 1:  

       motionTime.append(datetime.now())  

       

  # In the gray scale displaying the captured image 

   cv2.imshow("The image captured in the Gray Frame is shown below: ", gray_frame)  

   

   # To display the difference between inital static frame and the current frame 

   cv2.imshow("Difference between the  inital static frame and the current frame: ", differ_frame)  

   

   # To display on the frame screen the black and white images from the video  

   cv2.imshow("Threshold Frame created from the PC or Laptop Webcam is: ", thresh_frame)  

   

   # Through the colour frame displaying the contour of the object

   cv2.imshow("From the PC or Laptop webcam, this is one example of the Colour Frame:", cur_frame)  

   

   # Creating a key to wait  

   wait_key = cv2.waitKey(1)  

   

   # With the help of the 'm' key ending the whole process of our system   

   if wait_key == ord('m'):  

       # adding the motion variable value to motiontime list when something is moving on the screen  

       if var_motion == 1:  

           motionTime.append(datetime.now())  

       break 

完成代码

关闭循环后,我们会将 dataFrame 和 motionTime 列表中的数据添加到 CSV 文件中,最后关闭视频。

# At last we are adding the time of motion or var_motion inside the data frame  
for a in range(0, len(motionTime), 2):  

   dataFrame = dataFrame.append({"Initial" : time[a], "Final" : motionTime[a + 1]}, ignore_index = True)  

   
# To record all the movements, creating a CSV file  
dataFrame.to_csv("EachMovement.csv")  

# Releasing the video   
video.release()  

# Now, Closing or destroying all the open windows with the help of openCV  
cv2.destroyAllWindows()

流程总结

我们已经创建了代码;现在让我们再次简要讨论该过程。

首先,我们使用设备的网络摄像头拍摄视频,然后将输入视频的初始帧作为参考,并不时检查下一帧。如果找到与第一个不同的帧,则存在运动。这将在绿色矩形中标记。

组合代码

我们已经在不同的部分看到了代码。现在,让我们结合起来:

# Importing the Pandas libraries  
import pandas as panda  

# Importing the OpenCV libraries  
import cv2  

# Importing the time module  
import time  

# Importing the datetime function of the datetime module  
from datetime import datetime 

# Assigning our initial state in the form of variable initialState as None for initial frames  
initialState = None  

# List of all the tracks when there is any detected of motion in the frames  
motionTrackList= [ None, None ]  

# A new list 'time' for storing the time when movement detected  
motionTime = []  

# Initialising DataFrame variable 'dataFrame' using pandas libraries panda with Initial and Final column  
dataFrame = panda.DataFrame(columns = ["Initial", "Final"])

# starting the webCam to capture the video using cv2 module  
video = cv2.VideoCapture(0)  

# using infinite loop to capture the frames from the video 
while True:  

   # Reading each image or frame from the video using read function 

   check, cur_frame = video.read()  

   

   # Defining 'motion' variable equal to zero as initial frame 

   var_motion = 0  

   

   # From colour images creating a gray frame 

   gray_image = cv2.cvtColor(cur_frame, cv2.COLOR_BGR2GRAY)  

   

   # To find the changes creating a GaussianBlur from the gray scale image  

   gray_frame = cv2.GaussianBlur(gray_image, (21, 21), 0)  

   

   # For the first iteration checking the condition

   # we will assign grayFrame to initalState if is none  

   if initialState is None:  

       initialState = gray_frame  

       continue  

       

   # Calculation of difference between static or initial and gray frame we created  

   differ_frame = cv2.absdiff(initialState, gray_frame)  

   

   # the change between static or initial background and current gray frame are highlighted 

   

   thresh_frame = cv2.threshold(differ_frame, 30, 255, cv2.THRESH_BINARY)[1]  

   thresh_frame = cv2.dilate(thresh_frame, None, iterations = 2)  

   

   # For the moving object in the frame finding the coutours 

   cont,_ = cv2.findContours(thresh_frame.copy(),   

                      cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  

   

   for cur in cont:  

       if cv2.contourArea(cur) < 10000:  

           continue  

       var_motion = 1  

       (cur_x, cur_y,cur_w, cur_h) = cv2.boundingRect(cur)  

       

       # To create a rectangle of green color around the moving object  

       cv2.rectangle(cur_frame, (cur_x, cur_y), (cur_x + cur_w, cur_y + cur_h), (0, 255, 0), 3)  

       

  # from the frame adding the motion status   

   motionTrackList.append(var_motion)  

   motionTrackList = motionTrackList[-2:]  

   

   # Adding the Start time of the motion 

   if motionTrackList[-1] == 1 and motionTrackList[-2] == 0:  

       motionTime.append(datetime.now())  

       

  # Adding the End time of the motion 

   if motionTrackList[-1] == 0 and motionTrackList[-2] == 1:  

       motionTime.append(datetime.now())  

       

  # In the gray scale displaying the captured image 

   cv2.imshow("The image captured in the Gray Frame is shown below: ", gray_frame)  

   

   # To display the difference between inital static frame and the current frame 

   cv2.imshow("Difference between the  inital static frame and the current frame: ", differ_frame)  

   

   # To display on the frame screen the black and white images from the video  

   cv2.imshow("Threshold Frame created from the PC or Laptop Webcam is: ", thresh_frame)  

   

   # Through the colour frame displaying the contour of the object

   cv2.imshow("From the PC or Laptop webcam, this is one example of the Colour Frame:", cur_frame)  

   

   # Creating a key to wait  

   wait_key = cv2.waitKey(1)  

   

   # With the help of the 'm' key ending the whole process of our system   

   if wait_key == ord('m'):  

       # adding the motion variable value to motiontime list when something is moving on the screen  

       if var_motion == 1:  

           motionTime.append(datetime.now())  

       break 

# At last we are adding the time of motion or var_motion inside the data frame  
for a in range(0, len(motionTime), 2):  

   dataFrame = dataFrame.append({"Initial" : time[a], "Final" : motionTime[a + 1]}, ignore_index = True)  

   
# To record all the movements, creating a CSV file  
dataFrame.to_csv("EachMovement.csv")  

# Releasing the video   
video.release()  

# Now, Closing or destroying all the open windows with the help of openCV  
cv2.destroyAllWindows()

结果

运行上述代码后得出的结果将与下面看到的类似。

在这里,我们可以看到视频中男人的动作已经被追踪到了。因此,可以相应地看到输出。

然而,在这段代码中,跟踪将在移动对象周围的矩形框的帮助下完成,类似于下面可以看到的。这里要注意的一件有趣的事情是,该视频是一个安全摄像机镜头,已经对其进行了检测。

结论

  • Python 编程语言是一种开源库丰富的语言,可为用户提供许多应用程序。

  • 当一个物体静止并且没有速度时,它被认为是静止的,而恰恰相反,当一个物体没有完全静止时,它被认为是运动的。

  • OpenCV 是一个开源库,可以与许多编程语言一起使用,通过将它与 python 的 panda/NumPy 库集成,我们可以充分利用 OpenCV 的特性。

  • 主要思想是每个视频只是许多称为帧的静态图像的组合,并且帧之间的差异用于检测.

参考文章:https://www.kdnuggets.com/2022/08/perform-motion-detection-python.html

推荐书单

《Python OpenCV从入门到精通》

购买链接:https://item.jd.com/13409660.html

《Python OpenCV从入门到精通》以在Python开发环境下运用OpenCV处理图像为主线,全面介绍OpenCV提供的处理图像的方法。全书共分为16章,包括Python与OpenCV、搭建开发环境、图像处理的基本操作、像素的操作、色彩空间与通道、绘制图形和文字、图像的几何变换、图像的阈值处理、图像的运算、模板匹配、滤波器、腐蚀与膨胀、图形检测、视频处理、人脸检测和人脸识别以及MR智能视频打卡系统。本书图文丰富,直观呈现处理后的图像与原图之间的差异;在讲解OpenCV提供的方法时,列举了其中的必选参数和可选参数,读者能更快地掌握方法的语法格式;最后一章以MR智能视频打卡系统为例,指导读者系统地运用OpenCV解决工作中的实际问题。本书专注于图像处理本身,尽可能忽略图像处理算法的具体实现细节,降低阅读和学习的难度,有助于读者更好更快地达到入门的目的。此外,本书资源包中提供了完整的示例源码、要使用到的图像等配套学习资源。

精彩回顾

可视化案例研究——以智利总统选举为例

【案例】如何使用Flask构建天气预报

手把手教你创建简单的Python Flask

微信搜索关注《Python学研大本营》

访问【IT今日热榜】,发现每日技术热点

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值