展开菜单
首页 精品内容 本月促销 装机必备 Windows macOS软件 IOS软件 Android AI PDF教程 专题
全部分类

当前位置:

首页 > 编程开发 > Python实战:运动检测编程演练详解

Python实战:运动检测编程演练详解

​译者|朱先忠审校|孙淑娟概述由于Python编程语言面临多个开源库可用;因此,选择Python语言进行运动检测开发是很容易的。目前,运动检测已经有许多的商业应用。例如,它可以用于在线考试的监考,也可以用于商店、银行等领域的安全目的。Python编程语言是一种开源的且支持库极其丰富的语言,如今基于此语言已经为用户开发了大量的应用程序,并拥有大量用户。正因为如此,Python语言在市场上快速增长。Python语言的优点不胜枚举,不仅是因为它的语法简单、易于发现错误,而且其非常迅速的调试过程使其对用户

​译者 | 朱先忠

审校 | 孙淑娟

Python实战:运动检测编程演练详解

概述

由于Python编程语言面临多个开源库可用;因此,选择Python语言进行运动检测开发是很容易的。目前,运动检测已经有许多的商业应用。例如,它可以用于在线考试的监考,也可以用于商店、银行等领域的安全目的。

Python编程语言是一种开源的且支持库极其丰富的语言,如今基于此语言已经为用户开发了大量的应用程序,并拥有大量用户。正因为如此,Python语言在市场上快速增长。Python语言的优点不胜枚举,不仅是因为它的语法简单、易于发现错误,而且其非常迅速的调试过程使其对用户更加友好。

为什么建议您学习Python呢?我们可以使用下图来简单说明:

Python实战:运动检测编程演练详解

Python于1991年设计,由Python软件基金会开发。如今已经发布了许多版本。其中,Python2和Python3最为著名。目前,Python3已经被广泛使用,用户数量也在快速增长。在本文这个项目中,我们将使用Python3作为开发语言。

什么是运动检测?

根据物理学原理,当一个物体静止不动且没有速度时,它就被认为处于静止状态;而恰恰相反的是,当一物体没有完全静止且在某个方向(无论是左右、前后或上下)上有一定的运动或速度时,它都被认为处于运动状态。在本文中,我们将尝试检测出物体的运行情况。

Python实战:运动检测编程演练详解

目前,运动检测在现实生活中已经存在大量实现或应用,这充分证明其巨大的应用价值。其中,使用网络摄像头(我们将在本文中实现)作为安全警卫进行在线考试监考等是最典型的应用。

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

主要的参考库

在着手实现代码之前,让我们先看看我们将在代码中使用的一些模块或库,这些模块或库用于操作网络摄像头进行运动检测。正如我们所讨论的,这些开源库对于Python声誉的传播起着重要作用。让我们看看本文示例项目中需要的开源库:

  • OpenCV
  • Pandas

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

1.OpenCV

OpenCV是一个非常著名的开源库,可以与许多编程语言(如C++、Python等)一起使用,专门应用于处理图像和视频程序开发。通过与Python的开源库Pandas或者NumPy库集成应用,我们可以充分挖掘出OpenCV的功能。

2.Pandas

Pandas是一个开放源码的Python库,为数据分析提供了丰富的内置工具;因此,在数据科学和数据分析领域得到了广泛的应用。在Pandas中提供了数据结构形式DataFrame数据帧,这种结构对于将表格数据操作和存储到二维数据结构中提供了极方便的支持。

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

  • Python日期时间(DateTime)模块
  • Python时间(Time)模块

这两个模块都内置在Python中,以后无需安装。这些模块分别用来处理与日期和时间相关的功能。

代码实现

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

导入所需的库

在本节中,我们将首先导入所有库,如Pandas和OpenCV。然后,我们从DateTime模块导入time和DateTime函数。

#导入Pandas库
import Pandas as panda

# 导入OpenCV库
import cv2

#导入时间模块
import time

#从datetime 模块导入datetime 函数 
from datetime import datetime 

初始化数据变量

在本节中,我们要初始化一些变量,并将在代码中进一步使用这些变量。首先,我们将初始状态定义为“None”,然后通过另一个变量motionTrackList来存储跟踪的运动。

此外,我们还定义了一个列表“motionTime”,用于存储发现运动的时间,并使用Panda的模块初始化数据帧列表。

# 对于初始帧,以变量initialState的形式将初始状态指定为None
initialState = None

# 帧中检测到任何运动时存储所有轨迹的列表 
motionTrackList= [ None, None ]

# 一个新的“时间”列表,用于存储检测到移动时的时间
motionTime = []

