隔了好久来填坑,这次写一下怎么在板卡中部署模型。

打个小广告:

海思hi3519av100开发板链接:

https://item.taobao.com/item.htm?spm=a230r.1.14.117.4afe75a61WreAX&id=586610485052&ns=1&abbucket=1#detail

除了SDK与底板图纸之外我们提供了EMMC文件配置和摄像头采集到RFCN深度神经网络的物体识别和HDMI显示的完整代码,帮助开发者快速部署模型。

开发板中新更新了yolov3的demo,那么从demo中把NNIE相关的截取出来和大家分享一下。


/******************************************************************************
* function : ive sample
******************************************************************************/
#ifdef __HuaweiLite__
int app_main(int argc, char *argv[])
#else
int main(int argc, char *argv[])
#endif
{int s32Ret = HI_SUCCESS;s_ppChCmdArgv = argv;SAMPLE_SVP_NNIE_Yolov3();return s32Ret;
}

主函数很简单,直接跑了demo,读取图片后进行物体识别。

具体函数放在 ../深度学习demo\yolov3\yolov3\sample 中  sample_nnie.c。

/******************************************************************************
* function : show YOLOV3 sample(image 416x416 U8_C3)
******************************************************************************/
void SAMPLE_SVP_NNIE_Yolov3(void)
{HI_CHAR *pcSrcFile = "./data/nnie_image/rgb_planar/dog_bike_car_416x416.bgr";HI_CHAR *pcModelName = "./data/nnie_model/detection/inst_yolov3_cycle.wk";HI_U32 u32PicNum = 1;HI_FLOAT f32PrintResultThresh = 0.0f;HI_S32 s32Ret = HI_SUCCESS;SAMPLE_SVP_NNIE_CFG_S   stNnieCfg = {0};SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S stInputDataIdx = {0};SAMPLE_SVP_NNIE_PROCESS_SEG_INDEX_S stProcSegIdx = {0};/*Set configuration parameter*/f32PrintResultThresh = 0.15f;stNnieCfg.pszPic= pcSrcFile;stNnieCfg.u32MaxInputNum = u32PicNum; //max input image num in each batchstNnieCfg.u32MaxRoiNum = 0;stNnieCfg.aenNnieCoreId[0] = SVP_NNIE_ID_0;//set NNIE core/*Sys init*/SAMPLE_COMM_SVP_CheckSysInit();/*Yolov3 Load model*/SAMPLE_SVP_TRACE_INFO("Yolov3 Load model!\n");s32Ret = SAMPLE_COMM_SVP_NNIE_LoadModel(pcModelName,&s_stYolov3Model);SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret,YOLOV3_FAIL_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 inSAMPLE_SVP_NNIE_Yolov3_SoftwareInit function are correct*/SAMPLE_SVP_TRACE_INFO("Yolov3 parameter initialization!\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,YOLOV3_FAIL_0,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error,SAMPLE_SVP_NNIE_Yolov3_ParamInit failed!\n");/*Fill src data*/SAMPLE_SVP_TRACE_INFO("Yolov3 start!\n");stInputDataIdx.u32SegIdx = 0;stInputDataIdx.u32NodeIdx = 0;s32Ret = SAMPLE_SVP_NNIE_FillSrcData(&stNnieCfg,&s_stYolov3NnieParam,&stInputDataIdx);SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret,YOLOV3_FAIL_0,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error,SAMPLE_SVP_NNIE_FillSrcData failed!\n");gettimeofday(&tp,NULL);g_time_start = tp.tv_sec * 1000 + tp.tv_usec/1000;/*NNIE process(process the 0-th segment)*/stProcSegIdx.u32SegIdx = 0;s32Ret = SAMPLE_SVP_NNIE_Forward(&s_stYolov3NnieParam,&stInputDataIdx,&stProcSegIdx,HI_TRUE);SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret,YOLOV3_FAIL_0,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error,SAMPLE_SVP_NNIE_Forward failed!\n");/*Software process*//*if user has changed net struct, please make sure SAMPLE_SVP_NNIE_Yolov3_GetResultfunction input datas are correct*/s32Ret = SAMPLE_SVP_NNIE_Yolov3_GetResult(&s_stYolov3NnieParam,&s_stYolov3SoftwareParam);SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret,YOLOV3_FAIL_0,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error,SAMPLE_SVP_NNIE_Yolov3_GetResult failed!\n");/*print result, this sample has 81 classes:class 0:background      class 1:person       class 2:bicycle         class 3:car            class 4:motorbike      class 5:aeroplaneclass 6:bus             class 7:train        class 8:truck           class 9:boat           class 10:traffic lightclass 11:fire hydrant   class 12:stop sign   class 13:parking meter  class 14:bench         class 15:birdclass 16:cat            class 17:dog         class 18:horse          class 19:sheep         class 20:cowclass 21:elephant       class 22:bear        class 23:zebra          class 24:giraffe       class 25:backpackclass 26:umbrella       class 27:handbag     class 28:tie            class 29:suitcase      class 30:frisbeeclass 31:skis           class 32:snowboard   class 33:sports ball    class 34:kite          class 35:baseball batclass 36:baseball glove class 37:skateboard  class 38:surfboard      class 39:tennis racket class 40bottleclass 41:wine glass     class 42:cup         class 43:fork           class 44:knife         class 45:spoonclass 46:bowl           class 47:banana      class 48:apple          class 49:sandwich      class 50orangeclass 51:broccoli       class 52:carrot      class 53:hot dog        class 54:pizza         class 55:donutclass 56:cake           class 57:chair       class 58:sofa           class 59:pottedplant   class 60bedclass 61:diningtable    class 62:toilet      class 63:vmonitor       class 64:laptop        class 65:mouseclass 66:remote         class 67:keyboard    class 68:cell phone     class 69:microwave     class 70:ovenclass 71:toaster        class 72:sink        class 73:refrigerator   class 74:book          class 75:clockclass 76:vase           class 77:scissors    class 78:teddy bear     class 79:hair drier    class 80:toothbrush*/SAMPLE_SVP_TRACE_INFO("Yolov3 result:\n");(void)SAMPLE_SVP_NNIE_Detection_PrintResult(&s_stYolov3SoftwareParam.stDstScore,&s_stYolov3SoftwareParam.stDstRoi, &s_stYolov3SoftwareParam.stClassRoiNum,f32PrintResultThresh);gettimeofday(&tp1,NULL);g_time_end = tp1.tv_sec * 1000 + tp1.tv_usec/1000;printf("yolov3 time : %d ms .\n", g_time_end-g_time_start);YOLOV3_FAIL_0:SAMPLE_SVP_NNIE_Yolov3_Deinit(&s_stYolov3NnieParam,&s_stYolov3SoftwareParam,&s_stYolov3Model);SAMPLE_COMM_SVP_CheckSysExit();
}

