Toybrick

RKNN推理相关

自由的学习

注册会员

积分
165
发表于 2023-9-11 15:31:48    查看: 1104|回复: 3 | [复制链接]    打印 | 显示全部楼层
本帖最后由 自由的学习 于 2023-9-11 15:57 编辑

用C++推理RKNN模型遇到了一个很奇葩的问题,如果是单独用一张图片推理结果是完全正确的,然后我循环读取多张图片去推理,就出现了一个很奇怪的现象,第一张结果正确,第二张的推理结果还是第一张的,第三张是第二张的结果,依次类推之后每一张的结果都是前一张图片的了;经检查代码,先将每次读取的图片数据在传入resize_buf前保存下来,查看是没问题的,resize_buf接收数据前都有memset,用rga进行resize和转格式将数据塞给resize_buf,然后就直接传给inputs了,中间也没有其他任何多余处理;最后推理结果就是上面描述的奇怪现象了  我的API和DRV版本都是1.7.5

下面是处理的接口
  1. void HRKNNDecode::setInputsData(cv::Mat rgbImg, std::string imgname)
  2. {
  3.         long long begs = NowMs1();
  4.         int height = rgbImg.rows;
  5.         int width = rgbImg.cols;

  6.         int ret = 0;
  7.         IM_STATUS       STATUS;
  8.         rga_buffer_t         src;
  9.         rga_buffer_t         dst;
  10.         rga_buffer_t         mid;

  11.         memset(&src, 0, sizeof(src));
  12.         memset(&dst, 0, sizeof(dst));
  13.         memset(&mid, 0, sizeof(mid));
  14.         memset(resize_buf, 0, m_input_height * m_input_width * m_channel);
  15.         rknn_input inputs[1];
  16.         memset(inputs, 0, sizeof(inputs));
  17.         inputs[0].index = 0;
  18.         inputs[0].size = m_input_width * m_input_height * m_channel;
  19.         inputs[0].pass_through = 0;
  20.         inputs[0].fmt = RKNN_TENSOR_NHWC;
  21.         inputs[0].type = RKNN_TENSOR_UINT8;

  22.         long long beforecvttimes, cvttimes, resizetimes;
  23.         src = wrapbuffer_virtualaddr((void *)rgbImg.data, width, height, RK_FORMAT_BGR_888);
  24.         dst = wrapbuffer_virtualaddr((void *)resize_buf, m_input_width, m_input_height, RK_FORMAT_RGB_888);
  25.         if (src.width == 0 || dst.width == 0) {
  26.                 printf("wrapbuffer_virtualaddr src or dst width == 0,%s\n", imStrError());
  27.                 return;
  28.         }
  29.        
  30.         STATUS = imresize(src, dst);
  31.         if (STATUS == IM_STATUS_SUCCESS) {
  32.                 //printf("---------------imresize success!\n");
  33.         }
  34.         else {
  35.                 printf("**********imresize failed,ret==%d,%s\n", STATUS, imStrError(STATUS));

  36.                 return;
  37.         }
  38.         inputs[0].buf = resize_buf;

  39.         long long afterimgs = NowMs1();
  40.         printf("before process times == %lld\n", afterimgs - begs);
  41.         int res = rknn_inputs_set(m_ctx, 1, inputs);
  42.         if (res < 0)
  43.         {
  44.                 printf("rknn_input_set fail! ret=%d\n", res);
  45.                 return;
  46.         }

  47.         rknn_output outputs[io_num.n_output];
  48.         memset(outputs, 0, sizeof(outputs));
  49.         for (int i = 0; i < io_num.n_output; i++)
  50.         {
  51.                 outputs[i].want_float = 0;
  52.                 outputs[i].index = i;
  53.         }

  54.         res = rknn_run(m_ctx, NULL);
  55.         if (res < 0)
  56.         {
  57.                 printf("rknn_run fail!ret=%d\n", res);
  58.                 return;
  59.         }

  60.         res = rknn_outputs_get(m_ctx, io_num.n_output, outputs, NULL);
  61.         if (res < 0)
  62.         {
  63.                 printf("rknn_outputs_get fail!ret=%d\n", res);
  64.                 rknn_outputs_release(m_ctx, io_num.n_output, outputs);
  65.                 return;

  66.         }

  67.         long long rknntimes = NowMs1();
  68.         printf("rknn run times == %lld\n", rknntimes - afterimgs);
  69.         float scale_w = (float)width / m_input_width;
  70.         float scale_h = (float)height / m_input_height;

  71.         std::vector<OutputPose> output_res;
  72.         uint8_t* outputs_buf[io_num.n_output];
  73.         memset(outputs_buf, 0, sizeof(outputs_buf));
  74.         for (int i = 0; i < io_num.n_output; ++i)
  75.         {
  76.                 outputs_buf[i] = (uint8_t*)outputs[i].buf;
  77.         }

  78.         if (post_process(outputs_buf, out_zps, out_scales, output_res, scale_w, scale_h, width, height))
  79.         {
  80.                 //
  81.         }
  82.         else
  83.         {
  84.                 printf("have res  == %d\n", output_res.size());
  85.                 long long postptime = NowMs1();
  86.                 printf("postprocess times == %lld\n", postptime - rknntimes);
  87.                 //DrawPred(rgbImg, output_res, SKELETON, KPS_COLORS, LIMB_COLORS);
  88.                 //cv::imwrite(imgname, rgbImg);
  89.         }

  90.         rknn_outputs_release(m_ctx, io_num.n_output, outputs);

  91.         return;
  92. }
复制代码


回复

使用道具 举报

自由的学习

注册会员

积分
165
 楼主| 发表于 2023-9-12 10:58:44 | 显示全部楼层
我尝试在推理第二张图片 rknn_run之前调用了 rknn_outputs_get(m_ctx, io_num.n_output, outputs, NULL);发现竟然没有阻塞,还能将第一张图片的结果给获取到,然后在 rknn_run后再次正常流程调用rknn_outputs_get获取推理结果,这时候正确的第二张结果就获取到了,推理第三张图片同样走第二张的流程时,在rknn_run前调用rknn_outputs_get就会出现阻塞,这应该才是正确的现象吧。所以为什么我第一次推理结束后,第二张推理前rknn_outputs_get还能获取到结果啊,是我哪里清空操作没执行吗?如果是的话,为什么第三张就会正常阻塞了呢
回复

使用道具 举报

jefferyzhang

版主

积分
12768
发表于 2023-9-12 11:47:16 | 显示全部楼层
旧版本rknn api是可以配置获取模式的,async模式下output拿到的永远是上一帧的内容,这样方便开发无阻塞代码。
新版本文档里我确实也没找到这个接口在哪,是不是误入了async模式
回复

使用道具 举报

自由的学习

注册会员

积分
165
 楼主| 发表于 2023-9-12 13:18:13 | 显示全部楼层
jefferyzhang 发表于 2023-9-12 11:47
旧版本rknn api是可以配置获取模式的,async模式下output拿到的永远是上一帧的内容,这样方便开发无阻塞代 ...

谢谢,终于解决了,是初始化时候打开了异步模式导致的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

产品中心 购买渠道 开源社区 Wiki教程 资料下载 关于Toybrick


快速回复 返回顶部 返回列表