视频检测

更新时间:2023-08-09 09:25:02下载pdf

视频检测是指检测分析视频中的人形、宠物、车辆等目标,计算出对应目标的坐标位置、评分。目前,最多支持同时上报三个目标结果。

工作原理

人形检测和宠物检测,原理基本一致。把视频采集的 YUV 或者 RGB 数据发送给检测模组,检测模组分析帧,获取人形或宠物的坐标。

调用流程

视频检测

数据结构

检测类型

视频检测,目前主要支持人形,宠物检测等。具体以芯片平台能力为准。

typedef enum {
    TKL_MEDIA_DETECT_TYPE_HUMAN = 0,                                    // 人形,human
    TKL_MEDIA_DETECT_TYPE_PET,                                          // 宠物,一般指猫狗,cat,dog
    TKL_MEDIA_DETECT_TYPE_CAR,                                          // 车形,car
    TKL_MEDIA_DETECT_TYPE_FACE,                                         // 人脸,face
    TKL_MEDIA_DETECT_TYPE_FLAME,                                        // 火焰,flame
    TKL_MEDIA_DETECT_TYPE_BABY_CRY,                                     // 婴儿哭声,baby cry
    TKL_MEDIA_DETECT_TYPE_DB,                                           // 声音分贝,audio decibel
    TKL_MEDIA_DETECT_TYPE_MOTION,                                       // 移动
    TKL_MEDIA_DETECT_TYPE_TRIP,                                         // 拌线
    TKL_MEDIA_DETECT_TYPE_PERI,                                         // 周界
} TKL_MEDIA_DETECT_TYPE_E;

检测配置入参

不同平台有差异,FH8636、FH8652 等富瀚平台需要传入模型参数,其他平台无需传人。

typedef struct{
    CHAR_T         *pmodel;                                             // 检测模型数据指针
    INT32_T         model_len;                                          // 检测模型的数据长度
}TKL_VI_DETECT_CONFIG_T;

检测结果结构体

typedef struct
{
    FLOAT_T x;                                                     // 矩形框 x 坐标 | [0.0 - 1.0]
    FLOAT_T y;                                                     // 矩形框 y 坐标 | [0.0 - 1.0]
    FLOAT_T width;                                                 // 矩形框宽度 | [0.0 - 1.0]
    FLOAT_T height;                                                // 矩形框高度 | [0.0 - 1.0]
} TKL_VI_RECT_T;

typedef struct
{
    INT32_T x;
    INT32_T y;
} TKL_VI_POINT_T;

typedef struct
{
    TKL_VI_RECT_T    draw_rect;                                   // coordinate region
    FLOAT_T          score;                                       // score | [0.0 - 1.0]
    TKL_MEDIA_DETECT_TYPE_E type;                                 // 目标类型,人形,宠物,火焰等
} TKL_VI_DETECT_TARGET_T;

typedef struct
{
    int value;                                                    // 0,无动检,1,检测到动检
    TKL_VI_POINT_T motion_point;                                  // 动检中心点坐标, 矩形中心为(0, 0)
} TKL_VI_MD_RESULT_T;

typedef struct
{
    INT32_T count;
    TKL_VI_DETECT_TARGET_T target[TKL_VI_TARGET_MAX];
    union{
        TKL_VI_MD_RESULT_T md;
    };
} TKL_VI_DETECT_RESULT_T;

检测参数

typedef struct
{
    UINT32_T roi_count;                                           // 检测有效区域个数
    TKL_VI_RECT_T roi_rect[TKL_VI_MD_ROI_RECT_MAX];               // 区域框
    INT32_T track_enable;                                         // 移动追踪使能
} TKL_VI_MD_PARAM_T;

typedef struct
{
    UINT32_T point_count;                                         // 顶点个数
    TKL_VI_POINT_T point[TKL_VI_PERI_POINT_MAX];                  // 点
} TKL_VI_PERI_PARAM_T;

typedef struct
{
    INT32_T sensitivity;
    union{
        TKL_VI_MD_PARAM_T md;
        TKL_VI_PERI_PARAM_T peri;
    };
} TKL_VI_DETECT_PARAM_T;

视频检测接口