是采用完整版YOLOV3的416x416大小输入的模型。从中截取几个函数看一下。

首先是初始化函数:

/******************************************************************************
* function : Yolov3 init
******************************************************************************/
static HI_S32 SAMPLE_SVP_NNIE_Yolov3_ParamInit(SAMPLE_SVP_NNIE_CFG_S* pstCfg,SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, SAMPLE_SVP_NNIE_YOLOV3_SOFTWARE_PARAM_S* pstSoftWareParam)
{HI_S32 s32Ret = HI_SUCCESS;/*init hardware para*/s32Ret = SAMPLE_COMM_SVP_NNIE_ParamInit(pstCfg,pstNnieParam);SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret,INIT_FAIL_0,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error(%#x),SAMPLE_COMM_SVP_NNIE_ParamInit failed!\n",s32Ret);/*init software para*/s32Ret = SAMPLE_SVP_NNIE_Yolov3_SoftwareInit(pstCfg,pstNnieParam,pstSoftWareParam);SAMPLE_SVP_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret,INIT_FAIL_0,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error(%#x),SAMPLE_SVP_NNIE_Yolov3_SoftwareInit failed!\n",s32Ret);return s32Ret;
INIT_FAIL_0:s32Ret = SAMPLE_SVP_NNIE_Yolov3_Deinit(pstNnieParam,pstSoftWareParam,NULL);SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,SAMPLE_SVP_ERR_LEVEL_ERROR,"Error(%#x),SAMPLE_SVP_NNIE_Yolov3_Deinit failed!\n",s32Ret);return HI_FAILURE;}

