发帖
2 0 0

【BW21-CBV-Kit 开发板测评】手势和人脸的动态检测识别

无垠的广袤
金牌会员

15

主题

17

回帖

2385

积分

金牌会员

积分
2385
QQ
小安派·BW21-CBV-KIt 37 2 10 小时前

【BW21-CBV-Kit 开发板测评】手势和人脸的动态检测识别

本文介绍了安信可 BW21-CBV-Kit 开发套件实现 手势识别人脸识别 的测试情况。

工程测试

介绍官方 Demo (手势监测 HandGestureDetection 和人脸识别 RTSPFaceRecegnition)测试流程及效果展示。

NN_HG_Face.jpg

手势识别

通过加载 NN (Neural Network, 神经网络) 训练模型,实现手势的跟踪、提取、模拟、识别。

代码

注意修改 WiFi 名称和密码

#include "WiFi.h"
#include "StreamIO.h"
#include "VideoStream.h"
#include "RTSP.h"
#include "NNGestureDetection.h"
#include "VideoStreamOverlay.h"

#define CHANNEL   0
#define CHANNELNN 3

// Customised resolution for NN
#define NNWIDTH  192
#define NNHEIGHT 192

VideoSetting config(VIDEO_FHD, 30, VIDEO_H264, 0);
VideoSetting configNN(NNWIDTH, NNHEIGHT, 10, VIDEO_RGB, 0);
NNGestureDetection gesturedetect;
RTSP rtsp;
StreamIO videoStreamer(1, 1);
StreamIO videoStreamerRGBGD(1, 1);

char ssid[] = "xxx";    // your network SSID (name)
char pass[] = "xx";         // your network password
int status = WL_IDLE_STATUS;

IPAddress ip;
int rtsp_portnum;

void setup()
{
    Serial.begin(115200);

    // Attempt to connect to Wifi network:
    while (status != WL_CONNECTED) {
        Serial.print("Attempting to connect to WPA SSID: ");
        Serial.println(ssid);
        status = WiFi.begin(ssid, pass);

        // wait 2 seconds for connection:
        delay(2000);
    }

    ip = WiFi.localIP();

    // Configure camera video channels with video format information
    // Adjust the bitrate based on your WiFi network quality
    config.setBitrate(2 * 1024 * 1024);    // Recommend to use 2Mbps for RTSP streaming to prevent network congestion
    Camera.configVideoChannel(CHANNEL, config);
    Camera.configVideoChannel(CHANNELNN, configNN);
    Camera.videoInit();

    // Configure RTSP with corresponding video format information
    rtsp.configVideo(config);
    rtsp.begin();
    rtsp_portnum = rtsp.getPort();

    // Configure Gesture Detection model
    // Select Neural Network(NN) task and models
    gesturedetect.configVideo(configNN);
    gesturedetect.modelSelect(GESTURE_DETECTION, NA_MODEL, NA_MODEL, NA_MODEL, NA_MODEL, NA_MODEL, DEFAULT_PALMDETECT, DEFAULT_HANDLANDMARK);
    gesturedetect.begin();

    // Configure StreamIO object to stream data from video channel to RTSP
    videoStreamer.registerInput(Camera.getStream(CHANNEL));
    videoStreamer.registerOutput(rtsp);
    if (videoStreamer.begin() != 0) {
        Serial.println("StreamIO link start failed");
    }
    // Start data stream from video channel
    Camera.channelBegin(CHANNEL);

    // Configure StreamIO object to stream data from RGB video channel to gesture detection
    videoStreamerRGBGD.registerInput(Camera.getStream(CHANNELNN));
    videoStreamerRGBGD.setStackSize();
    videoStreamerRGBGD.setTaskPriority();
    videoStreamerRGBGD.registerOutput(gesturedetect);
    if (videoStreamerRGBGD.begin() != 0) {
        Serial.println("StreamIO link start failed");
    }

    // Start video channel for NN
    Camera.channelBegin(CHANNELNN);

    // Start OSD drawing on RTSP video channel
    OSD.configVideo(CHANNEL, config);
    OSD.configTextSize(CHANNEL, 16, 32);
    OSD.begin();
    gesturedetect.drawHandRegion();
}

void loop()
{
    // Do nothing
}

上传

1.按住 BOOT(下载) 按钮的同时按一下 EN(复位)按钮,进入下载模式;

