RV1126中AI例程解析

本次以基于rockx组件的ssd目标检测为例

官方提供的例程中有2个C++文件及2个头文件

RV1126中AI例程解析_第1张图片

其中:atk_ssd_object_recognize.cpp是一个使用 Rockchip 嵌入式平台进行图像处理的示例程序。整体功能是初始化视频输入、进行图像处理(RGA),然后将结果输出到显示终端。以下是代码的详细解释:

引入头文件

#include "atk_ssd_object_recognize.h" 

引入自定义的头文件,该文件可能包含与目标检测相关的功能声明。

主函数

int main(int argc, char *argv[]) 

主入口函数,接受命令行参数。

变量初始化

RK_CHAR *pDeviceName_01 = "rkispp_scale0"; RK_CHAR *pDeviceName_02 = "rkispp_scale1";
 RK_CHAR *pcDevNode = "/dev/dri/card0"; char *iq_file_dir = "/etc/iqfiles"; RK_S32 
s32CamId = 0; RK_U32 u32BufCnt = 3; RK_U32 fps = 20; int ret;
  • pDeviceName_01: 指定视频输入设备。
  • pDeviceName_02: 另一个视频输入设备(没被使用)。
  • pcDevNode: 图形输出设备节点。
  • iq_file_dir: 图像处理相关的文件路径。
  • s32CamId: 摄像头ID。
  • u32BufCnt: 缓冲区数量。
  • fps: 帧率。
  • ret: 用于存储函数返回值的变量。

打印初始化信息

printf("\n###############################################\n"); printf("VI CameraIdx: %d\npDeviceName: %s\nResolution: %dx%d\n\n", s32CamId,pDeviceName_01,video_width,video_height); 

打印当前设置的摄像头索引、设备名称和分辨率。

ISP 初始化

if (iq_file_dir) { #ifdef RKAIQ // 初始化ISP #endif } 

如果 IQ 文件目录存在,执行 ISP(图像信号处理)模块的初始化和运行。

视频输入通道配置

RK_MPI_VI_SetChnAttr(s32CamId, 0, &vi_chn_attr_01); ret |= RK_MPI_VI_EnableChn(s32CamId, 0); 

设置并启用视频输入通道,配置参数包括视频节点名、缓冲区数量、分辨率和像素格式等。

RGA(图像重数组件)初始化

RGA_ATTR_S stRgaAttr_01; ret = RK_MPI_RGA_CreateChn(0, &stRgaAttr_01); 

初始化 RGA,并设置输入输出图像的相关参数,例如旋转角度、分辨率和图像类型。

视频输出通道配置

ret = RK_MPI_VO_CreateChn(0, &stVoAttr); 

创建视频输出通道,并设置输出设备、图像类型及其显示区域等。

通道绑定

ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn); 

将视频输入通道 (VI) 绑定到 RGA 通道,实现数据流的传输。

创建线程

pthread_create(&rkmedia_rknn_tidp, NULL, rkmedia_rknn_thread, NULL); 

创建一个新的线程来处理其他任务,这里具体的处理逻辑在 rkmedia_rknn_thread 函数中实现。

主循环

while (!quit) { usleep(500000); } 

保持主程序运行,直到 quit 变量被设置为非零值,程序才会退出。

资源释放

ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDestChn); RK_MPI_VO_DestroyChn(0); RK_MPI_RGA_DestroyChn(0); RK_MPI_VI_DisableChn(s32CamId, 0); 

在程序结束时,解除通道绑定并销毁所有相关的通道,释放资源。

返回值

return 0; 

程序正常结束时返回0。

整段代码主要实现了从摄像头抓取图像,并通过 RGA 进行处理,再输出到显示设备的过程。它涉及到多个硬件模块的初始化、配置和管理,以及内存的管理和线程的使用,适合用于实时视频处理等应用。

ssd.cc文件是一个目标检测算法的后处理部分,主要是针对 SSD(Single Shot MultiBox Detector)模型的实现。代码中包含了文件的读取、框的解码、筛选有效结果、非极大值抑制(NMS)和最终结果的输出等功能。以下是代码的详细分析和各个组件的含义:

主要结构和函数

完整性总结

  1. 包含的头文件:

    • stdio.h: 标准输入输出库,提供文件和标准输入输出功能。
    • stdlib.h: 标准库,提供内存分配和其他功能。
    • math.h: 数学库,提供数学函数(如 exp 和 log)。
    • string.h: 字符串操作函数。
    • sys/time.h: 提供获取系统时间的功能。
    • "ssd.h": 假定是 SSD 模型相关的自定义头文件。
  2. 常量定义:

    • BOX_PRIORS_TXT_PATH 和 LABEL_NALE_TXT_PATH 是存储箱体先验和标签名称的文件路径。
    • MIN_SCORE 和 NMS_THRESHOLD 分别是最低置信度和非极大值抑制的阈值。
  3. 全局变量:

    • labels[NUM_CLASS]: 存储类别标签。
    • box_priors[4][NUM_RESULTS]: 存储框的先验信息。
  4. 获取当前时间:

    • getCurrentTimeUs(): 获取当前时间(以微秒为单位),用于时间测量。
  5. 读取文件的函数:

    • readLine: 从文件中读取一行,并动态分配内存以保存它。
    • readLines: 读取文件中的多行,返回读取的行数。
    • loadLabelName: 从指定文件加载类名并存储到 labels 数组。
    • loadBoxPriors: 从指定文件加载框的先验数据。
  6. 计算重叠度的函数:

    • CalculateOverlap: 计算两个边界框之间的 IoU(Intersection over Union)
  7. 激活函数:
    • unexpit(float x): 反向 Sigmoid 函数,用于将模型输出值转化为原始值。
      • 公式为 unexpit()=1+unexpit(x)=1+xx​。
    • expit(float x): Sigmoid 函数,将原始值转化为介于 0 和 1 的值,用于处理模型的概率输出。
  8. 目标检测结果处理

    主要逻辑:
    • sort(output, props, validCount): 首先,对检测到的结果进行排序,通常依据置信度得分(props)进行排序。
    • nms(validCount, predictions, output): 执行非极大值抑制,删除重叠度高于设定阈值的框,以减少冗余检测结果。
    • 结果处理:
      • 这里开始一个循环:将有效的检测结果加入到对应的结构体中。
      • 框的信息提取:
        • x1, y1: 左上角坐标
        • x2, y2: 右下角坐标
        • predictions[n * 4 + ...]: 使用预测的偏移量和图像的宽高恢复框的坐标。
      • 过滤无效框:
        • 检查框的坐标(x1y1x2y2)是否都为 0,如果是则跳过。
      • 填充目标检测结果:
        • 将框的坐标和其他信息(如分类分数、类别标签等)存储到 group->results 中。
        • memcpy: 复制类别标签到结果结构中。
        • last_count++: 增加有效检测结果的计数。
  9. 更新框的计数:

    • group->count = last_count;: 更新检测结构体中的框数量。
  10. 最后,函数返回 0 表示处理成功。这段代码能够有效地将 SSD 模型的预测结果处理成最终的目标检测结果,适合后续的展示或使用。

你可能感兴趣的:(人工智能,目标跟踪,计算机视觉)