一键三连:树莓派视频监控、人脸识别抓拍与上传(附快速安装脚本)

距上次研究 树莓派编译构建 OpenCV C++ 项目 之后,我最终完成了一个强大的树莓派 NodeJs 应用—— pilib-capture,可以单程序实现:

  • 远程视频监控
  • 人脸识别抓拍
  • 抓拍后上传

启动方式也很简单,单条指令即可运行:

sudo LOCAL_PORT=8080 pilib-capturer

pilib-capture 程序已经部署到了实际生产环境,用于监控进出人流量

当然实际部署的时候,基于用户隐私考虑,人脸抓拍只做计数,不做存储。

安装说明戳 这里

pilib-capture 架构图如下:

  • 采用 USB 摄像头作为视频输入源,比网上流传的主板 CAM 接口摄像头性价比更高。
  • 采用 NodeJS 编写服务器,异步架构,事件驱动,并发量和 HTTP 支持比网上流传的 Python 版本服务器更好。
  • NodeJS 通过 cpp 绑定直接调用 OpenCV 库,不会损失视频处理的性能。
  • 开放 HTTP 控制端口和 AVI 视频串流端口,浏览器打开网页即可操作。

USB 摄像头调用

在 NodeJS 里,可以用 opencv4nodejs 库调用 OpenCV 提供的摄像头方法 cv.VideoCapture()

VideoCapture 类核心定义如下:

export class VideoCapture {
  constructor(filePath: string);
  constructor(devicePort: number);
  read(): Mat;

constructor() 构造函数接受设备路径参数,可以是视频文件路径,也可以是 webcam 设备 id。

调用 .read() 方法,会返回当前捕获的帧 Mat 对象。Mat 即矩阵(matrix),是 opencv4nodejs 里的图形对象,包含所有的图形操作方法。

摄像头调用核心代码:

import * as cv from 'opencv4nodejs';

// 打开摄像头
const cam = new cv.VideoCapture(0);
// 从摄像头读取一帧
const mat = this.cam.read();

摄像头控制参数戳 这里

OpenCV 人脸识别

可以用于树莓派的人脸识别方案有很多,比如 tensorFlow、dlib、OpenCV 等。

我在写 pilib-capturer 的时候,从实际应用场景、系统复杂度和树莓派性能出发考虑,并没有采用神经网络识别模型,而是采用了 OpenCV 自带的训练好的 基于 Haar 特征的人脸识别分类器

Haar 分类器人脸识别核心代码:

import * as cv from 'opencv4nodejs';

const cam = new cv.VideoCapture(0);
const mat = this.cam.read();

// 载入分类器模型
const classifier = new cv.CascadeClassifier(cv.HAAR_FRONTALFACE_ALT2);

// 多尺度检测,定位人脸区域
const detection = classifier.detectMultiScale(mat);

// detection.objects 包含了所有人脸区域的位置信息
console.log(detection.objects);

// 还可以调 drawRectangle 方法,给人脸区域标记红框
detection.objects.forEach(r => {
  mat.drawRectangle(r, new cv.Vec3(0, 0, 255));
});

实际测试中,发现 Haar 分类器存在抖动,偶尔会出现一两帧的误识别,把一些相似的图形识别成了人脸。

要解决这个问题,最直观的办法就是 提高分类器准确度,但这并不容易...

所以,在 pilib-capturer 里改用 一阶低通滤波 的方式去抖动。一两帧的误识别属于高频信号,可以被一阶低通滤波很自然地排除掉。

目前支持 CAPTURER_LPF_FA(滤波系数) 和 CAPTURER_LPF_THRESHOLD(滤波判断阈值) 两个参数调节滤波效果。

具体配置戳 这里

HTTP 控制接口

在 HTTP 的处理上,pilib-capturer 引用了我的另一个 NodeJs 模块:ah-server

ah-server 是一个非常轻量的可扩展的 web 服务器框架,使用体验类似 egg.js。使用框架能力,可以让 HTTP 端口处理轻松一点。

目前 pilib-capturer 只提供了“拍照”接口:GET http://{hostname}/shot。通过这个接口,可以控制程序拍照和立即上传。

接口核心代码如下:

import { Controller, IContext, IControllerMapperItem } from 'ah-server';

export class ShotController extends Controller {
  // 定义路由
  mapper: IControllerMapperItem[] = [
    {
      path: '/shot',
      method: 'GET',
      handler: this.shot,
    },
  ];

  async shot(ctx: IContext) {
    ctx.set({ 'Content-Type': 'image' });

    // 返回图片二进制,以便浏览器可以直接打开查看
    ctx.body = this.snapshot.toBuf().buf;
  }
}

ah-server.Controller 是 ah-sever 的路由控制器基类,扩展这个类就可以访问请求的所有上下文信息。

Avi 视频串流接口

既然树莓派接入了网络,而且连接了 USB 摄像头,那就可以做“远程视频监控”了。最初我做这个功能是为了方便实时调试人脸识别抓拍,但发现完全可以包装成视频串流接口,实现类似“直播”、“远程视频监控”的功能。

当有客户端(比如 VLC 播放器)请求视频串流接口(GET /liveStream)的时候,pilib-capturer 会启动一个 ffmpeg 进程,用来把摄像头的图片帧封装成 avi 格式,然后以串流的形式返回客户端。客户端收到 AVI 串流,就可以收看“直播”了。

ffmpeg 核心参数如下:

# -c:v copy 表示 直接复制到 avi 容器,不要编码(性能考虑)
# "-i -" 和 命令末尾的 "-" 表示管道输入、管道输出(与 NodeJS 进程间通信)
ffmpeg -y -f image2pipe -s 320x240 -r 20 -i - -an -c:v copy -f avi -

图像上传接口

pilib-capturer 从摄像头识别到人脸后,可以配置成:

  • 上传到指定地址
  • 保存到本地

由 UPLOAD_ENDPOINT 启动参数控制。默认保存目录是本地 ./output,但如果配置成 http 或 https 开头的地址,则会以 POST 请求的方式将抓拍照发送过去。

具体配置戳 这里

扩展资料


  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值