发帖
4 1 0

智能家居新玩法:BW21-CBV人脸识别接入Home Assistant

shawn
论坛元老

6

主题

35

回帖

4308

积分

论坛元老

积分
4308
小安派·BW21-CBV-KIt 107 4 2025-3-24 15:21:13

场景

本文将介绍如何利用BW21-CBV人脸识别套件,实现智能家居的两个有趣场景:

  1. 室内人脸识别欢迎回家: 在入户门内安装BW21-CBV套件,通过人脸识别判断回家的人是谁,并将识别结果推送至Home Assistant (HA) 平台。HA可以根据识别到的人员,播放不同的欢迎语,实现个性化的智能家居体验。
  2. 室外人脸检测安防提醒: 在入户门外安装BW21-CBV套件,当检测到有人靠近时,将抓拍的图片推送给HA平台。结合HA的图片处理能力,甚至可以接入GPT等图像识别服务,分析来访者信息并推送相关提醒,提升家居安全性。

实现思路

由于笔者不太熟悉C++,因此在方案选择上,以能够最大程度复用现有资源和代码为原则。对于人脸识别部分,优先考虑使用BW21-CBV自带的人脸识别示例,目标是能够获取识别到的人脸姓名。

在将识别结果推送到HA平台方面,常见的方案有MQTT和Web API。虽然MQTT具有实时性高的优点,但考虑到HA的MQTT功能需要安装额外的第三方组件,并且运行HA的树莓派3资源相对有限,为了尽量减少资源占用和简化配置,最终选择了使用HA的Web API进行数据推送。Web API的优势在于无需额外安装组件,只需要在HA账户中生成一个长期有效的访问令牌(Long-Lived Access Token)即可。

代码实现

代码实现主要采用RTSPFaceRecognition示例,需要我们编写的两个关键部分是:向HA发送POST请求和处理BW21-CBV的人脸识别结果。

1. 使用WiFiClient发送POST请求

BW21-CBV官方示例中,虽然使用了POST方法,但其数据通常是通过GET方式传递的。因此,我们需要自定义一个函数,使用 WiFiClient库来构建并发送带有JSON数据的POST请求。

#include <WiFiClient.h>
#include <ArduinoJson.h>

const char* kHostname = "your_home_assistant_ip_or_domain"; // 替换为你的Home Assistant IP地址或域名
const int kPort = 8123; // Home Assistant 默认端口
const char* kPath = "/api/states/sensor.face_recognition"; // 你希望更新的HA实体ID
const char* kToken = "your_long_lived_access_token"; // 替换为你的HA长效访问令牌

WiFiClient wifiClient;
StaticJsonDocument doc; // 根据实际数据大小调整

void hapost() {
  if (wifiClient.connect(kHostname, kPort)) {
    doc["state"] = facename; // 将识别到的人名设置为HA实体的状态

    String jsonString;
    serializeJson(doc, jsonString);

    wifiClient.println("POST " + String(kPath) + " HTTP/1.1");
    wifiClient.println("Host: " + String(kHostname));
    wifiClient.println("Content-Type: application/json");
    wifiClient.println("Authorization: Bearer " + String(kToken));
    wifiClient.println("Content-Length: " + String(jsonString.length()));
    wifiClient.println("Connection: keep-alive");
    wifiClient.println(); // 空行表示HTTP头部结束
    wifiClient.print(jsonString); // 发送JSON数据

    Serial.println("Data sent to Home Assistant");
  } else {
    Serial.println("Failed to connect to Home Assistant");
  }
  wifiClient.stop(); // 关闭连接

2. 处理人脸识别结果

BW21-CBV在检测到人脸后可能会产生较多的识别结果回调。如果不加以处理,频繁的HTTP推送可能会导致设备失去响应。为了解决这个问题,我们在人脸识别结果处理函数(假设为 FRPostProcess)中进行了如下优化:

String _facename = ""; // 保存上一次识别到的人名
String facename = "";  // 保存当前识别到的人名
int facesta = 0;     // 标记是否检测到新人脸

void FRPostProcess(FaceRecognition::FRResult& result) {
  if (result.isDetected()) {
    for (size_t i = 0; i < result.face_count(); ++i) {
      FaceRecognition::FRItem item = result.get(i);
      if (i == 0) { // 只取第一个识别结果
        _facename = facename;
        facename = item.name();
        facesta = 1;
        break; // 找到第一个后跳出循环
      }
    }
  } else {
    facename = "unknown"; // 未检测到人脸
    facesta = 1;
  }
}

3. 在Loop函数中上报数据

在主循环函数 loop()中,我们根据 facename的变化来判断是否需要向HA发送数据:

void loop() {
  // ... 其他代码 ...

  if (facesta == 1) { // 只有当检测到新人脸时才进行上报
    if (facename != _facename) {
      if (facename != String("unknown")) {
        printf("Face name:\t %s \n\r", facename.c_str());
        hapost();
      } else if (_facename != String("unknown")) {
        // 如果之前识别到人,现在变成unknown,也上报一次
        printf("Face name:\t %s \n\r", facename.c_str());
        hapost();
      }
      _facename = facename; // 更新上一次的人名
    }
    facesta = 0; // 重置标志位
  }

  // ... 其他代码 ...
}

4.自动加载人脸数据及开启畸变修正

void setup() {
  // ... 其他初始化代码 ...

  CameraSetting configCam;

  facerecog.setResultCallback(FRPostProcess);
  // 注册人脸识别回调函数
  facerecog.restoreRegisteredFace();
  // 开启畸变修正
  configCam.setLDC(1);
}

效果测试

按照上述步骤配置完成后,当BW21-CBV识别到人脸后,你可以在Home Assistant中看到名为 sensor.face_recognition的实体,其状态会显示识别到的人名,你可以基于这个实体创建自动化。让我们简单测试下看看效果:

看起来还不错,响应速度不比mqtt慢,完全达到预期目标。

结束

既然三位巨头已经同框,而且他们之间还有些分歧,那么让他们每人给我们讲几句吧,也希望现实中三巨头早日同框!

BW21-CBV->ha->gemini->edge-tts->homepod,目前在实现场景一“欢迎回家”的效果。

──── 1人觉得很赞 ────

使用道具 举报

2025-3-24 15:40:38
这个视频趣味性贼高~
2025-3-24 17:18:23
斩首行动吗,核弹自动跟踪
2025-3-24 23:00:50
非常棒
打卡
您需要登录后才可以回帖 立即登录
高级模式
返回
统计信息
  • 会员数: 28435 个
  • 话题数: 40513 篇