HISI3559A 使用yolov3 (VI-VPSS-VO)实时目标检测

Posted 为了维护世界和平_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HISI3559A 使用yolov3 (VI-VPSS-VO)实时目标检测相关的知识,希望对你有一定的参考价值。

使用yolov3 模型进行实时目标检测

主芯片:Hisi3559A
摄像头:imx214

使用海思VI-VPSS-VO进行实时检测

程序修改,将识别图片修改成实时识别视频

******************************************************************************
* function : SAMPLE_SVP_NNIE_yolov3_video
******************************************************************************/
void SAMPLE_SVP_NNIE_yolov3_video(void)

	//模型参数
    HI_CHAR *pcModelName = "./data/nnie_model/detection/inst_yolov3_cycle.wk";

	SAMPLE_SVP_NNIE_CFG_S   stNnieCfg = 0;
    SIZE_S stSize;
    PIC_SIZE_E enSize = PIC_D1_PAL;//PIC_CIF
    HI_S32 s32Ret = HI_SUCCESS;
    HI_CHAR acThreadName[16] = 0;

    memset(&s_stYolov3Model,0,sizeof(s_stYolov3Model));
    memset(&s_stYolov3NnieParam,0,sizeof(s_stYolov3NnieParam));
    memset(&s_stYolov3SoftwareParam,0,sizeof(s_stYolov3SoftwareParam));

    /******************************************
     step 1: start vi vpss vo
     ******************************************/
    s_stRfcnSwitch.bVenc = HI_FALSE;
    s_stRfcnSwitch.bVo   = HI_TRUE;
    s32Ret = SAMPLE_COMM_IVE_StartViVpssVencVo(&s_stViConfig,&s_stRfcnSwitch,&enSize);
    SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, END_RFCN_0,
        "Error(%#x),SAMPLE_COMM_IVE_StartViVpssVencVo failed!\\n", s32Ret);

    s32Ret = SAMPLE_COMM_SYS_GetPicSize(enSize, &stSize);
    SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, END_RFCN_0,
        "Error(%#x),SAMPLE_COMM_SYS_GetPicSize failed!\\n", s32Ret);

    /******************************************
     step 2: init NNIE param
     ******************************************/
    stNnieCfg.pszPic= NULL;
    stNnieCfg.u32MaxInputNum = 1; //max input image num in each batch
    stNnieCfg.u32MaxRoiNum = 0;
    stNnieCfg.aenNnieCoreId[0] = SVP_NNIE_ID_0; //set NNIE core for 0-th Seg
    stNnieCfg.aenNnieCoreId[1] = SVP_NNIE_ID_0; //set NNIE core for 1-th Seg
    stNnieCfg.aenNnieCoreId[2] = SVP_NNIE_ID_0; //set NNIE core for 2-th Seg

	
    /*Set configuration parameter*/

    s32Ret = SAMPLE_COMM_SVP_NNIE_LoadModel(pcModelName,&s_stYolov3Model);
    SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret,END_RFCN_0,SAMPLE_SVP_ERR_LEVEL_ERROR,
        "Error,SAMPLE_COMM_SVP_NNIE_LoadModel failed!\\n");

    /*Yolov3 parameter initialization*/
    /*Yolov3 software parameters are set in SAMPLE_SVP_NNIE_Yolov3_SoftwareInit,
      if user has changed net struct, please make sure the parameter settings in
      SAMPLE_SVP_NNIE_Yolov3_SoftwareInit function are correct*/
    SAMPLE_SVP_TRACE_INFO("Yolov3 parameter initialization wy!\\n");
    s_stYolov3NnieParam.pstModel = &s_stYolov3Model.stModel;
    s32Ret = SAMPLE_SVP_NNIE_Yolov3_ParamInit(&stNnieCfg,&s_stYolov3NnieParam,&s_stYolov3SoftwareParam);
    SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret,END_RFCN_1,SAMPLE_SVP_ERR_LEVEL_ERROR,
        "Error,SAMPLE_SVP_NNIE_Yolov3_ParamInit failed!\\n");

    s_bNnieStopSignal = HI_FALSE;

    /******************************************
      step 3: Create work thread
     ******************************************/
    snprintf(acThreadName, 16, "NNIE_ViToVo");
    prctl(PR_SET_NAME, (unsigned long)acThreadName, 0,0,0);
    pthread_create(&s_hNnieThread, 0, SAMPLE_SVP_NNIE_yolov3_ViToVo, NULL);

    SAMPLE_PAUSE();

    s_bNnieStopSignal = HI_TRUE;
    pthread_join(s_hNnieThread, HI_NULL);
    s_hNnieThread = 0;