# 使用带有初始列和最终列的Panda库初始化数据帧变量“DataFrame” 
dataFrame = panda.DataFrame(columns = ["Initial", "Final"])

关键帧捕获过程

在本节中,我们将实现本文示例项目中最关键的运动检测步骤。下面,让我们分步骤进行解说:

  1. 首先,我们将开始使用cv2模块捕获视频,并将其存储在视频变量中。
  2. 然后,我们将使用无限while循环从视频中捕获每一帧。
  3. 接下来,将使用read()方法读取每个帧,并将它们存储到各自的变量中。
  4. 我们定义了一个变量var_motion,并将其初始化为零。
  5. 我们使用cv2函数cvtColor和GaussianBlur创建另外两个变量grayImage和grayFrame,以找到运动中的变化。
  6. 如果我们的initialState为None,则我们将当前grayFrame指定为initialState;否则,使用“continue”关键字跳过后面代码的执行。
  7. 在后面代码中,我们计算在当前迭代中创建的初始帧和灰度帧grayscale之间的差异。
  8. 然后,我们将使用cv2阈值和dilate函数突出显示初始帧和当前帧之间的变化。
  9. 我们将从当前图像或帧中的运动对象中找到轮廓,并通过使用rectangle函数在其周围创建绿色边界来指示运动对象。
  10. 在此之后,我们将把当前检测到的元素添加到列表变量motionTrackList。
  11. 到目前为止,我们已经通过使用imshow方法显示出如灰度和原始帧等所有的关键帧。
  12. 此外,我们还使用cv2模块的witkey()方法来结束进程。程序中,我们选择使用按下键盘上的'm'键来结束我们的进程。
# 使用cv2模块启动网络摄像头以捕获视频 
video = cv2.VideoCapture(0)

# 使用无限循环从视频中捕获帧
while True:

 # 使用read功能从视频中读取每个图像或帧

 check, cur_frame = video.read()

 

 #将'motion'变量定义为等于零的初始帧

 var_motion = 0

 

 # 从彩色图像创建灰色帧 

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

 

 # 从灰度图像中使用GaussianBlur函数找到变化部分

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

 

 # 在第一次迭代时进行条件检查

 # 如果为None,则把grayFrame赋值给变量initalState

 if initialState is None:

 initialState = gray_frame

 continue

 

 # 计算静态(或初始)帧与我们创建的灰色帧之间的差异

 differ_frame = cv2.absdiff(initialState, gray_frame)

 

 # 静态或初始背景与当前灰色帧之间的变化将突出显示 

 

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

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

 

 #对于帧中的移动对象,查找轮廓

 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)

 

 # 在移动对象周围创建一个绿色矩形

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

 

# 从帧中添加运动状态 

 motionTrackList.append(var_motion)

 motionTrackList = motionTrackList[-2:]

 

 # 添加运动的开始时间 

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

 motionTime.append(datetime.now())

 

# 添加运动的结束时间 

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

 motionTime.append(datetime.now())

 

# 在显示捕获图像的灰度级中 

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

 

 # 显示初始静态帧和当前帧之间的差异 

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

 

 # 在框架屏幕上显示视频中的黑白图像 

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

 

 #通过彩色框显示物体的轮廓

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

 

 # 创建处于等待状态的键盘按键 

 wait_key = cv2.waitKey(1)

 

 # 按下'm'键时,结束整个进程执行

 if wait_key == ord('m'):

 # 当屏幕上有东西移动时,将运动变量值添加到motiontime列表中 

 if var_motion == 1:

 motionTime.append(datetime.now())

 break 

代码收尾工作

在结束循环体执行后,我们将从dataFrame和motionTime列表中添加数据到CSV文件中,最后关闭视频。这一部分代码的实现如下所示:

# 最后,我们在数据帧中添加运动时间 
for a in range(0, len(motionTime), 2):

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

 
# 创建CSV文件记录下所有运动信息
dataFrame.to_csv("EachMovement.csv")

# 释放视频内存 
video.release()

#现在,在openCV的帮助下关闭或销毁所有打开的窗口
cv2.destroyAllWindows()

至此,我们已经成功地创建完所有代码。现在,让我们再次归纳一下整个过程。

首先,我们使用设备的网络摄像头捕捉视频,然后将输入视频的初始帧作为参考,并不时检查下一帧。如果发现与第一帧不同的帧,则说明存在运动。该信息将被标记在绿色矩形中。

完整的代码

现在,让我们把上面所有代码片断连接到一起,如下所示:

#导入Pandas库
import Pandas as panda

# 导入OpenCV库
import cv2

#导入时间模块
import time

#从datetime 模块导入datetime 函数 
from datetime import datetime 

