sujingliang 发表于 2025-5-3 21:40

【STM32N6570-DK测评】4、AI+H264+USB摄像头综合应用

本帖最后由 sujingliang 于 2025-5-3 21:46 编辑

en.n6-ai-h264-usb-uvc例程在STM32N6570-DK板上部署对象检测模型,并使用UVC/H264格式通过USB传输结果到计算机,通过视频查看软件观察结果。

示例中演示的功能
-多线程应用程序流(Azure RTOS ThreadX)
-NPU加速量化AI模型推理
-双DCMIP管道
-DCMIP裁剪、抽取、缩小规模
-DCMIP ISP使用情况
-H264编码器
-USB UVC(Azure RTOS USBX)
-开发模式
-从外部闪存启动

部署en.n6-ai-h264-usb-uvc例程后,STM32N6570-DK通过USB连接PC机,会被识别为了USB摄像头:

此时,使用类似PotPlayer 64 bit的工具可以将USB摄像头拍摄的内容显示在屏幕上:


一、多线程

int main(void)
{
...
return main_threadx();//调用主线程函数
}
初始化ThreadX,调用 tx_kernel_enter() 启动内核
static int main_threadx()
{
_tx_initialize_kernel_setup();
tx_kernel_enter();
assert(0);

return -1;
}tx_kernel_enter() 启动 ThreadX 内核后,会自动调用 tx_application_define
tx_application_define中建立主线程

void tx_application_define(void *first_unused_memory)
{
const UINT priority = TX_MAX_PRIORITIES - 1;
const ULONG time_slice = 10;
int ret;

ret = tx_thread_create(&main_thread, "main", main_thread_fct, 0, main_tread_stack,
                         sizeof(main_tread_stack), priority, priority, time_slice, TX_AUTO_START);
assert(ret == 0);
}main_thread_fct中调用app_run();
static void main_thread_fct(ULONG arg)
{
...
app_run();
}app_run()中建立3个thread
void app_run()
{
...
/* threads init */
ret = tx_thread_create(&nn_thread, "nn", nn_thread_fct, 0, nn_tread_stack,
                         sizeof(nn_tread_stack), nn_priority, nn_priority, time_slice, TX_AUTO_START);
assert(ret == TX_SUCCESS);
ret = tx_thread_create(&dp_thread, "dp", dp_thread_fct, 0, dp_tread_stack,
                         sizeof(dp_tread_stack), dp_priority, dp_priority, time_slice, TX_AUTO_START);
assert(ret == TX_SUCCESS);
ret = tx_thread_create(&isp_thread, "isp", isp_thread_fct, 0, isp_tread_stack,
                         sizeof(isp_tread_stack), isp_priority, isp_priority, time_slice, TX_AUTO_START);
assert(ret == TX_SUCCESS);
}到此,线程初始化基本完成。

二、修改显示内容
static void build_display(uint8_t *p_buffer, od_pp_out_t *pp_out)
{
const uint8_t *fig_array[] = {fig0, fig1, fig2, fig3, fig4, fig5, fig6, fig7, fig8, fig9};
const uint8_t *nz_array[] ={gImage_nz1,gImage_nz2};
int line_nb = VENC_HEIGHT / INF_INFO_FONT.height - 4;
stat_info_t si_copy;
int nb;
int i;

stat_info_copy(&si_copy);

for (i = 0; i < pp_out->nb_detect; i++)
    draw_box(p_buffer, &pp_out->pOutBuff);

line_nb = build_display_inference_info(p_buffer, si_copy.nn_inference_time.last, line_nb);
line_nb = build_display_cpu_load(p_buffer, line_nb);

nb = MIN(pp_out->nb_detect, ARRAY_NB(fig_array) - 1);
   DRAW_CopyArgbHW(p_buffer, VENC_WIDTH, VENC_HEIGHT, (uint8_t *) nz_array, 256, 256, 16, 256);


build_display_stat_info(p_buffer, &si_copy);
}build_display可以在显示缓冲区中进行画图操作,可以将对象检测模型的结果显示在屏幕上,如:


对象检测模型监测到3个人,显示每个人模型匹配比率,并在左上角显示监测到的对象为:3。
个人实践情况:


将gImage_nz1、gImage_nz2改成了哪吒的表情包,图片格式为BGRA
const unsigned char gImage_nz1 = { /* 0X10,0X20,0X01,0X00,0X01,0X00,0X00,0XE4, */
0XFD,0XFD,0XFD,0X00,0XFD,0XFD,0XFD,0X00,0XFD,0XFD,0XFD,0X00,0XFC,0XFC,0XFC,0X00,
0XFE,0XFE,0XFE,0X00,0XFE,0XFE,0XFE,0X00,0XFE,0XFE,0XFE,0X00,0XFE,0XFE,0XFE,0X00,修改后的界面显示:

识别到对象为奇数时,显示哪吒头像1;
识别到对象为偶数时,显示哪吒头像2;


本例程将STM32N6570-DK驱动为USB摄像头,通过摄像头拍摄的视频流结合对象检测模型,将检测结果H264格式压缩后,传递给PC显示。




页: [1]
查看完整版本: 【STM32N6570-DK测评】4、AI+H264+USB摄像头综合应用