Hass Multimedia (MPP) Development (9) - video motion detection and occlusion

Preface:

    Hass multimedia processing platform (MPP) is divided into: a video input (VI), a video processing (VPSS), a video encoder (VENC), a video decoder (VDEC), video output (VO), Video Detection Analysis (VDA), the audio input (AI), an audio output (AO), the audio encoder (AENC), an audio decoder (ADEC), area management (the rEGION) modules. here are analyzed to detect video motion detection (VDA) in.

Video Detection Analysis (The video detection analysis VDA) by detecting change in luminance of the video, the video detection results obtained. VDA comprising motion detection (motion detection (MD)) and the detection occlusion (occlusion detection (OD)) in two modes, the detection results is also divided into the video motion detection result obtained by the detection result and the occlusion zone the current operating mode:

  • Motion detection (MD) detects the received motion video VDA channel, and outputs a motion detection result. Macroblock SAD value information, comprising a moving region in each image (the OBJ) information and the number of pixels in the entire frame alarm.
  • Occlusion detection (OD) VDA channel receiver detects whether there is video-occlusion, occlusion, and outputs a detection result.

Occlusion parameters and detailed video motion detection, can view the document "HiMPP V3.0 Media Processing Software Development Reference"
Hass official to mpp sample, the code module it is vda h264 video stream using a simulated data stream. To test its accuracy, using the data in the data streams VI herein for testing.

test:

I use the 720P camera, the resolution is 1280 * input VI 720; however, the maximum input resolution vda module are: 960 * 960; VPSS So I cut into the 720P screen D1 resolution. VPSS operations are:

/******************************************************** 
Function:    BIAO_VDA_StartVpss
Description: 开启VPSS
Input:  none
OutPut: none
Return: 0: success,none 0:error
Others: 
    这里对VI输入的视频数据进行裁剪操作
Author: Caibiao Lee
Date:   2020-02-02
*********************************************************/
HI_S32 BIAO_VDA_StartVpss(HI_S32 s32VpssGrpNum, HI_U32 u32VpssChn,PIC_SIZE_E enInputSize,PIC_SIZE_E enOutputSize)
{
    HI_S32 i = 0;
    HI_S32 s32Ret;
    HI_U32 u32Depth;
    VPSS_CHN_MODE_S stVpssChnMode;
    VPSS_GRP_ATTR_S stGrpAttr;
    HI_U32 u32OverlayMask;
    VPSS_CROP_INFO_S stCropInfo;

    if(PIC_HD720==enInputSize)
    {
        stGrpAttr.u32MaxW   = 1280;
        stGrpAttr.u32MaxH   = 720;
    }else
    {
        stGrpAttr.u32MaxW   = 720;
        stGrpAttr.u32MaxH   = 576;        
    }

    stGrpAttr.enPixFmt  = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
    stGrpAttr.enDieMode = VPSS_DIE_MODE_NODIE;
    stGrpAttr.bIeEn     = HI_FALSE;
    stGrpAttr.bNrEn     = HI_FALSE;
    stGrpAttr.bHistEn   = HI_FALSE;
    stGrpAttr.bDciEn    = HI_FALSE;
    stGrpAttr.bEsEn     = HI_FALSE;

    for (i = 0; i < s32VpssGrpNum; i++)
    {
        s32Ret = HI_MPI_VPSS_CreateGrp(i, &stGrpAttr);
        if (HI_SUCCESS != s32Ret)
        {
            printf("creat vpss grp%d fail, s32Ret: 0x%x.\n", i, s32Ret);
            return s32Ret;

        }

        /**输入与输出不一致,开启裁减功能,将图像裁减成输出的分辨率**/
        if(enOutputSize!=enInputSize)
        {
            s32Ret = HI_MPI_VPSS_GetGrpCrop(i, &stCropInfo);
            if(s32Ret != HI_SUCCESS)
            {
                printf("Get Crop %d fail, s32Ret: 0x%x.\n", i, s32Ret);
                return s32Ret;
            }
            stCropInfo.bEnable = 1;
            stCropInfo.enCropCoordinate = VPSS_CROP_ABS_COOR;
            stCropInfo.stCropRect.s32X = 0;
            stCropInfo.stCropRect.s32Y = 0;

            if(PIC_D1==enOutputSize)
            {
                stCropInfo.stCropRect.u32Width = 720;
                stCropInfo.stCropRect.u32Height = 576;
            }else
            {
                stCropInfo.stCropRect.u32Width = 368;
                stCropInfo.stCropRect.u32Height = 288;         
            }

            s32Ret = HI_MPI_VPSS_SetGrpCrop(i, &stCropInfo);
            if(s32Ret != HI_SUCCESS)
            {
                printf("Set Crop %d fail, s32Ret: 0x%x.\n", i, s32Ret);
                return s32Ret;
            }

        }

        s32Ret = HI_MPI_VPSS_EnableChn(i, u32VpssChn);
        if (HI_SUCCESS != s32Ret)
        {
            printf("creat vpss grp%d chnl%d fail, s32Ret: 0x%x.\n", i, u32VpssChn, s32Ret);
            return s32Ret;
        }

        s32Ret = HI_MPI_VPSS_GetChnMode(i, u32VpssChn, &stVpssChnMode);
        if (HI_SUCCESS != s32Ret)
        {
            printf("get vpss grp%d chn%d mode fail, s32Ret: 0x%x.\n", i, u32VpssChn, s32Ret);
            return s32Ret;
        }
        
        stVpssChnMode.bDouble        = HI_FALSE;
        stVpssChnMode.enChnMode      = VPSS_CHN_MODE_USER;
        stVpssChnMode.enPixelFormat  = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
        if(PIC_D1==enOutputSize)
        {
            stVpssChnMode.u32Width       = 720;
            stVpssChnMode.u32Height      = 576;
        }else
        {
            stVpssChnMode.u32Width       = 1280;
            stVpssChnMode.u32Height      = 720;
        }

        stVpssChnMode.enCompressMode = COMPRESS_MODE_NONE;
        
        s32Ret = HI_MPI_VPSS_SetChnMode(i, u32VpssChn, &stVpssChnMode);
        if (HI_SUCCESS != s32Ret)
        {
            printf("set vpss grp%d chn%d mode fail, s32Ret: 0x%x.\n", i, u32VpssChn, s32Ret);
            return s32Ret;
        }
        
        s32Ret = HI_MPI_VPSS_StartGrp(i);
        if (HI_SUCCESS != s32Ret)
        {
            printf("start vpss grp%d fail, s32Ret: 0x%x.\n", i, s32Ret);
            return s32Ret;
        }

        u32Depth = 6;
        s32Ret = HI_MPI_VPSS_SetDepth(i, u32VpssChn, u32Depth);
        if (HI_SUCCESS != s32Ret)
        {
            printf("HI_MPI_VPSS_SetDepth fail! Grp: %d, Chn: %d! s32Ret: 0x%x.\n", i, u32VpssChn, s32Ret);
            return s32Ret;
        }

        u32OverlayMask = 255;
        s32Ret = HI_MPI_VPSS_SetChnOverlay(i, u32VpssChn, u32OverlayMask);
        if (HI_SUCCESS != s32Ret)
        {
            printf("HI_MPI_VPSS_SetChnOverlay fail! Grp: %d, Chn: %d! s32Ret: 0x%x.\n", i, u32VpssChn, s32Ret);
            return s32Ret;
        }
    }

    return HI_SUCCESS;
}

Video shielding the entire process can be carried out as follows:


/******************************************************** 
Function:    BIAO_VDA_OD
Description: 开启遮挡检测
Input:  none
OutPut: none
Return: 0: success,none 0:error
Others: 
    绑定关系为:    VI->VPSS->vda
Author: Caibiao Lee
Date:   2020-02-02
*********************************************************/
HI_S32 BIAO_VDA_OD(HI_VOID)
{
    HI_S32 s32Ret = HI_SUCCESS;
    VDA_CHN VdaChn_Od = 1;
    SIZE_S stSize;
    MPP_CHN_S stSrcChn, stDesChn;  
    VDEC_SENDPARAM_S stVdesSendPram;
    VPSS_GRP_ATTR_S stGrpAttr;
    PIC_SIZE_E enSize = PIC_HD720; 
    PIC_SIZE_E VpssSize = PIC_D1; 
    VIDEO_NORM_E enNorm = VIDEO_ENCODING_MODE_PAL;
    SAMPLE_VI_MODE_E enViMode = SAMPLE_VI_MODE_2_720P;
    HI_S32 s32VpssGrpNum;
    HI_U32 u32VpssChn;

    /*************************************************
    step 1: mpp system init. 
    *************************************************/
    s32Ret = BIAO_VDA_SYS_Init(enSize,enNorm);
    if (HI_SUCCESS != s32Ret)
    {
        printf("system init failed! s32Ret: 0x%x.\n", s32Ret);
        goto END_0;
    }

    /******************************************
     step 2: start vi dev & chn
    ******************************************/
    s32Ret = SAMPLE_COMM_VI_Start(enViMode, enNorm);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("start vi failed!\n");
        goto END_1;
    }

    /*************************************************
    step 3: start vpss group and chn
    *************************************************/
    s32VpssGrpNum = 1;
    u32VpssChn    = VPSS_CHN2;
    s32Ret = BIAO_VDA_StartVpss(s32VpssGrpNum, u32VpssChn,enSize,VpssSize);
    if(HI_SUCCESS != s32Ret)
    {
        printf("SAMPLE_RGN_StartVpss failed! s32Ret: 0x%x.\n", s32Ret);
        goto END_2;
    }

    /*************************************************
    step 4: bind vi and vpss
    *************************************************/
    stSrcChn.enModId  = HI_ID_VIU;
    stSrcChn.s32DevId = 0;
    stSrcChn.s32ChnId = 0;

    stDesChn.enModId  = HI_ID_VPSS;
    stDesChn.s32DevId = 0;
    stDesChn.s32ChnId = u32VpssChn;

    s32Ret = HI_MPI_SYS_Bind(&stSrcChn, &stDesChn);
    if(HI_SUCCESS != s32Ret)
    {
        printf("HI_MPI_SYS_Bind failed! s32Ret: 0x%x.\n", s32Ret);
        goto END_3;
    }

    /*************************************************
    step  5: start VDA OD process
    *************************************************/
    s32Ret = SAMPLE_COMM_SYS_GetPicSize(enNorm, VpssSize, &stSize);
    if (HI_SUCCESS != s32Ret)
    {
        printf("SAMPLE_COMM_SYS_GetPicSize failed! s32Ret: 0x%x.\n", s32Ret);
        goto END_4;
    }

    if (0 != stSize.u32Width % VDA_WIDTH_ALIGN)
    {
        stSize.u32Width = (stSize.u32Width / VDA_WIDTH_ALIGN + 1) * VDA_WIDTH_ALIGN;
    }

    if (0 != stSize.u32Height % VDA_HEIGHT_ALIGN)
    {
        stSize.u32Height = (stSize.u32Height / VDA_HEIGHT_ALIGN + 1) * VDA_HEIGHT_ALIGN;
    }
   
    s32Ret = SAMPLE_COMM_VDA_OdStart(VdaChn_Od, u32VpssChn, &stSize);
    if (HI_SUCCESS != s32Ret)
    {
        printf("VDA OD Start failed! s32Ret: 0x%x.\n", s32Ret);
        goto END_4;
    }

    printf("Press any key to stop!");
    getchar();

END_4:
    SAMPLE_COMM_VDA_OdStop(VdaChn_Od, u32VpssChn);

END_3:   
    SAMPLE_COMM_VI_UnBindVpss(enViMode);
    
END_2:
    BIAO_VDA_StopVpss(s32VpssGrpNum);
    
END_1:
    SAMPLE_COMM_VI_Stop(enViMode);  
END_0:
    BIAO_VDA_SYS_Exit();
    return s32Ret;
}

Test results:

    Hass official use default parameters, the input screen D1 real-time detection, regardless of video motion detection or video occlusion detection, its accuracy is not high, if you want to accurately detect, also need to own or use other debugging detect and analyze the way.

 

This chapter from the frequency measurement engineering "catalog preface" to get the address provided

 

The first article in this column "catalog preface," lists the complete directory column, read by directory order to help your understanding.

 

 

 

Published 175 original articles · won praise 262 · views 700 000 +

Guess you like

Origin blog.csdn.net/li_wen01/article/details/105217917