2.选择目标串口对应的端口号,点击 Download 按钮,待上传成功提示 Success,完成固件上传;

3.再次短按 EN 键复位,执行程序。

配置

上传完成后打开串口监视器,检测到 WiFi 并连接,输出 Camera 摄像头的 ip 地址,

WiFi_Pass.jpg

VLC 软件中输入 rtsp://192.168.1.104:554 实现 rtsp 推流。

rtsp_setting.jpg

效果

数字手势

HG_number.gif

动作手势

HG_action.gif

静态展示合集

HandGesture.jpg

人脸识别

使用 BW21-CBV-Kit 开发板识别检测到的人脸。

代码

详情参考:Neural Nework – Face Recognition – Realtek IoT/Wi-Fi MCU Solutions

#include "WiFi.h"
#include "StreamIO.h"
#include "VideoStream.h"
#include "RTSP.h"
#include "NNFaceDetectionRecognition.h"
#include "VideoStreamOverlay.h"

#define CHANNEL   0
#define CHANNELNN 3

// Customised resolution for NN
#define NNWIDTH  576
#define NNHEIGHT 320

VideoSetting config(VIDEO_FHD, 30, VIDEO_H264, 0);
VideoSetting configNN(NNWIDTH, NNHEIGHT, 10, VIDEO_RGB, 0);
NNFaceDetectionRecognition facerecog;
RTSP rtsp;
StreamIO videoStreamer(1, 1);
StreamIO videoStreamerFDFR(1, 1);
StreamIO videoStreamerRGBFD(1, 1);

char ssid[] = "xxx";    // your network SSID (name)
char pass[] = "xxx";        // your network password
int status = WL_IDLE_STATUS;

IPAddress ip;
int rtsp_portnum;

void setup()
{
    Serial.begin(115200);

    // Attempt to connect to Wifi network:
    while (status != WL_CONNECTED) {
        Serial.print("Attempting to connect to WPA SSID: ");
        Serial.println(ssid);
        status = WiFi.begin(ssid, pass);

        // wait 2 seconds for connection:
        delay(2000);
    }

    ip = WiFi.localIP();

    // Configure camera video channels with video format information
    // Adjust the bitrate based on your WiFi network quality
    config.setBitrate(2 * 1024 * 1024);    // Recommend to use 2Mbps for RTSP streaming to prevent network congestion
    Camera.configVideoChannel(CHANNEL, config);
    Camera.configVideoChannel(CHANNELNN, configNN);
    Camera.videoInit();

    // Configure RTSP with corresponding video format information
    rtsp.configVideo(config);
    rtsp.begin();
    rtsp_portnum = rtsp.getPort();

    // Configure Face Recognition model
    // Select Neural Network(NN) task and models
    facerecog.configVideo(configNN);
    facerecog.modelSelect(FACE_RECOGNITION, NA_MODEL, DEFAULT_SCRFD, DEFAULT_MOBILEFACENET);
    facerecog.begin();
    facerecog.setResultCallback(FRPostProcess);

    // Configure StreamIO object to stream data from video channel to RTSP
    videoStreamer.registerInput(Camera.getStream(CHANNEL));
    videoStreamer.registerOutput(rtsp);
    if (videoStreamer.begin() != 0) {
        Serial.println("StreamIO link start failed");
    }
    // Start data stream from video channel
    Camera.channelBegin(CHANNEL);

    // Configure StreamIO object to stream data from RGB video channel to face detection
    videoStreamerRGBFD.registerInput(Camera.getStream(CHANNELNN));
    videoStreamerRGBFD.setStackSize();
    videoStreamerRGBFD.setTaskPriority();
    videoStreamerRGBFD.registerOutput(facerecog);
    if (videoStreamerRGBFD.begin() != 0) {
        Serial.println("StreamIO link start failed");
    }

    // Start video channel for NN
    Camera.channelBegin(CHANNELNN);

    // Start OSD drawing on RTSP video channel
    OSD.configVideo(CHANNEL, config);
    OSD.begin();
}

