esp-who github_muster分支human_face_recognition例程无法通过编译

哪来的野生bug
Posts: 2
Joined: Mon Jul 14, 2025 1:07 pm

esp-who github_muster分支human_face_recognition例程无法通过编译

Postby 哪来的野生bug » Tue Jul 15, 2025 12:06 am

硬件:esp32-s3,OV2460,微雪esp32-s3-lcd-2开发板
开发环境:linux,vscode,esp-idf v5.4.1

目标:复现human_face_recognition/lcd例程
问题描述:
esp-who/components/modules/ai/who_ai_utils.cpp中的draw_hollow_rectangle和draw_point函数老是编译不过(这两个函数在esp-who/components/esp-dl/esp-dl/vision/image/dl_image_draw.cpp中定义)

开始是调用传入的参数不对(好几个版本都没改),我已经修复
然后参数类型不对,我把const给删掉了
然后命名空间(dl::image)里面找不到类型和函数定义,改了CMakeLists.txt和命名空间
然后match不到使用那个模板(这两个是模板函数,但它们每个模板的所有参数类型都一样,我服了),然后调用手动指定了模板,在链接的时候又会报找不到这两个函数

一些复现步骤:
拉取esp-who:

Code: Select all

git clone -b github_master https://github.con/espressif/esp-who
在components下拉取esp-dl、esp-sr和esp32-camera

Code: Select all

git clone https://github.com/espressif/esp-dl
git clone https://github.com/espressif/esp-sr
git clone https://github.com/espressif/esp32-camera
esp-dl好像直接克隆的主目录下没有CMakeLists.txt,那就克隆v1.1的brach,注意要有human_face_detect_msr的什么模型的cpp的版本

修改esp-who/components/module/ai/who_ai_utils.cpp

Code: Select all

#include "who_ai_utils.hpp"

#include "esp_log.h"
#include "esp_camera.h"
#include "esp_heap_caps.h"

#include "dl_image.hpp"
#include "dl_image_define.hpp"

static const char *TAG = "ai_utils";

// +-------+--------------------+----------+
// |       |       RGB565       |  RGB888  |
// +=======+====================+==========+
// |  Red  | 0b0000000011111000 | 0x0000FF |
// +-------+--------------------+----------+
// | Green | 0b1110000000000111 | 0x00FF00 |
// +-------+--------------------+----------+
// |  Blue | 0b0001111100000000 | 0xFF0000 |
// +-------+--------------------+----------+

void draw_detection_result(uint16_t *image_ptr, int image_height, int image_width, std::list<dl::detect::result_t> &results)
{
    dl::image::img_t img;
    img.data = image_ptr;
    img.height = image_height;
    img.width = image_width;
    img.pix_type = dl::image::DL_IMAGE_PIX_TYPE_RGB565;

    uint16_t _red = 0b0000000011111000;
    uint16_t _green = 0b1110000000000111;
    uint16_t _blue = 0b0000111100000000;

    dl::image::pix_t red;
    red.data = &_red;
    red.type = dl::image::DL_IMAGE_PIX_TYPE_RGB565;

    dl::image::pix_t green;
    green.data = &_green;
    green.type = dl::image::DL_IMAGE_PIX_TYPE_RGB565;

    dl::image::pix_t blue;
    blue.data = &_blue;
    blue.type = dl::image::DL_IMAGE_PIX_TYPE_RGB565;

    int i = 0;
    for (std::list<dl::detect::result_t>::iterator prediction = results.begin(); prediction != results.end(); prediction++, i++)
    {
        dl::image::draw_hollow_rectangle<uint16_t>(img,
                                         DL_MAX(prediction->box[0], 0),
                                         DL_MAX(prediction->box[1], 0),
                                         DL_MAX(prediction->box[2], 0),
                                         DL_MAX(prediction->box[3], 0),
                                         (uint8_t)2,
                                         green);

        if (prediction->keypoint.size() == 10)
        {
            dl::image::draw_point<uint16_t>(img, DL_MAX(prediction->keypoint[0], 0), DL_MAX(prediction->keypoint[1], 0), 4, red); // left eye
            dl::image::draw_point<uint16_t>(img, DL_MAX(prediction->keypoint[2], 0), DL_MAX(prediction->keypoint[3], 0), 4, red); // mouth left corner
            dl::image::draw_point<uint16_t>(img, DL_MAX(prediction->keypoint[4], 0), DL_MAX(prediction->keypoint[5], 0), 4, green); // nose
            dl::image::draw_point<uint16_t>(img, DL_MAX(prediction->keypoint[6], 0), DL_MAX(prediction->keypoint[7], 0), 4, blue); // right eye
            dl::image::draw_point<uint16_t>(img, DL_MAX(prediction->keypoint[8], 0), DL_MAX(prediction->keypoint[9], 0), 4, blue); // mouth right corner
        }
    }
}