END_RFCN_1:
    SAMPLE_SVP_NNIE_Yolov3_Deinit(&s_stRfcnNnieParam,&s_stYolov3SoftwareParam,&s_stYolov3Model);
END_RFCN_0:
    SAMPLE_COMM_IVE_StopViVpssVencVo(&s_stViConfig,&s_stRfcnSwitch);
    return ;


static HI_VOID* SAMPLE_SVP_NNIE_yolov3_ViToVo(HI_VOID* pArgs)

    HI_S32 s32Ret;
    SAMPLE_SVP_NNIE_PARAM_S *pstParam;
    SAMPLE_SVP_NNIE_RFCN_SOFTWARE_PARAM_S *pstSwParam;
    VIDEO_FRAME_INFO_S stBaseFrmInfo;
    VIDEO_FRAME_INFO_S stExtFrmInfo;
    HI_S32 s32MilliSec = 20000;
    VO_LAYER voLayer = 0;
    VO_CHN voChn = 0;
    HI_S32 s32VpssGrp = 0;
    HI_S32 as32VpssChn[] = VPSS_CHN0, VPSS_CHN1;

    pstParam = &s_stYolov3NnieParam;
    pstSwParam = &s_stYolov3SoftwareParam;

        while (HI_FALSE == s_bNnieStopSignal)
        
        s32Ret = HI_MPI_VPSS_GetChnFrame(s32VpssGrp, as32VpssChn[1], &stExtFrmInfo, s32MilliSec);
        if(HI_SUCCESS != s32Ret)
        
            SAMPLE_PRT("Error(%#x),HI_MPI_VPSS_GetChnFrame failed, VPSS_GRP(%d), VPSS_CHN(%d)!\\n",
                s32Ret,s32VpssGrp, as32VpssChn[1]);
            continue;
        

        s32Ret = HI_MPI_VPSS_GetChnFrame(s32VpssGrp, as32VpssChn[0], &stBaseFrmInfo, s32MilliSec);
        SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS!=s32Ret, EXT_RELEASE,
            "Error(%#x),HI_MPI_VPSS_GetChnFrame failed, VPSS_GRP(%d), VPSS_CHN(%d)!\\n",
            s32Ret,s32VpssGrp, as32VpssChn[0]);

        s32Ret = SAMPLE_SVP_NNIE_Yolov3_Proc(pstParam,pstSwParam, &stExtFrmInfo,
        stBaseFrmInfo.stVFrame.u32Width,stBaseFrmInfo.stVFrame.u32Height);

        SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS!=s32Ret, BASE_RELEASE,
            "Error(%#x),SAMPLE_SVP_NNIE_Yolov3_Proc failed!\\n", s32Ret);
        //Draw rect
        //printf("u32ClsNum=%d,u32TotalNum=%d,%d %d \\n",s_stYolov3SoftwareParam.stRect.u32ClsNum,s_stYolov3SoftwareParam.stRect.u32TotalNum,
        //s_stYolov3SoftwareParam.stRect.astRect[0][0].astPoint[0].s32X,s_stYolov3SoftwareParam.stRect.astRect[0][0].astPoint[0].s32Y);
                printf("draw ... \\n");
        s32Ret = SAMPLE_COMM_SVP_NNIE_FillRect(&stBaseFrmInfo, &(s_stYolov3SoftwareParam.stRect), 0x0000FF00);
        SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS!=s32Ret, BASE_RELEASE,
            "SAMPLE_COMM_SVP_NNIE_FillRect failed, Error(%#x)!\\n", s32Ret);

                 //add wy       
                 SAMPLE_SVP_TRACE_INFO("yolov3 result:\\n");
                (void)SAMPLE_SVP_NNIE_Detection_PrintResult(&s_stYolov3SoftwareParam.stDstScore,
                        &s_stYolov3SoftwareParam.stDstRoi, &s_stYolov3SoftwareParam.stClassRoiNum,0.8);


        s32Ret = HI_MPI_VO_SendFrame(voLayer, voChn, &stBaseFrmInfo, s32MilliSec);
        SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS!=s32Ret, BASE_RELEASE,
            "HI_MPI_VO_SendFrame failed, Error(%#x)!\\n", s32Ret);

        BASE_RELEASE:
            s32Ret = HI_MPI_VPSS_ReleaseChnFrame(s32VpssGrp,as32VpssChn[0], &stBaseFrmInfo);
            if (HI_SUCCESS != s32Ret)
            
                SAMPLE_PRT("Error(%#x),HI_MPI_VPSS_ReleaseChnFrame failed,Grp(%d) chn(%d)!\\n",
                    s32Ret,s32VpssGrp,as32VpssChn[0]);
            

        EXT_RELEASE:
            s32Ret = HI_MPI_VPSS_ReleaseChnFrame(s32VpssGrp,as32VpssChn[1], &stExtFrmInfo);
            if (HI_SUCCESS != s32Ret)
            
                SAMPLE_PRT("Error(%#x),HI_MPI_VPSS_ReleaseChnFrame failed,Grp(%d) chn(%d)!\\n",
                    s32Ret,s32VpssGrp,as32VpssChn[1]);
            

    

    return HI_NULL;