# 对于初始帧,以变量initialState的形式将初始状态指定为None
initialState = None

# 帧中检测到任何运动时存储所有轨迹的列表 
motionTrackList= [ None, None ]

# 一个新的“时间”列表,用于存储检测到移动时的时间
motionTime = []

# 使用带有初始列和最终列的Panda库初始化数据帧变量“DataFrame” 
dataFrame = panda.DataFrame(columns = ["Initial", "Final"])

# 使用cv2模块启动网络摄像头以捕获视频 
video = cv2.VideoCapture(0)

# 使用无限循环从视频中捕获帧
while True:

 # 使用read功能从视频中读取每个图像或帧

 check, cur_frame = video.read()

 

 #将'motion'变量定义为等于零的初始帧

 var_motion = 0

 

 # 从彩色图像创建灰色帧 

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

 

 # 从灰度图像中使用GaussianBlur函数找到变化部分

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

 

 # 在第一次迭代时进行条件检查

 # 如果为None,则把grayFrame赋值给变量initalState

 if initialState is None:

 initialState = gray_frame

 continue

 

 # 计算静态(或初始)帧与我们创建的灰色帧之间的差异

 differ_frame = cv2.absdiff(initialState, gray_frame)

 

 # 静态或初始背景与当前灰色帧之间的变化将突出显示 

 

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

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

 

 #对于帧中的移动对象,查找轮廓

 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)

 

 # 在移动对象周围创建一个绿色矩形

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

 

# 从帧中添加运动状态 

 motionTrackList.append(var_motion)

 motionTrackList = motionTrackList[-2:]

 

 # 添加运动的开始时间 

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

 motionTime.append(datetime.now())

 

# 添加运动的结束时间 

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

 motionTime.append(datetime.now())

 

# 在显示捕获图像的灰度级中 

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

 

 # 显示初始静态帧和当前帧之间的差异 

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

 

 # 在框架屏幕上显示视频中的黑白图像 

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

 

 #通过彩色框显示物体的轮廓

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

 

 # 创建处于等待状态的键盘按键 

 wait_key = cv2.waitKey(1)

 

 # 借助'm'键结束我们系统的整个进行 

 if wait_key == ord('m'):

 # 当屏幕上有物体运行时把运动变量值添加到列表motiontime中

 if var_motion == 1:

 motionTime.append(datetime.now())

 break 

# 最后,我们在数据帧中添加运动时间 
for a in range(0, len(motionTime), 2):

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

 
# 记录下所有运行,并创建到一个CSV文件中 
dataFrame.to_csv("EachMovement.csv")

# 释放视频内存
video.release()

#现在,在openCV的帮助下关闭或销毁所有打开的窗口
cv2.destroyAllWindows()

运行结果

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

Python实战:运动检测编程演练详解

从这个动画中,我们可以看到该男子在视频中的动作已经被跟踪。因此,可以相应地看到输出结果。

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

Python实战:运动检测编程演练详解

结论

  • Python编程语言是一种开源的且有丰富的开源库支持的语言,目前已经为用户提供了许多现成的应用程序。
  • 当一个物体静止不动且没有速度时,则认为它处于静止状态;反之,当一个对象未完全静止时,则视为它处于运动状态。
  • OpenCV是一个开源库,可用于多种编程语言,通过将其与Python的Panda/NumPy库集成,我们可以充分发挥OpenCV的功能。

最后来归纳一下。本文中所介绍的运动检测的主要思想是,每个视频只是许多静态图像(称为帧)的组合,我们是通过判断帧之间的差异来实现运行检测的。

译者介绍

朱先忠,51CTO社区编辑,51CTO专家博客、讲师,潍坊一所高校计算机教师,自由编程界老兵一枚。早期专注各种微软技术(编著成ASP.NET AJX、Cocos 2d-X相关三本技术图书),近十多年投身于开源世界(熟悉流行全栈Web开发技术),了解基于OneNet/AliOS+Arduino/ESP32/树莓派等物联网开发技术与Scala+Hadoop+Spark+Flink等大数据开发技术。

原文标题:How to Perform Motion Detection Using Python​,作者:Vaishnavi Amira Yada​

本文内容来源于互联网,如有侵权请联系删除。
作者最新文章
编程开发 Python
相关文章 更多
精品专题 更多
本月促销

正软商城本月促销专区,汇集办公、设计、安全、影音、系统工具及AI软件等正版软件优惠活动,提供限时折扣、特价授权和优惠购买信息,活动库存及价格以页面实时展示为准。

装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

macOS软件

正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

IOS软件

正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

AI

正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

PDF教程

正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

Mac软件 更多
灵活计算器
灵活计算器

灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