YOLOV3的相关参数在 SAMPLE_SVP_NNIE_Yolov3_SoftwareInit 函数中进行设置:

/******************************************************************************
* function : Yolov3 software para init
******************************************************************************/
static HI_S32 SAMPLE_SVP_NNIE_Yolov3_SoftwareInit(SAMPLE_SVP_NNIE_CFG_S* pstCfg,SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, SAMPLE_SVP_NNIE_YOLOV3_SOFTWARE_PARAM_S* pstSoftWareParam)
{HI_S32 s32Ret = HI_SUCCESS;HI_U32 u32ClassNum = 0;HI_U32 u32TotalSize = 0;HI_U32 u32DstRoiSize = 0;HI_U32 u32DstScoreSize = 0;HI_U32 u32ClassRoiNumSize = 0;HI_U32 u32TmpBufTotalSize = 0;HI_U64 u64PhyAddr = 0;HI_U8* pu8VirAddr = NULL;pstSoftWareParam->u32OriImHeight = pstNnieParam->astSegData[0].astSrc[0].unShape.stWhc.u32Height;pstSoftWareParam->u32OriImWidth = pstNnieParam->astSegData[0].astSrc[0].unShape.stWhc.u32Width;pstSoftWareParam->u32BboxNumEachGrid = 3;pstSoftWareParam->u32ClassNum = 80;pstSoftWareParam->au32GridNumHeight[0] = 13;pstSoftWareParam->au32GridNumHeight[1] = 26;pstSoftWareParam->au32GridNumHeight[2] = 52;pstSoftWareParam->au32GridNumWidth[0] = 13;pstSoftWareParam->au32GridNumWidth[1] = 26;pstSoftWareParam->au32GridNumWidth[2] = 52;pstSoftWareParam->u32NmsThresh = (HI_U32)(0.15f*SAMPLE_SVP_NNIE_QUANT_BASE);pstSoftWareParam->u32ConfThresh = (HI_U32)(0.25f*SAMPLE_SVP_NNIE_QUANT_BASE);pstSoftWareParam->u32MaxRoiNum = 10;pstSoftWareParam->af32Bias[0][0] = 116;pstSoftWareParam->af32Bias[0][1] = 90;pstSoftWareParam->af32Bias[0][2] = 156;pstSoftWareParam->af32Bias[0][3] = 198;pstSoftWareParam->af32Bias[0][4] = 373;pstSoftWareParam->af32Bias[0][5] = 326;pstSoftWareParam->af32Bias[1][0] = 30;pstSoftWareParam->af32Bias[1][1] = 61;pstSoftWareParam->af32Bias[1][2] = 62;pstSoftWareParam->af32Bias[1][3] = 45;pstSoftWareParam->af32Bias[1][4] = 59;pstSoftWareParam->af32Bias[1][5] = 119;pstSoftWareParam->af32Bias[2][0] = 10;pstSoftWareParam->af32Bias[2][1] = 13;pstSoftWareParam->af32Bias[2][2] = 16;pstSoftWareParam->af32Bias[2][3] = 30;pstSoftWareParam->af32Bias[2][4] = 33;pstSoftWareParam->af32Bias[2][5] = 23;/*Malloc assist buffer memory*/u32ClassNum = pstSoftWareParam->u32ClassNum+1;... /*部分省略*/...return s32Ret;
}

这里面涉及到的数字参数都是在Ruyi中模型量化的时候对应的参数,如果默认用80类yolov3的话基本不用修改。

u32ClassNum代表识别的类别数,这里是默认80类。

主程序里面 f32PrintResultThresh 参数是识别为物体的阈值,这里配置的值是 0.15f,即大于15%的概率时是真实物体。

由于海思模型量化后概率值量级分化很严重,所以阈值可以设置的比较低,与原始模型的阈值设置有些区别。

