>  기사  >  백엔드 개발  >  Python 동작 감지 프로그래밍 실습 훈련

Python 동작 감지 프로그래밍 실습 훈련

PHPz
PHPz앞으로
2023-04-25 13:10:061312검색

번역가 | Zhu Xianzhong

리뷰어 | Sun Shujuan

Python 동작 감지 프로그래밍 실습 훈련

개요

Python 프로그래밍 언어는 사용 가능한 여러 오픈 소스 라이브러리에 직면하므로 동작 감지 개발을 위해 Python 언어를 선택하기가 쉽습니다. 현재 모션 감지에는 많은 상용 응용 프로그램이 있습니다. 예를 들어 온라인 시험 감독이나 상점, 은행 등의 보안 목적으로 사용될 수 있습니다.

Python 프로그래밍 언어는 매우 풍부한 지원 라이브러리를 갖춘 오픈 소스 언어입니다. 오늘날 이 언어를 기반으로 하는 사용자를 위해 수많은 응용 프로그램이 개발되었으며 많은 수의 사용자가 있습니다. 이로 인해 Python 언어가 시장에서 빠르게 성장하고 있습니다. Python 언어의 장점은 매우 많습니다. 구문이 간단하고 오류를 쉽게 찾을 수 있을 뿐만 아니라 매우 빠른 디버깅 프로세스로 인해 더욱 사용자 친화적이라는 점입니다.

파이썬을 배우는 것이 왜 권장되나요? 다음 다이어그램을 사용하여 간단히 설명할 수 있습니다.

Python 동작 감지 프로그래밍 실습 훈련

Python은 1991년에 설계되었으며 Python Software Foundation에서 개발되었습니다. 오늘은 다양한 버전이 출시되었습니다. 그 중 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는 테이블 형식의 데이터를 2차원 데이터 구조로 운영하고 저장하기 위한 매우 편리한 지원을 제공하는 DataFrame 형식의 데이터 구조를 제공합니다.

위 두 모듈 중 어느 것도 Python에 내장되어 있지 않으므로 사용하기 전에 설치해야 합니다. 이 외에도 우리 프로젝트에서는 두 개의 다른 모듈도 사용할 것입니다.

  • Python DateTime(DateTime) 모듈
  • Python 시간(Time) 모듈

두 모듈 모두 Python에 내장되어 있으므로 나중에 설치할 필요가 없습니다. 이 모듈은 각각 날짜 및 시간 관련 기능을 처리하는 데 사용됩니다.

코드 구현

지금까지 우리는 코드에서 사용할 라이브러리를 살펴보았습니다. 다음으로, 비디오는 단지 수많은 정지 이미지나 프레임의 조합일 뿐이라고 가정하고, 그 모든 프레임의 조합을 이용하여 비디오를 만들어 보겠습니다.

필수 라이브러리 가져오기

이 섹션에서는 먼저 Pandas 및 OpenCV와 같은 모든 라이브러리를 가져옵니다. 그런 다음 DateTime 모듈에서 시간 및 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 동작 감지 프로그래밍 실습 훈련의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 51cto.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제