opencv是一个强大的工具,结合raspberrypi可以打开许多便携式智能设备的大门,我们将学习如何利用opencv的强大功能并在我们的实时闭路电视画面上构建一个raspberrypi运动检测系统。
我们将编写一个 python 脚本,它可以同时监控所有四个闭路电视摄像机的任何活动(运动)。如果在任何摄像头上检测到活动,我们的 raspberry pi 将自动切换到该特定摄像头屏幕并突出显示发生了哪些活动,所有这些都是实时的,只有 1.5 秒的延迟。我还添加了一个警报功能,例如蜂鸣器,如果检测到活动,它可以通过蜂鸣声提醒用户。但是您可以轻松地将其放大以发送消息或电子邮件或其他什么!令人兴奋的权利!让我们开始吧
使用 buster 和 opencv 设置 raspberry pi
我正在使用运行 buster os 的 raspberry pi 3 b+,opencv 的版本是 4.1。如果您是新手,请先按照以下教程开始操作。
树莓派入门
在树莓派上安装 opencv
raspberry pi 上的 rtsp cctv 录像监控
目标是让您的 pi 启动并准备好进行开发。可以在您的 pi 上安装任何版本的 raspbian os,但请确保 opencv 的版本为 4.1 或更高版本。您可以按照上面的教程编译您的 opencv,这将花费数小时,但对于繁重的项目更可靠,或者直接使用以下命令从 pip 安装它。
$ pip install opencv-contrib-python==4.1.0.25
如果您是第一次使用 pip 安装 opencv,则还必须安装其他依赖项。为此,请使用以下命令。
$ sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev$ sudo apt-get install libxvidcore-dev libx264-dev$sudo apt-get install libatlas-base-dev gfortran$ sudo apt-get install 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 英寸显示器与树莓派接口后,我们可以直接将蜂鸣器安装在显示器的背面,为我们扩展了一些 gpio 引脚。我已经连接了我的蜂鸣器,如下所示-
如果您对使用更多 i/o 引脚感兴趣,那么下面的引脚描述将很有用。正如您在扩展引脚中看到的那样,大多数引脚都被显示器本身用于触摸屏界面。但是,我们仍然有没有连接的引脚 3、5、7、8、10、11、12、13、15、16 和 24,我们可以将其用于我们自己的应用程序。在本教程中,我将蜂鸣器连接到 gpio 3。
为闭路电视运动检测编程树莓派
这个项目的完整 python 脚本可以在这个页面的底部找到,但是让我们讨论代码的每个部分以了解它是如何工作的。
使用 rtsp 在 raspberry pi 上无延迟监控多个摄像头
完成这项工作的挑战性部分是减少 raspberry pi 上的负载以避免流式传输延迟。最初,我尝试在所有四个摄像机之间切换以寻找运动,但它非常滞后(大约 10 秒)。所以我将所有四个摄像头组合成一个图像,并在该图像上进行所有运动检测活动。我写了两个函数,分别是创建相机和读取相机。
创建相机功能用于打开带有相应通道号的凸轮。请注意,rtsp url 以“02”结尾,这意味着我正在使用分辨率较低的子流视频源,因此阅读速度更快。此外,您使用的视频编解码器类型也有助于提高速度,我尝试了不同的编码,发现 ffmpeg 是所有编码中最快速的。
def create_camera(频道): rtsp = rtsp:// + rtsp_username + : + rtsp_password + @ + rtsp_ip + :554/streaming/channels/ + channel + 02 #更改 ip 以适合您的 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 [:cam_height, :cam_width, :3] = current_screen 成功,current_screen = cam2.read() main_screen[cam_height:cam_height*2, :cam_width, :3] = current_screen 成功,current_screen = cam3.read() main_screen[:cam_height, cam_width:cam_width*2, :3] = current_screen 成功,current_screen = cam4.read() main_screen[cam_height:cam_height*2, cam_width:cam_width*2, :3] = current_screen 返回(主屏幕)
组合了所有四个凸轮的主屏幕图像将如下图所示。
使用 raspberry pi 在 opencv 上进行运动检测
现在我们已经准备好图像,我们可以从运动检测开始。在while 循环中,我们首先读取两个不同的帧,即 frame1 和 frame2,然后将它们转换为灰度
frame1 = read_camera() #读取第一帧grayimage_f1 = cv2.cvtcolor(frame1, cv2.color_bgr2gray) # 转换为灰色frame2 = read_camera() #读取第2帧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中的指定值,则我们将其视为活动并在更改周围绘制一个框以向用户突出显示它。
contours, _ = cv2.findcontours (dilatedimage, cv2.retr_tree, cv2.chain_approx_simple) #查找轮廓是一个神奇的函数对于轮廓中的轮廓:#对于检测到的每个变化 (x,y,w,h) = cv2.boundingrect(contour) #获取发现变化的位置 如果 cv2.contourarea(contour) > 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 触摸屏上。
定义查找屏幕(): 如果(x < cam_width): 如果(y < cam_height): 屏幕 = frame1 [0:cam_height, 0:cam_width] print(凸轮屏幕 1 中的活动) 别的: 屏幕 = frame1[cam_height:cam_height*2, :cam_width] print(凸轮屏幕 2 中的活动) 别的: 如果(y cam_width) 和 (y=3):#wait for conts 3 动作 #按蜂鸣器 gpio.输出(蜂鸣器,1) time.sleep(0.02) gpio.输出(蜂鸣器,0) 触发警报 =0
监控 cpu 温度和使用情况
该系统旨在 24x7 全天候工作,因此 pi 会变得非常热,因此我决定通过在屏幕上显示这些值来监控温度和 cpu 使用率。我们已经使用 gpiozero 库获得了这些信息。
cpu = cpu温度() 负载 = 平均负载() cpu_temperature = str((cpu.temperature)//1) load_average = str(load.load_average) #print (cpu.温度) #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 运动探测器
我已经测试了好几天来收集它,它每次都能正常工作,这真的是一个有趣的构建,直到我损坏了一台相机,更多关于它的内容以及下面的视频中的详细工作。但是这个系统是可靠的,我很惊讶地看到 pi 能顺利处理所有这些黄油。
#!/usr/bin/env python3
导入简历2
将 numpy 导入为 np
进口时间
导入 rpi.gpio 作为 gpio
从 gpiozero 导入 cputemperature, loadaverage
#输入 cctv 的凭据
rtsp_username = 管理员
rtsp_password = aswinth347653
rtsp_ip = 192.168.29.100
cam_width = 352 #设置为来自 dvr 的传入视频的分辨率
cam_height = 288 #设置为来自 dvr 的传入视频的分辨率
motion_threshold = 1000 #降低此值以增加灵敏度
cam_no = 1
触发警报 =0
gpio.setmode(gpio.bcm)
gpio.setwarnings (假)
蜂鸣器 = 3
gpio.setup(蜂鸣器,gpio.out)
def create_camera(频道):
rtsp = rtsp:// + rtsp_username + : + rtsp_password + @ + rtsp_ip + :554/streaming/channels/ + channel + 02 #更改 ip 以适合您的
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
返回帽
def read_camera ():
成功,current_screen = cam1.read()
main_screen [:cam_height, :cam_width, :3] = current_screen
成功,current_screen = cam2.read()
main_screen[cam_height:cam_height*2, :cam_width, :3] = current_screen
成功,current_screen = cam3.read()
main_screen[:cam_height, cam_width:cam_width*2, :3] = current_screen
成功,current_screen = cam4.read()
main_screen[cam_height:cam_height*2, cam_width:cam_width*2, :3] = current_screen
返回(主屏幕)
定义查找屏幕():
如果(x < cam_width):
如果(y cam_width) 和 (y=3):#wait for conts 3 动作
#按蜂鸣器
gpio.输出(蜂鸣器,1)
time.sleep(0.02)
gpio.输出(蜂鸣器,0)
触发警报 =0
cpu = cpu温度()
负载 = 平均负载()
cpu_temperature = str((cpu.temperature)//1)
load_average = str(load.load_average)
#print (cpu.温度)
#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)
打印(trig_alarm)
暗淡 = (800, 480)
full_frame = cv2.resize (display_screen,dim,interpolation=cv2.inter_area)
cv2.namedwindow(aisha, cv2.window_normal)
cv2.setwindowproperty('aisha', cv2.wnd_prop_fullscreen, cv2.window_fullscreen)
cv2.imshow(aisha,full_frame)
如果 cv2.waitkey(1) & 0xff == ord('p'):
cam1.release()
cam2.release()
cam3.release()
cam4.release()
cv2.destroyallwindows()
休息
我国通信设备2012年出口额达1493亿美元 增15%
Samson发布了众多产品构成完整的信号链
Winfor、WPF,该如何选择?
Chrome OS未来会比Android更重要
红米Pro2、小米7、小米6Plus最新消息汇总:红米Pro2、小米7、小米6Plus配置性能价格提前看,你会买谁?
利用OpenCV构建一个RaspberryPi运动检测系统
氢动力汽车和电动汽车究竟谁更胜一筹
诺基亚推出了一个全新的Wi-Fi 6产品Beacon 6
采用CPLD的光伏逆变器锁相及保护电路设计
中国移动12月净增5G用户1762.1万,但是整体用户依然出现流失
MAX1454 高集成模拟传感器
回顾市委书记李强调研华虹集团上海集成电路研发中心的内容介绍
智能小镇再加码,该如何布局?
贴片光耦OR-1009规格参数、规格书、特性、应用以及选型
关于利用MATLAB/Simulink 锂电池建模的步骤分析
智慧物流有哪些领域的应用
嵌入式系统的发展历程
ARM的USB连机通讯
量子计算发展速度很快 阿里达摩院亮剑量子计算
蓝牙网格技术让蓝牙成为物联网(IoT)通信的主要标准迈出了重要的一步