void loop()
{
    if (Serial.available() > 0) {
        String input = Serial.readString();
        input.trim();

        if (input.startsWith(String("REG="))) {
            String name = input.substring(4);
            facerecog.registerFace(name);
        } else if (input.startsWith(String("DEL="))) {
            String name = input.substring(4);
            facerecog.removeFace(name);
        } else if (input.startsWith(String("RESET"))) {
            facerecog.resetRegisteredFace();
        } else if (input.startsWith(String("BACKUP"))) {
            facerecog.backupRegisteredFace();
        } else if (input.startsWith(String("RESTORE"))) {
            facerecog.restoreRegisteredFace();
        }
    }

    delay(2000);
    OSD.createBitmap(CHANNEL);
    OSD.update(CHANNEL);
}

// User callback function for post processing of face recognition results
void FRPostProcess(std::vector<FaceRecognitionResult> results)
{
    uint16_t im_h = config.height();
    uint16_t im_w = config.width();

    Serial.print("Network URL for RTSP Streaming: ");
    Serial.print("rtsp://");
    Serial.print(ip);
    Serial.print(":");
    Serial.println(rtsp_portnum);
    Serial.println(" ");

    printf("Total number of faces detected = %d\r\n", facerecog.getResultCount());
    OSD.createBitmap(CHANNEL);

    if (facerecog.getResultCount() > 0) {
        for (int i = 0; i < facerecog.getResultCount(); i++) {
            FaceRecognitionResult item = results[i];
            // Result coordinates are floats ranging from 0.00 to 1.00
            // Multiply with RTSP resolution to get coordinates in pixels
            int xmin = (int)(item.xMin() * im_w);
            int xmax = (int)(item.xMax() * im_w);
            int ymin = (int)(item.yMin() * im_h);
            int ymax = (int)(item.yMax() * im_h);

            uint32_t osd_color;
            if (String(item.name()) == String("unknown")) {
                osd_color = OSD_COLOR_RED;
            } else {
                osd_color = OSD_COLOR_GREEN;
            }

            // Draw boundary box
            printf("Face %d name %s:\t%d %d %d %d\n\r", i, item.name(), xmin, xmax, ymin, ymax);
            OSD.drawRect(CHANNEL, xmin, ymin, xmax, ymax, 3, osd_color);

            // Print identification text above boundary box
            char text_str[40];
            snprintf(text_str, sizeof(text_str), "Face:%s", item.name());
            OSD.drawText(CHANNEL, xmin, ymin - OSD.getTextHeight(CHANNEL), text_str, osd_color);
        }
    }
    OSD.update(CHANNEL);
}

上传完成后打开串口监视器,检测到 WiFi 并连接,输出 Camera 摄像头的 ip 地址,在 VLC 软件中输入 rtsp://192.168.253.1:554 实现 rtsp 推流。

将目标人脸对准摄像头,当监测到人脸并被红色线框选中时,在串口输入 REG=Bean 实现人名录入,此时线框颜色变为绿色,提示词指示对应的人物名字。

FaceRec_Bean.jpg

效果

动态识别

FaceRec_bean.gif

FR_Bean.gif

注意到人脸识别在距离较远时准确率更高,若人脸占据画面较大比例,则识别效果下降。此外,人脸识别程序在运行过程中,模块温度有明显升高,需要注意散热等问题。

可能因素包括:代码中设置的人脸信息采集分辨率为 192x192 ,面对动态画面的实际情况,采集样本不足,对于采集画面大小、复杂的人脸表情变化的应对能力有限;摄像头分辨率限制;处理器运算能力限制等。

改进方案:增加硬件算力、散热方案、扩充样本数量、增大训练迭代次数、改进模型。

注意:若串口输出错误信息 error: vipnn not applied 则需重新安装开发板程序包。

NN_error.jpg

总结

本文介绍了安信可 BW21-CBV-Kit 开发套件实现 手势识别人脸识别 以及动态监测的项目,并对测试结果和试验的实际表现进行分析,给出相应的可能存在的问题和对应的解决方案,为该项目的后续完善和改进提供了思路和参考。

──── 0人觉得很赞 ────

使用道具 举报

写的真好~必须加精支持
爱笑 发表于 2025-3-12 13:56
写的真好~必须加精支持

这个Demo好像支持多张人脸识别,后面尝试一下;计划设计适配一个PCB底座,扩展排针,再加上一些外设传感器,搭配3D外壳,让它更便携,提升拍摄画面的稳定性
您需要登录后才可以回帖 立即登录
高级模式
返回
统计信息
  • 会员数: 28067 个
  • 话题数: 39620 篇