//#define FRCN 0

/******************************************************************************
* function : Yolov3 Proc
******************************************************************************/
static HI_S32 SAMPLE_SVP_NNIE_Yolov3_Proc(SAMPLE_SVP_NNIE_PARAM_S *pstParam,
    SAMPLE_SVP_NNIE_RFCN_SOFTWARE_PARAM_S *pstSwParam, VIDEO_FRAME_INFO_S* pstExtFrmInfo,
    HI_U32 u32BaseWidth,HI_U32 u32BaseHeight)

    HI_S32 s32Ret = HI_FAILURE;
    SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S stInputDataIdx = 0;
    SAMPLE_SVP_NNIE_PROCESS_SEG_INDEX_S stProcSegIdx = 0;

    stInputDataIdx.u32SegIdx = 0;
    stInputDataIdx.u32NodeIdx = 0;
    /*SP420*/
    pstParam->astSegData[stInputDataIdx.u32SegIdx].astSrc[stInputDataIdx.u32NodeIdx].u64VirAddr = pstExtFrmInfo->stVFrame.u64VirAddr[0];
    pstParam->astSegData[stInputDataIdx.u32SegIdx].astSrc[stInputDataIdx.u32NodeIdx].u64PhyAddr = pstExtFrmInfo->stVFrame.u64PhyAddr[0];
    pstParam->astSegData[stInputDataIdx.u32SegIdx].astSrc[stInputDataIdx.u32NodeIdx].u32Stride  = pstExtFrmInfo->stVFrame.u32Stride[0];

#ifdef FRCN
    /*NNIE process 0-th seg*/
    stProcSegIdx.u32SegIdx = 0;
    s32Ret = SAMPLE_SVP_NNIE_Forward(pstParam,&stInputDataIdx,&stProcSegIdx,HI_TRUE);
    SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,SAMPLE_SVP_ERR_LEVEL_ERROR,
        "Error,SAMPLE_SVP_NNIE_Forward failed!\\n");
#endif

    /*NNIE process(process the 0-th segment) wy*/
    stProcSegIdx.u32SegIdx = 0;
    s32Ret = SAMPLE_SVP_NNIE_Forward(pstParam,&stInputDataIdx,&stProcSegIdx,HI_TRUE);
    SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,SAMPLE_SVP_ERR_LEVEL_ERROR,
        "Error,SAMPLE_SVP_NNIE_Forward failed!\\n");

#ifdef FRCN
    /*RPN*/
    s32Ret = SAMPLE_SVP_NNIE_Rfcn_Rpn(pstParam, pstSwParam);
    SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,SAMPLE_SVP_ERR_LEVEL_ERROR,
        "Error,SAMPLE_SVP_NNIE_RFCN_Rpn failed!\\n");

    /*NNIE process 1-th seg, the input data comes from 3-rd report node of 0-th seg,
      the input roi comes from RPN results*/
    stInputDataIdx.u32SegIdx = 0;
    stInputDataIdx.u32NodeIdx = 3;
    stProcSegIdx.u32SegIdx = 1;
    s32Ret = SAMPLE_SVP_NNIE_ForwardWithBbox(pstParam,&stInputDataIdx,
        &pstSwParam->stRpnBbox,&stProcSegIdx,HI_TRUE);
    SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,SAMPLE_SVP_ERR_LEVEL_ERROR,
        "Error,SAMPLE_SVP_NNIE_Forward failed!\\n");

    /*NNIE process 2-nd seg, the input data comes from 4-th report node of 0-th seg
      the input roi comes from RPN results*/
    stInputDataIdx.u32SegIdx = 0;
    stInputDataIdx.u32NodeIdx = 4;
    stProcSegIdx.u32SegIdx = 2;
    s32Ret = SAMPLE_SVP_NNIE_ForwardWithBbox(pstParam,&stInputDataIdx,
        &pstSwParam->stRpnBbox,&stProcSegIdx,HI_TRUE);
    SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,SAMPLE_SVP_ERR_LEVEL_ERROR,
        "Error,SAMPLE_SVP_NNIE_Forward failed!\\n");

    /*GetResult*/
    /*if user has changed net struct, please make sure SAMPLE_SVP_NNIE_Rfcn_GetResult
     function's input datas are correct*/
    s32Ret = SAMPLE_SVP_NNIE_Rfcn_GetResult(pstParam,pstSwParam);
    SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,SAMPLE_SVP_ERR_LEVEL_ERROR,
        "Error,SAMPLE_SVP_NNIE_Rfcn_GetResult failed!\\n");
