- 使用Buster和OpenCV设置Raspberry Pi
- 将蜂鸣器添加到Raspberry Pi 5英寸显示屏
- 对Raspberry Pi进行编程以进行CCTV运动检测
- 使用Raspberry Pi在OpenCV上进行运动检测
- 设置运动检测警报
- 监控CPU温度和使用情况
- 启动您的Pi CCTV Motion Detector
OpenCV是功能强大的工具,与Raspberry Pi结合使用可以为许多便携式智能设备打开大门。在我们之前的Raspberry Pi CCTV监视文章中,我们学习了如何使用RTSP从DVR获取实时CCTV视频并在Raspberry Pi上显示,请在进行操作之前先进行检查。在本文中,我们将学习如何利用OpenCV的功能,并在我们的现场CCTV录像中构建Raspberry Pi运动检测系统。如果您没有安装CCTV,您仍然可以通过将USB摄像机直接连接到Pi来构建Raspberry Pi监视系统。如果您不是Pi和Python的忠实拥护者,可以使用ESP32构建类似的东西,有关更多详细信息,请参阅ESP32 Wi-Fi门铃。
我们将编写一个Python脚本,该脚本可以同时监视所有四个CCTV摄像机的任何活动(运动)。如果在任何相机上检测到活动,我们的Raspberry Pi将自动切换到该特定的相机屏幕,并突出显示发生了哪些活动,所有这些都只需1.5秒即可实时进行。我还添加了一个警报功能,例如蜂鸣器,可以通过检测到活动蜂鸣来向用户发出警报。但是您可以轻松地扩大规模以发送消息或电子邮件,否则就不行!令人兴奋的权利!让我们开始吧
使用Buster和OpenCV设置Raspberry Pi
我正在使用运行有Buster OS的Raspberry Pi 3 B +,OpenCV的版本是4.1。如果您是全新手,请按照以下教程进行操作。
目标是使您的Pi做好准备并进行开发。可以在Pi上安装任何版本的Raspbian OS,但请确保OpenCV的版本为4.1或更高版本。您可以按照上面的教程来编译您的OpenCV,这将花费几个小时,但是对于繁重的项目而言更可靠,或者使用以下命令直接从pip进行安装。
$ pip install opencv-contrib-python == 4.1.0.25
如果您是第一次使用pip安装OpenCV,则还必须安装其他依赖项。为此,请使用以下命令。
$ sudo apt-get安装libavcodec-dev libavformat-dev libswscale-dev libv4l-dev $ sudo apt-get安装libxvidcore-dev libx264-dev $ sudo apt-get安装libatlas-base-dev gfortran $ sudo apt-get安装libhdf5- dev libhdf5-serial-dev libhdf5-103 $ sudo apt-get install libqtgui4 libqtwebkit4 libqt4-test python3-pyqt5
我们已经建立了许多Raspberry Pi OpenCV项目,您也可以查看更多灵感。
将蜂鸣器添加到Raspberry Pi 5英寸显示屏
在硬件方面,除了5英寸显示屏和蜂鸣器外,我们没有多少其他东西。在将5英寸显示器与Raspberry Pi接口连接之后,我们可以将蜂鸣器直接安装到显示器的背面,该显示器为我们扩展了一些GPIO引脚。我已经连接了我的Buzzer,如下所示-
如果您有兴趣利用更多的I / O引脚,则下面的引脚说明将很有用。如您所见,在扩展引脚中,大多数引脚都由Display本身用于触摸屏界面。但仍然有3、5、7、8、10、11、12、13、15、16和24引脚没有连接,我们可以将其用于自己的应用程序。在本教程中,我将蜂鸣器连接到GPIO 3。
对Raspberry Pi进行编程以进行CCTV运动检测
该项目的完整python脚本位于页面底部,但让我们讨论代码的每个部分以了解其工作原理。
使用RTSP在Raspberry Pi上监视多个摄像机而不会出现延迟
进行这项工作的挑战性部分是减少Raspberry pi的负载,以避免流式传输的滞后。最初,我尝试在所有四个摄像头之间切换以寻找运动,但动作非常缓慢(约10秒)。因此,我将所有四个摄像机合并为一个图像,并对该图像进行了所有运动检测活动。我编写了两个功能,分别是创建相机和读取相机。
的 创建相机 功能用于与其相应的通道号打开凸轮。请注意,RTSP URL以“ 02”结尾,这表示我正在使用子流视频提要,其分辨率较低,因此读取速度更快。另外,您使用的视频编解码器的类型也有助于提高速度,我尝试了不同的代码,发现FFMPEG是所有的禁食。
def create_camera(channel):rtsp =“ rtsp://” + rtsp_username +“:” + rtsp_password +“ @” + rtsp_IP +“:554 / Streaming / channels /” + channel +“ 02”#更改IP以适合yours cap = cv2.VideoCapture(rtsp,cv2.CAP_FFMPEG)cap.set(3,cam_width)#宽度的ID号为3 cap.set(4,cam_height)#高度的ID号为480 cap.set(10,100 )#亮度的ID号是10个返回盖
在 读取照相机 功能中,我们将读取所有四个凸轮,即cam1,cam2,cam3和cam4,以将它们全部组合成一个称为 Main_screen的 图像。准备好此主屏幕后,我们将在此图像上完成所有OpenCV工作。
def read_camera():成功,current_screen = cam1.read()Main_screen =当前屏幕成功,current_screen = cam2.read()Main_screen =当前屏幕成功,current_screen = cam3.read()Main_screen =当前屏幕成功,current_screen = cam4.read()主屏幕=当前屏幕返回(主屏幕)
将所有四个凸轮组合在一起的主屏幕图像将如下图所示。
使用Raspberry Pi在OpenCV上进行运动检测
现在我们已经准备好图像,我们可以从运动检测开始。在 while循环中 ,我们首先读取两个不同的帧,即frame1和frame2,然后将它们转换为灰度
frame1 = read_camera()#读取第一帧greyImage_F1 = cv2.cvtColor(frame1,cv2.COLOR_BGR2GRAY)#转换为灰色frame2 = read_camera()#读取第二帧grayImage_F2 = cv2.cvtColor(frame2,cv2.COLOR_BGR2GRAY)
然后,我们在这两个图像之间进行区别,以查看发生了什么变化,并使用阈值将所有发生变化的地方归为一组,有点像斑点。为避免尖锐边缘,对图像进行模糊处理和扩大通常也是很常见的。
diffImage = cv2.absdiff(grayImage_F1,grayImage_F2)#获得差异-这很酷blurImage = cv2.GaussianBlur(diffImage,(5,5),0)_,thresholdImage = cv2.threshold(blurImage,20,255,cv2.THRESH_BINARY )dilatedImage = cv2.dilate(thresholdImage,kernal,iterations = 5)
下一步是找到计数器并检查每个计数器的面积,通过找到面积,我们可以算出运动的幅度。如果面积大于变量 motion_detected中 的指定值,则我们将其视为一项活动,并在更改周围绘制一个框以向用户突出显示。
轮廓,_ = cv2.findContours(dilatedImage,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)#find轮廓是轮廓中轮廓的魔术函数:#对于检测到的每个变化(x,y,w,h)= cv2.boundingRect (轮廓)#获取如果cv2.contourArea(轮廓)> motion_threshold:cv2.rectangle(frame1,(x,y),(x + w,y + h),(255,255,0)找到变化的位置,1)display_screen = find_screen()
函数 find_screen() 用于查找活动在四个摄像机之间发生的位置。我们可以发现,因为我们知道运动的x和y值。我们将这些x和y值与每个屏幕的位置进行比较,以查找哪个屏幕进行了活动,然后再次裁剪该特定屏幕,以便可以将其显示在pi触摸屏上。
def find_screen():如果(x <cam_width):如果(y <cam_height):屏幕= frame1 print(“凸轮屏幕1中的活动”)否则:screen = frame1 print(“凸轮屏幕2中的活动”)else:如果(y <cam_height):屏幕= frame1打印(“凸轮屏幕3中的活动”)否则:screen = frame1打印(“凸轮屏幕4中的活动”)返回(屏幕)
设置运动检测警报
一旦知道在哪个屏幕上检测到运动,就可以轻松添加所需的任何类型的警报。在这里,我们将蜂鸣连接到GPIO 3.蜂鸣器 如果 如果在屏幕3和增量称为变量检测语句检查运动 trig_alarm 。您可以检测到您选择的任何屏幕,甚至可以检测多个屏幕。
如果[[x> cam_width)和[y
如果 trig_alarm 的值大于3,我们将蜂鸣一次。进行此计数的原因是,有时我会注意到阴影或鸟类创建了虚假警报。因此,只有在连续活动3帧的情况下,我们才会收到警报。
if(trig_alarm> = 3):#等待连续3次运动#蜂鸣器GPIO。输出(BUZZER,1)time.sleep(0.02)GPIO.output(BUZZER,0)trig_alarm = 0
监控CPU温度和使用情况
系统缩进工作24x7,因此Pi可能会变得很热,因此我决定通过在屏幕上显示这些值来监视温度和CPU使用率。我们已经使用gpiozero库获得了此信息。
cpu = CPUTemperature()负载= LoadAverage()cpu_temperature = str((cpu.temperature)// 1)load_average = str(load.load_average)#print(cpu.temperature)#print(load.load_average)cv2.putText(display_screen ,cpu_temperature,(250,250),cv2.FONT_HERSHEY_SIMPLEX,0.4,(0,0,255),1)cv2.putText(display_screen,load_average,(300,250),cv2.FONT_HERSHEY_SIMPLEX,0.4,(0,255,0),2)
启动您的Pi CCTV Motion Detector
我已经测试了好几天,以收集它,并且每次都可以使用,在我损坏一台相机之前,这确实是一个有趣的构建,