void draw_detection_result(uint8_t *image_ptr, int image_height, int image_width, std::list<dl::detect::result_t> &results)
{
    dl::image::img_t img;
    img.data = image_ptr;
    img.height = image_height;
    img.width = image_width;
    img.pix_type = dl::image::DL_IMAGE_PIX_TYPE_RGB888;

    uint8_t _red = 0xFF0000;
    uint8_t _green = 0x00FF00;
    uint8_t _blue = 0x0000FF;

    dl::image::pix_t red;
    red.data = &_red;
    red.type = dl::image::DL_IMAGE_PIX_TYPE_RGB888;

    dl::image::pix_t green;
    green.data = &_green;
    green.type = dl::image::DL_IMAGE_PIX_TYPE_RGB888;

    dl::image::pix_t blue;
    blue.data = &_blue;
    blue.type = dl::image::DL_IMAGE_PIX_TYPE_RGB888;

    int i = 0;
    for (std::list<dl::detect::result_t>::iterator prediction = results.begin(); prediction != results.end(); prediction++, i++)
    {
        dl::image::draw_hollow_rectangle<uint8_t>(img,
                                         DL_MAX(prediction->box[0], 0),
                                         DL_MAX(prediction->box[1], 0),
                                         DL_MAX(prediction->box[2], 0),
                                         DL_MAX(prediction->keypoint[3], 0),
                                         (uint8_t)2,
                                         green);

        if (prediction->keypoint.size() == 10)
        {
            dl::image::draw_point<uint8_t>(img, DL_MAX(prediction->keypoint[0], 0), DL_MAX(prediction->keypoint[1], 0), 4, red); // left eye
            dl::image::draw_point<uint8_t>(img, DL_MAX(prediction->keypoint[2], 0), DL_MAX(prediction->keypoint[3], 0), 4, red); // mouth left corner
            dl::image::draw_point<uint8_t>(img, DL_MAX(prediction->keypoint[4], 0), DL_MAX(prediction->keypoint[5], 0), 4, green); // nose
            dl::image::draw_point<uint8_t>(img, DL_MAX(prediction->keypoint[6], 0), DL_MAX(prediction->keypoint[7], 0), 4, blue); // right eye
            dl::image::draw_point<uint8_t>(img, DL_MAX(prediction->keypoint[8], 0), DL_MAX(prediction->keypoint[9], 0), 4, blue); // mouth right corner
        }
    }
}

void print_detection_result(std::list<dl::detect::result_t> &results)
{
    int i = 0;
    for (std::list<dl::detect::result_t>::iterator prediction = results.begin(); prediction != results.end(); prediction++, i++)
    {
        ESP_LOGI("detection_result", "[%2d]: (%3d, %3d, %3d, %3d)", i, prediction->box[0], prediction->box[1], prediction->box[2], prediction->box[3]);

        if (prediction->keypoint.size() == 10)
        {
            ESP_LOGI("detection_result", "      left eye: (%3d, %3d), right eye: (%3d, %3d), nose: (%3d, %3d), mouth left: (%3d, %3d), mouth right: (%3d, %3d)",
                     prediction->keypoint[0], prediction->keypoint[1],  // left eye
                     prediction->keypoint[6], prediction->keypoint[7],  // right eye
                     prediction->keypoint[4], prediction->keypoint[5],  // nose
                     prediction->keypoint[2], prediction->keypoint[3],  // mouth left corner
                     prediction->keypoint[8], prediction->keypoint[9]); // mouth right corner
        }
    }
}

void *app_camera_decode(camera_fb_t *fb)
{
    if (fb->format == PIXFORMAT_RGB565)
    {
        return (void *)fb->buf;
    }
    else
    {
        uint8_t *image_ptr = (uint8_t *)malloc(fb->height * fb->width * 3 * sizeof(uint8_t));
        if (image_ptr)
        {
            if (fmt2rgb888(fb->buf, fb->len, fb->format, image_ptr))
            {
                return (void *)image_ptr;
            }
            else
            {
                ESP_LOGE(TAG, "fmt2rgb888 failed");
                free(image_ptr);
            }
        }
        else
        {
            ESP_LOGE(TAG, "malloc memory for image rgb888 failed");
        }
    }
    return NULL;
}
修改esp-who/components/esp-dl/CMakeLists.txt(他只包含了include里的头文件,而这个头文件里没有img_t和pix_t类型定义)
加入esp-dl/vision/image到src和include路径里

修改esp-who/components/esp-dl/esp-dl/vision/image/dl_image_draw.cpp和.hpp,去掉函数传参中的const

编译报错好像还有过一个哪里free_align()没有的错误,直接改成free就行
如果有其他零碎的错误,好像都不难改

我做过的一些尝试:
修改who_ai_utils.cpp的命名空间(全部加入dl::image/在函数加入dl::image),没解决
加上/去掉手动指定who_ai_uttils,cpp中画框和画点的模板

其他:
我没用esp-who的master分支,因为我不是官方的开发板,重构后的master又找不到哪里改摄像头和lcd引脚定义

我对C++函数模板和函数重载的用法不是很懂,dl_image_draw.cpp中的用法感觉很迷惑(为什么传参都是一样的?编译器根本判断不了。这不如不用函数模板,写成两个函数如何)

如果您能帮我找到其他的方可以编译的人脸识别例程,也欢迎指导我。
Attachments
dl_image_draw.hpp
(804 Bytes) Downloaded 56 times
dl_image_draw.cpp
(5.5 KiB) Downloaded 52 times
who_ai_utils.cpp
(6.41 KiB) Downloaded 71 times

Who is online

Users browsing this forum: No registered users and 1 guest