#endif
		
    /*Software process wy*/
    /*if user has changed net struct, please make sure SAMPLE_SVP_NNIE_Yolov3_GetResult
     function input datas are correct*/
    //s32Ret = SAMPLE_SVP_NNIE_Yolov3_GetResult(&s_stYolov3NnieParam,&s_stYolov3SoftwareParam);
    /*
    s32Ret = SAMPLE_SVP_NNIE_Yolov3_GetResult(pstParam,pstSwParam);
    SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,SAMPLE_SVP_ERR_LEVEL_ERROR,
        "Error,SAMPLE_SVP_NNIE_Yolov3_GetResult failed!\\n");*/

    s32Ret = SAMPLE_SVP_NNIE_Yolov3_GetResult(&s_stYolov3NnieParam,&s_stYolov3SoftwareParam);
    SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,SAMPLE_SVP_ERR_LEVEL_ERROR,
        "Error,SAMPLE_SVP_NNIE_Yolov3_GetResult failed!\\n");


/*		
    SAMPLE_SVP_TRACE_INFO("Yolov3 result:\\n");
    (void)SAMPLE_SVP_NNIE_Detection_PrintResult(&s_stYolov3SoftwareParam.stDstScore,
        &s_stYolov3SoftwareParam.stDstRoi, &s_stYolov3SoftwareParam.stClassRoiNum,0.8);*/

	/*print result, this sample has 81 classes:
	 class 0:background 	 class 1:person 	  class 2:bicycle		  class 3:car			 class 4:motorbike		class 5:aeroplane
	 class 6:bus			 class 7:train		  class 8:truck 		  class 9:boat			 class 10:traffic light
	 class 11:fire hydrant	 class 12:stop sign   class 13:parking meter  class 14:bench		 class 15:bird
	 class 16:cat			 class 17:dog		  class 18:horse		  class 19:sheep		 class 20:cow
	 class 21:elephant		 class 22:bear		  class 23:zebra		  class 24:giraffe		 class 25:backpack
	 class 26:umbrella		 class 27:handbag	  class 28:tie			  class 29:suitcase 	 class 30:frisbee
	 class 31:skis			 class 32:snowboard   class 33:sports ball	  class 34:kite 		 class 35:baseball bat
	 class 36:baseball glove class 37:skateboard  class 38:surfboard	  class 39:tennis racket class 40bottle
	 class 41:wine glass	 class 42:cup		  class 43:fork 		  class 44:knife		 class 45:spoon
	 class 46:bowl			 class 47:banana	  class 48:apple		  class 49:sandwich 	 class 50orange
	 class 51:broccoli		 class 52:carrot	  class 53:hot dog		  class 54:pizza		 class 55:donut
	 class 56:cake			 class 57:chair 	  class 58:sofa 		  class 59:pottedplant	 class 60bed
	 class 61:diningtable	 class 62:toilet	  class 63:vmonitor 	  class 64:laptop		 class 65:mouse
	 class 66:remote		 class 67:keyboard	  class 68:cell phone	  class 69:microwave	 class 70:oven
	 class 71:toaster		 class 72:sink		  class 73:refrigerator   class 74:book 		 class 75:clock
	 class 76:vase			 class 77:scissors	  class 78:teddy bear	  class 79:hair drier	 class 80:toothbrush*/
	 
    s32Ret = SAMPLE_SVP_NNIE_RoiToRect(&(pstSwParam->stDstScore),
								    &(pstSwParam->stDstRoi), &(pstSwParam->stClassRoiNum), pstSwParam->af32ScoreThr,HI_TRUE,&(pstSwParam->stRect),
								    pstExtFrmInfo->stVFrame.u32Width, pstExtFrmInfo->stVFrame.u32Height,u32BaseWidth,u32BaseHeight);*/

    s32Ret = SAMPLE_SVP_NNIE_RoiToRect(&(s_stYolov3SoftwareParam.stDstScore),
								    &(s_stYolov3SoftwareParam.stDstRoi), &(s_stYolov3SoftwareParam.stClassRoiNum), s_stYolov3SoftwareParam.af32ScoreThr,HI_TRUE,&(s_stYolov3SoftwareParam.stRect),
								    pstExtFrmInfo->stVFrame.u32Width, pstExtFrmInfo->stVFrame.u32Height,u32BaseWidth,u32BaseHeight);

									
    SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,SAMPLE_SVP_ERR_LEVEL_ERROR,
        "Error(%#x),SAMPLE_SVP_NNIE_RoiToRect failed!\\n",s32Ret);
	
    return s32Ret;