/******************************************************************************
* function : print detection result
******************************************************************************/
static HI_S32 SAMPLE_SVP_NNIE_Detection_PrintResult(SVP_BLOB_S *pstDstScore,SVP_BLOB_S *pstDstRoi, SVP_BLOB_S *pstClassRoiNum, HI_FLOAT f32PrintResultThresh)
{HI_U32 i = 0, j = 0;HI_U32 u32RoiNumBias = 0;HI_U32 u32ScoreBias = 0;HI_U32 u32BboxBias = 0;HI_FLOAT f32Score = 0.0f;HI_S32* ps32Score = SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_S32,pstDstScore->u64VirAddr);HI_S32* ps32Roi = SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_S32,pstDstRoi->u64VirAddr);HI_S32* ps32ClassRoiNum = SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_S32,pstClassRoiNum->u64VirAddr);HI_U32 u32ClassNum = pstClassRoiNum->unShape.stWhc.u32Width;HI_S32 s32XMin = 0,s32YMin= 0,s32XMax = 0,s32YMax = 0;u32RoiNumBias += ps32ClassRoiNum[0];for (i = 1; i < u32ClassNum; i++){u32ScoreBias = u32RoiNumBias;u32BboxBias = u32RoiNumBias * SAMPLE_SVP_NNIE_COORDI_NUM;/*if the confidence score greater than result threshold, the result will be printed*/if((HI_FLOAT)ps32Score[u32ScoreBias] / SAMPLE_SVP_NNIE_QUANT_BASE >=f32PrintResultThresh && ps32ClassRoiNum[i]!=0){SAMPLE_SVP_TRACE_INFO("==== The %dth class box info====\n", i);}for (j = 0; j < (HI_U32)ps32ClassRoiNum[i]; j++){f32Score = (HI_FLOAT)ps32Score[u32ScoreBias + j] / SAMPLE_SVP_NNIE_QUANT_BASE;if (f32Score < f32PrintResultThresh){break;}s32XMin = ps32Roi[u32BboxBias + j*SAMPLE_SVP_NNIE_COORDI_NUM];s32YMin = ps32Roi[u32BboxBias + j*SAMPLE_SVP_NNIE_COORDI_NUM + 1];s32XMax = ps32Roi[u32BboxBias + j*SAMPLE_SVP_NNIE_COORDI_NUM + 2];s32YMax = ps32Roi[u32BboxBias + j*SAMPLE_SVP_NNIE_COORDI_NUM + 3];SAMPLE_SVP_TRACE_INFO("%d %d %d %d %f\n", s32XMin, s32YMin, s32XMax, s32YMax, f32Score);}u32RoiNumBias += ps32ClassRoiNum[i];}return HI_SUCCESS;
}

上面部分是打印识别到物体类别信息。

最后打印从图片输入到识别输出的时间延迟。

    g_time_end = tp1.tv_sec * 1000 + tp1.tv_usec/1000;printf("yolov3 time : %d ms .\n", g_time_end-g_time_start);

目前运行未做修改的完整版 yolov3时间在70ms左右一张是比较正常的。

开发板资料中 ..深度学习demo\yolov3\data\nnie_model\detection 中提供了已经量化后的 YOLOV3模型,

是从Darknet YOLOV3模型上转成caffe下的yolov3模型的。

..深度学习demo\yolov3\data\nnie_image\rgb_planar 中提供了可供测试的 dog_bike_car.jpg和转换后的.bgr图片。