赤友清理大师
赤友清理大师

赤友清理大师是一款为 Mac 设计的智能清理优化工具,可精准扫描垃圾、大文件、重复文件等,释放磁盘空间。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

极度公式
极度公式

极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

图几
图几

图几是一款适用于 macOS 的截图、标注与美化工具,支持离线操作保障隐私。界面整理和高频系统操作被放到一起考虑,桌面或窗口内容一多时,管理起来会更省心。

密码键盘
密码键盘

密码键盘是一款兼具安全性与便捷性的高效密码管理器。日常使用里的持续防护和信息管理会更突出,适合把安全控制放进长期使用流程中的场景。

思源笔记
思源笔记

思源笔记是一款本地笔记软件,提供所见即所得的编辑方式,为长文写作带来顺滑的体验。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

Office 365 简体中文
Office 365 简体中文

一款文字处理软件,一种订阅式的跨平台办公软件,基于云平台提供多种服务,通过将 Excel 和 Outlook 等应用与 OneDrive 和 Microsoft Teams 等强大的云服务相结合,Office 365 可让任何人使用任何设备随时随地创建和共享内容。

WALTR PRO
WALTR PRO

WALTR是一款电脑至iOS文件传输转换工具,操作简单,快速实现文件识别与传送。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

CodeExpander
CodeExpander

CodeExpander 是一款快捷短语输入增强工具,通过键入缩写自动展开为自定义文段,提升工作效率。任务管理和过程控制会更完整,持续下载、批量同步或需要稳定传输流程的场景会更适合它。

Mountain Duck
Mountain Duck

Mountain Duck 是一款能将多个网盘挂载到本地的工具,像本地磁盘一样使用网盘。清理链路的完整性会更好一些,做应用卸载、残留处理和空间整理时,通常能少走很多手动排查步骤。

Menuist
Menuist

Menuist 是一款面向 macOS 的 Finder 右键菜单增强工具,主要用来补充新建文件、快捷导航等常用操作,让日常文件管理和访问路径时更高效、更顺手。

Mole
Mole

Mole 是一款专为 Mac 设计的深度清理优化工具,涵盖缓存清理、应用管理及实时状态监控等功能。清理链路的完整性会更好一些,做应用卸载、残留处理和空间整理时,通常能少走很多手动排查步骤。

WINDOWS 更多
Windows 10
Windows 10

Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。

极度公式
极度公式

极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

密码键盘
密码键盘

密码键盘是一款兼具安全性与便捷性的高效密码管理器。日常使用里的持续防护和信息管理会更突出,适合把安全控制放进长期使用流程中的场景。

思源笔记
思源笔记

思源笔记是一款本地笔记软件,提供所见即所得的编辑方式,为长文写作带来顺滑的体验。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

傲梅轻松备份
傲梅轻松备份

傲梅轻松备份是一款专业易用的数据备份软件,为重要数据提供安全保障。日常使用里的持续防护和信息管理会更突出,适合把安全控制放进长期使用流程中的场景。

Office 365 简体中文
Office 365 简体中文

一款文字处理软件,一种订阅式的跨平台办公软件,基于云平台提供多种服务,通过将 Excel 和 Outlook 等应用与 OneDrive 和 Microsoft Teams 等强大的云服务相结合,Office 365 可让任何人使用任何设备随时随地创建和共享内容。

Wise Folder Hider Pro
Wise Folder Hider Pro

Wise Folder Hider Pro 是一款专业级文件和文件夹隐藏加密软件,为私密数据添加多重保护。高频操作更强调就近处理,浏览、整理和跨目录移动文件时,来回切换和重复点击都会少很多。

WALTR PRO
WALTR PRO

WALTR是一款电脑至iOS文件传输转换工具,操作简单,快速实现文件识别与传送。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

CodeExpander
CodeExpander

CodeExpander 是一款快捷短语输入增强工具,通过键入缩写自动展开为自定义文段,提升工作效率。任务管理和过程控制会更完整,持续下载、批量同步或需要稳定传输流程的场景会更适合它。

PinStack
PinStack

PinStack是一款轻量级的Windows平台剪贴板管理工具,优化您的剪贴板使用体验。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。

Mountain Duck
Mountain Duck

Mountain Duck 是一款能将多个网盘挂载到本地的工具,像本地磁盘一样使用网盘。清理链路的完整性会更好一些,做应用卸载、残留处理和空间整理时,通常能少走很多手动排查步骤。

Seer
Seer

Seer是一款在Win平台下的空格键功能增强效率工具,只需轻敲空格键,就能预览几乎任何格式的文件。它更适合把零散的小功能集中起来使用,处理高频琐碎任务时会更省事。