用PythonFlask给树莓派监控加人脸识别Picamera2实战教程树莓派作为一款高性价比的单板计算机在智能监控领域有着广泛的应用场景。传统的监控方案往往只提供简单的视频流功能而结合现代计算机视觉技术我们可以实现更智能化的监控系统。本文将详细介绍如何利用Python生态中的Flask框架和最新的Picamera2库构建一个支持人脸识别和移动侦测的智能监控系统。1. 环境准备与硬件配置在开始编码之前我们需要确保硬件和软件环境都已正确配置。树莓派官方摄像头模块或兼容的USB摄像头均可用于本项目但官方摄像头模块通常能提供更好的性能和更低的CPU占用率。1.1 硬件连接与设置对于树莓派官方摄像头模块确保树莓派已关机轻轻抬起CSI接口的卡槽将摄像头排线插入CSI接口金属触点朝向远离HDMI接口的一侧按下卡槽锁定排线启用摄像头接口sudo raspi-config在菜单中选择Interface OptionsCamera选择启用后重启树莓派。验证摄像头是否工作libcamera-hello -t 0如果能看到摄像头实时画面说明硬件配置正确。1.2 软件依赖安装我们需要安装以下Python包pip install picamera2 flask opencv-python numpy python-telegram-bot对于人脸识别功能还需要安装dlib库sudo apt-get install cmake python3-dev pip install dlib2. 构建基础视频流服务Flask是一个轻量级的Python Web框架非常适合构建这样的监控系统。我们将首先创建一个基础的视频流服务。2.1 初始化Flask应用创建一个名为app.py的文件添加以下代码from flask import Flask, Response from picamera2 import Picamera2 import cv2 import numpy as np app Flask(__name__) picam2 Picamera2() config picam2.create_video_configuration(main{size: (640, 480)}) picam2.configure(config) picam2.start()2.2 实现视频流生成器添加生成视频帧的函数def generate_frames(): while True: frame picam2.capture_array() ret, buffer cv2.imencode(.jpg, frame) frame buffer.tobytes() yield (b--frame\r\n bContent-Type: image/jpeg\r\n\r\n frame b\r\n)2.3 创建视频流路由添加Flask路由以提供视频流app.route(/video_feed) def video_feed(): return Response(generate_frames(), mimetypemultipart/x-mixed-replace; boundaryframe) app.route(/) def index(): return html head title树莓派智能监控/title /head body h1实时监控/h1 img src/video_feed width640 height480 /body /html if __name__ __main__: app.run(host0.0.0.0, port5000, threadedTrue)运行应用后访问树莓派IP地址的5000端口即可看到实时视频流。3. 实现移动侦测功能移动侦测是监控系统的重要功能可以在检测到画面变化时触发警报或录像。3.1 背景减除算法OpenCV提供了几种背景减除算法这里使用MOG2fgbg cv2.createBackgroundSubtractorMOG2(history500, varThreshold16, detectShadowsTrue) def detect_motion(frame): gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) fgmask fgbg.apply(gray) _, thresh cv2.threshold(fgmask, 244, 255, cv2.THRESH_BINARY) contours, _ cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) motion_detected False for contour in contours: if cv2.contourArea(contour) 500: # 忽略小面积变化 motion_detected True break return motion_detected, frame3.2 集成移动侦测到视频流修改generate_frames函数以包含移动侦测def generate_frames(): while True: frame picam2.capture_array() motion_detected, processed_frame detect_motion(frame) if motion_detected: timestamp datetime.now().strftime(%Y%m%d_%H%M%S) cv2.imwrite(fmotion_{timestamp}.jpg, frame) # 这里可以添加通知逻辑 ret, buffer cv2.imencode(.jpg, processed_frame) frame buffer.tobytes() yield (b--frame\r\n bContent-Type: image/jpeg\r\n\r\n frame b\r\n)4. 添加人脸识别功能人脸识别可以为监控系统增加更多智能功能如识别已知人员或标记陌生人。4.1 加载人脸检测模型使用OpenCV的DNN模块加载Caffe模型prototxt deploy.prototxt model res10_300x300_ssd_iter_140000.caffemodel net cv2.dnn.readNetFromCaffe(prototxt, model)4.2 实现人脸检测函数def detect_faces(frame): (h, w) frame.shape[:2] blob cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0)) net.setInput(blob) detections net.forward() faces [] for i in range(0, detections.shape[2]): confidence detections[0, 0, i, 2] if confidence 0.5: # 置信度阈值 box detections[0, 0, i, 3:7] * np.array([w, h, w, h]) (startX, startY, endX, endY) box.astype(int) faces.append((startX, startY, endX-startX, endY-startY)) return faces4.3 在视频流中标记人脸修改generate_frames函数以标记检测到的人脸def generate_frames(): while True: frame picam2.capture_array() faces detect_faces(frame) for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (xw, yh), (0, 255, 0), 2) ret, buffer cv2.imencode(.jpg, frame) frame buffer.tobytes() yield (b--frame\r\n bContent-Type: image/jpeg\r\n\r\n frame b\r\n)5. 实现报警通知功能当检测到移动或陌生人脸时系统可以通过Telegram发送通知。5.1 配置Telegram机器人在Telegram中与BotFather对话创建新机器人获取API token和chat ID5.2 实现通知发送功能from telegram import Bot import asyncio TELEGRAM_TOKEN your_bot_token CHAT_ID your_chat_id async def send_telegram_alert(image_path, message): bot Bot(tokenTELEGRAM_TOKEN) with open(image_path, rb) as photo: await bot.send_photo(chat_idCHAT_ID, photophoto, captionmessage) def send_alert(image, message): timestamp datetime.now().strftime(%Y%m%d_%H%M%S) image_path falert_{timestamp}.jpg cv2.imwrite(image_path, image) asyncio.run(send_telegram_alert(image_path, message))5.3 集成报警到主逻辑在检测到重要事件时调用报警功能def generate_frames(): known_faces load_known_faces() # 需要事先实现加载已知人脸的功能 while True: frame picam2.capture_array() motion_detected, _ detect_motion(frame) faces detect_faces(frame) if motion_detected and faces: unknown_faces [] for face in faces: if not recognize_face(frame, face, known_faces): # 需要实现人脸识别函数 unknown_faces.append(face) if unknown_faces: send_alert(frame, 检测到未知人员) ret, buffer cv2.imencode(.jpg, frame) frame buffer.tobytes() yield (b--frame\r\n bContent-Type: image/jpeg\r\n\r\n frame b\r\n)6. 性能优化与部署建议在实际部署时需要考虑系统性能和稳定性。6.1 性能优化技巧分辨率调整根据实际需要选择合适的分辨率config picam2.create_video_configuration(main{size: (640, 480)})帧率控制降低帧率可以减少CPU使用config picam2.create_video_configuration(main{size: (640, 480)}, controls{FrameRate: 15})硬件加速启用树莓派的硬件编码config picam2.create_video_configuration(main{size: (640, 480)}, encodehw)6.2 部署建议使用systemd管理服务确保意外退出后自动重启考虑使用nginx作为反向代理提高并发性能定期清理旧的截图和录像文件在高温环境下为树莓派添加散热措施# 示例systemd服务文件 [Unit] DescriptionRaspberry Pi Surveillance Service Afternetwork.target [Service] ExecStart/usr/bin/python3 /home/pi/app.py WorkingDirectory/home/pi StandardOutputinherit StandardErrorinherit Restartalways Userpi [Install] WantedBymulti-user.target7. 扩展功能思路基础功能实现后可以考虑以下扩展多摄像头支持使用多个树莓派构建分布式监控系统云端存储将重要事件视频上传到云存储深度学习模型替换为更精准的YOLO等目标检测模型门禁集成与电子门锁联动实现智能门禁行为分析检测异常行为如跌倒、徘徊等实现这些扩展需要根据具体需求调整架构可能需要引入消息队列、数据库等组件。