【正点原子K210连载】第三十二章 YOLO2人手检测实验《DNK210使用指南-SDK版》

[复制链接]
501|0
第三十二章 YOLO2人手检测实验

在上一章节中,介绍了利用KPU模块实现基于YOLO2的人脸检测功能,本章将继续介绍利用KPU模块实现基于YOLO2的人手检测功能。通过本章的学习,读者将学习到使用SDK编程技术实现基于YOLO2网络的人手检测应用。
本章分为如下几个小节:
32.1 KPU模块介绍
32.2 硬件设计
32.3 程序设计
32.4 运行验证


32.1 KPU模块介绍
有关KPU模块的介绍,请见第30.1小节《KPU介绍》。
32.2 硬件设计
32.2.1 例程功能
1. 获取摄像头输出的图像,并送入KPU进行YOLO2的人手检测模型运算,后将运算结果和摄像头输出的图像一起显示在LCD上。
32.2.2 硬件资源
本章实验内容,主要讲解KPU模块的使用,无需关注硬件资源。
32.2.3 原理图
本章实验内容,主要讲解KPU模块的使用,无需关注原理图。
32.3 程序设计
32.3.1 main.c代码
main.c中的代码如下所示:
INCBIN(model, "hand_detect.kmodel");
image_t kpu_image,draw_image;
uint8_t *disp;
uint8_t *ai;
static float g_anchor[ANCHOR_NUM * 2] = {0.8125, 0.4556, 1.1328, 1.2667, 1.8594, 1.4889, 1.4844, 2.2000, 2.6484, 2.9333}; /**/
static volatile uint8_t ai_done_flag;
/* KPU运算完成回调 */
static void ai_done_callback(void *userdata)
{
    ai_done_flag = 1;
}
void draw_boxes_callback(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2, uint32_t label, float prob)
{
    char datatemp[10];
    if (x1 >= 320)
    {
        x1 = 319;
    }
    if (x2 >= 320)
    {
        x2 = 319;
    }
    if (y1 >= 240)
    {
        y1 = 239;
    }
    if (y2 >= 240)
    {
        y2 = 239;
    }
    draw_box_rgb565_image((uint16_t *)disp, 320, x1, y1, x2, y2, GREEN);
    sprintf((char *)datatemp,"%2.1ffps", prob * 100);
    draw_string_rgb565_image((uint16_t *)disp, 320, 240, x1, y1, datatemp, BLUE);
}
int main(void)
{
    kpu_model_context_t task;
    float *output;
    size_t output_size;
    region_layer_t detect_rl;
    sysctl_pll_set_freq(SYSCTL_PLL0, 800000000);
    sysctl_pll_set_freq(SYSCTL_PLL1, 400000000);
    sysctl_pll_set_freq(SYSCTL_PLL2, 45158400);
    sysctl_clock_enable(SYSCTL_CLOCK_AI);
    sysctl_set_power_mode(SYSCTL_POWER_BANK6, SYSCTL_POWER_V18);
    sysctl_set_power_mode(SYSCTL_POWER_BANK7, SYSCTL_POWER_V18);
    sysctl_set_spi0_dvp_data(1);
    lcd_init();
    lcd_set_direction(DIR_YX_LRUD);
    camera_init(24000000);
    camera_set_pixformat(PIXFORMAT_RGB565);
    camera_set_framesize(320, 240);
    if (kpu_load_kmodel(&task, (const uint8_t *)model_data) != 0)
    {
        printf("Kmodel load failed!\n");
        while (1);
    }
    detect_rl.anchor_number = ANCHOR_NUM;
    detect_rl.anchor = g_anchor;
    detect_rl.threshold = 0.7;
    detect_rl.nms_value = 0.3;
    region_layer_init(&detect_rl, 10, 8, 30, 320, 256);
   
    kpu_image.pixel = 3;
    kpu_image.width = 320;
    kpu_image.height = 240;
    // image_init(&kpu_image);
    draw_image.pixel = 3;
    draw_image.width = 320;
    draw_image.height = 256;
    image_init(&draw_image);
    while (1)
    {
        if (camera_snapshot(&disp, &ai) == 0)
        {
            kpu_image.addr = ai;
            image_draw(&kpu_image, &draw_image, 0, 0);
            ai_done_flag = 0;
            
            if (kpu_run_kmodel(&task, (const uint8_t *)draw_image.addr, DMAC_CHANNEL5, ai_done_callback, NULL) != 0)
            {
                printf("Kmodel run failed!\n");
                while (1);
            }
            while (ai_done_flag == 0);
            if (kpu_get_output(&task, 0, (uint8_t **)&output, &output_size) != 0)
            {
                printf("Output get failed!\n");
                while (1);
            }
            detect_rl.input = output;
            region_layer_run(&detect_rl, NULL);
            region_layer_draw_boxes(&detect_rl, draw_boxes_callback);
            
            lcd_draw_picture(0, 0, 320, 240, (uint16_t *)disp);
            camera_snapshot_release();
        }
    }
}
hand_detect.kmodel是人手识别的模型,网络运算的图片大小为320*256。
可以看到一开始是先初始化了LCD和摄像头,然后加载YOLO2人脸检测网络需要用到的网络模型,并初始化YOLO2网络,配置region_layer_t结构体参数的数据。
最后在一个循环中不断地获取摄像头输出的图像,图像尺寸为320*240,由于网络需要的图像尺寸与摄像头直接输出的图像尺寸不一致,因此将其复制到网络需要的图像尺寸的图像上,我们调用image_draw函数实现,再将其送入KPU中进行运算,然后再进行YOLO2网络运算,接着将KPU运算的结果传入region_layer相关文件进行解析,最后将检测到的物体信息通过draw_boxes_callback回调函数绘制到LCD显示器上。
32.4 运行验证
DNK210开发板连接到电脑主机,通过VSCode将固件烧录到开发板中,将摄像头对准人手,让其采集到人手图像,随后便能在LCD上看到摄像头输出的图像,同时图像中的人手均被绿色的矩形框框出,并在矩形框内的左上角标出了人手的置信度,如下图所示:
图32.4.1 LCD显示YOLO2人手检测结果

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

136

主题

137

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部