如何在海思 Hi3519AV100上移植YOLOV3 (3)相关推荐

  1. 海思3519A上运行yolov3(总览)

    架构总览 海思3519A芯片的架构: 系统设计架构图 因为嵌入式板卡上不能进行编译,只能执行指令和运行编译后的执行文件,所以要采用Linux服务器和3519A板卡的交叉编译方式. 设计流程 华为海思官 ...

  2. 海思3519上移植Qt5.5.1

    1. 源码下载 网址:http://download.qt.io/archive/qt/5.5/5.5.1/single/ 源码包: qt-everywhere-opensource-src-5.5. ...

  3. 海思Hi3516A上移植OpenCV

    最近新换了工作,工作中一项任务是将OpenCV移植到Hi3516A平台上.这项工作涉及到很多步骤,中间可以说经历了千难万险,克服了种种艰难困苦,最终成功了!现将过程详细写出,一方面作为此段工作的总结和 ...

  4. 海思3519A上运行yolov3(二)——Linux和Windows开发环境和运行环境搭建

    本文主要讲Linux环境配置和Windows上软件的安装 一.Linux 1. Linux服务器上安装Hi3519A的Linux交叉编译器arm-himix200-linux, 复制Linux交叉编译 ...

  5. 海思3519A上运行yolov3(一)——板卡配置(包括烧写内核、文件系统等)

    一.首次安装SDK 讲SDK安装的压缩包拷贝到Linux服务器进行安装和编译 1.SDK压缩包:Hi3519AV100_SDK_V2.0.1.1.0.tar 2.交叉编译器Linux工具链:arm-h ...

  6. 海思3559AV100上运行自己训练的yolov3

    1.简介 现在海思芯片上只支持将caffemodel转成wk文件,然而网上也没有caffe-yolov3,只能使用darknet-yolov3进行训练,然后将模型文件转换成caffemodel文件,再 ...

  7. 海思Hi3519AV100深度学习方案(一)darknet转caffmodel之caffe安装(基于Ubuntu16.04+python3.5+opencv3.4.0+cuda10.0)

    系列文章目录 海思Hi3519AV100深度学习方案(二)darknet转caffmodel之模型转换(yolov3+caffe+python3.5) 文章目录 系列文章目录 前言 一.系统已有环境检 ...

  8. 从零开始在海思芯片上部署uboot、kernel、rootfs、mpp

    前言 本文介绍的是拿到海思芯片的开发板和海思的SDK开发包,在裸机上部署uboot.kernel.rootfs.mpp的过程,其中不涉及uboot.kernel.rootfs.mpp的细节,主要是介绍 ...

  9. 图像识别——强大的低功耗嵌入式AI方案海思Hi3519AV100介绍

    强大的低功耗嵌入式AI方案海思Hi3519AV100介绍 海思Hi3519AV100是2018年10月在北京安防展展会上第一次进入我们视线的,然后11月初北京一家公司委托我们先研究一下,并从代理拿到初 ...

最新文章

  1. mysql如何下载连接到visual_Visual Studio 2015 Community连接到Mysql
  2. oracle9i安装不上,终于成功安装oracle9i了(Cent OS 4.0+oracle9204)
  3. 从C#到Objective-C,循序渐进学习苹果开发(7)--使用FMDB对Sqlite数据库进行操作
  4. 一文帮你梳理清楚:奇异值分解和矩阵分解 | 技术头条
  5. expo开发React Native快捷键记录
  6. 【Spring-web】RestTemplate源码学习——梳理内部实现过程
  7. SQL Server 2005中更改sa的用户名和密码
  8. [Google Guava] 11-事件总线
  9. windows2003 DNS服务器配置
  10. XP系统中如何查哪些网址曾经远程连接过本机器。
  11. Andorid audio设备名和音频基本概念
  12. Asp.net 高性能数据分页函数,调用示例
  13. ISO14001与ISO45001都是什么认证?
  14. Mac录屏无声音?5分钟解决|mac录屏收音APP-Loopback for Mac使用方法
  15. html5视频加速播放插件,Video Speed Controller Chrome(HTML5视频加速播放插件) v0.3.2 官方免费版...
  16. 完美解决Sudo doesn‘t work: “/etc/sudoers is owned by uid 1000, should be 0”
  17. Python多分类问题pr曲线绘制(含代码)
  18. 铁、髓鞘和大脑:神经影像遇见神经生物学
  19. python画函数图像网格_用python 画一个网格
  20. python项目七:自建公告板

热门文章

  1. adxl345取出值怎么算角度_改了别人的程序和一些自己的研究,用ADXL345测量角度成功...
  2. 一个问题,两人讨论,几行代码,一些启发
  3. 美团网CEO王兴:创业十年屡败屡战 终成硕果
  4. opencv3/C++ mixChannels()详解:4通道图像分割、HSV通道获取
  5. mysql8.0源代码解析_源码解读:MySQL 8.0 InnoDB无锁化设计的日志系统
  6. 电子信息工程——学习资料(更新.........)
  7. PTA: 旅游规划 [狄杰斯特拉+堆优化+链式前向星]
  8. 批量文件改名工具软件
  9. 敷完面膜后要擦水乳吗_敷完面膜还要擦水乳吗 顺序务必要搞清楚
  10. 分钟换算成时分秒格式