/******************************************************************************
* function : NNIE Forward
******************************************************************************/
static HI_S32 SAMPLE_SVP_NNIE_Forward(SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam,
    SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S* pstInputDataIdx,
    SAMPLE_SVP_NNIE_PROCESS_SEG_INDEX_S* pstProcSegIdx,HI_BOOL bInstant)

    HI_S32 s32Ret = HI_SUCCESS;
    HI_U32 i = 0, j = 0;
    HI_BOOL bFinish = HI_FALSE;
    SVP_NNIE_HANDLE hSvpNnieHandle = 0;
    HI_U32 u32TotalStepNum = 0;

    SAMPLE_COMM_SVP_FlushCache(pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].stTskBuf.u64PhyAddr,
        (HI_VOID *) pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].stTskBuf.u64VirAddr,
        pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].stTskBuf.u32Size);

    /*set input blob according to node name*/
    if(pstInputDataIdx->u32SegIdx != pstProcSegIdx->u32SegIdx)
    
        for(i = 0; i < pstNnieParam->pstModel->astSeg[pstProcSegIdx->u32SegIdx].u16SrcNum; i++)
        
            for(j = 0; j < pstNnieParam->pstModel->astSeg[pstInputDataIdx->u32SegIdx].u16DstNum; j++)
            
                if(0 == strncmp(pstNnieParam->pstModel->astSeg[pstInputDataIdx->u32SegIdx].astDstNode[j].szName,
                    pstNnieParam->pstModel->astSeg[pstProcSegIdx->u32SegIdx].astSrcNode[i].szName,
                    SVP_NNIE_NODE_NAME_LEN))
                
                    pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astSrc[i] =
                        pstNnieParam->astSegData[pstInputDataIdx->u32SegIdx].astDst[j];
                    break;
                
            
            SAMPLE_SVP_CHECK_EXPR_RET((j == pstNnieParam->pstModel->astSeg[pstInputDataIdx->u32SegIdx].u16DstNum),
                HI_FAILURE,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error,can't find %d-th seg's %d-th src blob!\\n",
                pstProcSegIdx->u32SegIdx,i);
        
    

    /*NNIE_Forward*/

    gettimeofday(&start,NULL);

    s32Ret = HI_MPI_SVP_NNIE_Forward(&hSvpNnieHandle,
        pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astSrc,
        pstNnieParam->pstModel, pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst,
        &pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx], bInstant);

    gettimeofday(&end,NULL);
    
    unsigned  long diff;
    diff = 1000000 * (end.tv_sec-start.tv_sec)+ end.tv_usec-start.tv_usec;
    printf(time is %ld\\n”,diff);

    SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,SAMPLE_SVP_ERR_LEVEL_ERROR,
        "Error,HI_MPI_SVP_NNIE_Forward failed!\\n");

    if(bInstant)
    
  

以上是关于HISI3559A 使用yolov3 (VI-VPSS-VO)实时目标检测的主要内容,如果未能解决你的问题,请参考以下文章

Hisi3559AV100 RuyiStudio使用 NNIE量化模型 板端运行成功

c_cpp Hi3559A特征图遍历

c_cpp Hi3559A插件层写法

(原)hisi3531立体声pcm实现播放方式

基于海思3559A方案+Atlas 200 AI模块_边缘计算平台开发及接口定义

有谁比较过海思Hi3519a与海思Hi3559a的实际isp效果差别?