检测初始化

IPC 设备,暂时只有一个传感器,只支持 1 路,chn0 即可。

/**
* @brief detect init
*
* @param[in] chn: vi chn
* @param[in] type: detect type
* @param[in] pconfig: config
*
* @return OPRT_OK on success. Others on error, please refer to tkl_error_code.h
*/
OPERATE_RET tkl_vi_detect_init(TKL_VI_CHN_E chn, TKL_MEDIA_DETECT_TYPE_E type, TKL_VI_DETECT_CONFIG_T *p_config);

开启检测

/**
* @brief detect start
*
* @param[in] chn: vi chn
* @param[in] type: detect type
* @return OPRT_OK on success. Others on error, please refer to tkl_error_code.h
*/
OPERATE_RET tkl_vi_detect_start(TKL_VI_CHN_E chn, TKL_MEDIA_DETECT_TYPE_E type);

获取检测结果

/**
* @brief get detection results
*
* @param[in] chn: vi chn
* @param[in] type: detect type
* @param[out] presult: detection results
*
* @return OPRT_OK on success. Others on error, please refer to tkl_error_code.h
*/
OPERATE_RET tkl_vi_detect_get_result(TKL_VI_CHN_E chn, TKL_MEDIA_DETECT_TYPE_E type, TKL_VI_DETECT_RESULT_T *presult);

检测参数设置

/**
* @brief set detection param
*
* @param[in] chn: vi chn
* @param[in] type: detect type
* @param[in] pparam: detection param
*
* @return OPRT_OK on success. Others on error, please refer to tkl_error_code.h
*/
OPERATE_RET tkl_vi_detect_set(TKL_VI_CHN_E chn, TKL_MEDIA_DETECT_TYPE_E type, TKL_VI_DETECT_PARAM_T *pparam);

检测反初始化

/**
* @brief detect uninit
*
* @param[in] chn: vi chn
* @param[in] type: detect type
*
* @return OPRT_OK on success. Others on error, please refer to tkl_error_code.h
*/
OPERATE_RET tkl_vi_detect_uninit(TKL_VI_CHN_E chn, TKL_MEDIA_DETECT_TYPE_E type);

使用示例

// 人形检测:
static char *load_models(char *modelPath, int *p_size)
{
    int32_t readLen;
    int32_t fileLen;
    FILE *fp;

    if (!(fp = fopen(modelPath, "rb"))) {
        printf("Error: open %s failed\n", modelPath);
        return NULL;
    }

    fseek(fp, 0, SEEK_END);
    fileLen = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    char *buf = malloc(fileLen);
    if (buf == NULL) {
        printf("Error: malloc model buf failed, size = %d\n", fileLen);
        fclose(fp);
        return NULL;
    }

    readLen = fread(buf, 1, fileLen, fp);
    if (readLen < fileLen) {
        printf("Error: read model file failed, fileLen = %d, readLen = %d\n", fileLen, readLen);
        free(buf);
        buf = NULL;
    }

    fclose(fp);
    *p_size = readLen;
    return buf;
}

    ...
    char *modelPath = "/mnt/sdcard/person_pet.nbg";
    TKL_VI_DETECT_CONFIG_T model_config = {0};
    model_config .pmodel = load_models(modelPath, &model_config .model_len);
    if (model_config .pmodel == NULL){
        printf("load_models failed!\n");
        return;
    }

    ret = tkl_vi_detect_init(0, TKL_MEDIA_DETECT_TYPE_HUMAN, pconfig);
    ...
    ret = tkl_vi_detect_start(0, TKL_MEDIA_DETECT_TYPE_HUMAN);
    ...
    ret = tkl_vi_detect_get_result(0, TKL_MEDIA_DETECT_TYPE_HUMAN, &result);
    ...
    ret = tkl_vi_detect_stop(0, TKL_MEDIA_DETECT_TYPE_HUMAN);
    ...
    free(model_config.pmodel);

// 宠物检测和人形检测,调用方式一样。可参考人形检测流程。

注意事项

如果检测算法比较消耗 CPU,不需要获取检测结果时,建议调用 tkl_vi_detect_stop 停掉检测,从而节省性能。