查看: 1980|回复: 0

[评测分享] 【米尔FZ3深度学习计算卡】视频流识别测试

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-10 08:31
  • 签到天数: 300 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2020-12-6 23:44:36 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 day_day 于 2020-12-7 20:45 编辑

    (一)PC端测试
    由于之前设备端版本不兼容的原因,因此想要现在PC端测试一下。PC端linux部署测试需要训练服务器版本,还需要额外申请一个序列号。
    PC端编译与设备端基本相似,但运行的时候有问题,一直提示找不到库:
    $ ./mysrc
    ./mysrc: error while loading shared libraries: libeasyedge.so.0.5.8: cannot open shared object file: No such file or directory

    这是因为编译的时候cmake是指定路径来识别库的,而系统中又不像FZ3设备端直接在系统环境变量的路径内带有相关库,因此要在控制台暴露一下库的路径:
    1. export LD_LIBRARY_PATH=../../lib/
    复制代码

    (二)PC端视频流
    1-PC端又可以用我最熟悉的Qt了
    只需要在pro文件里面加入opencv和百度AI相关的系统库即可:
    1. LIBS += -L /usr/local/lib/libopencv_*.so
    2. LIBS += -L ../../lib/lib*.so
    复制代码

    2-进行一些初始化配置
    1.     global_controller()->set_licence_key("");

    2.     // 1. 配置输出log
    3.     EdgeLogConfig log_config;
    4.     log_config.enable_debug = false;
    5.     global_controller()->set_log_config(log_config);

    6.     // 2. 设置识别配置
    7.     PaddleFluidConfig config;

    8.     // 2.1. 使用CPU预测
    9.     config.use_gpu = false;

    10.     // 2.2. 使用NVIDIA GPU预测;请务必下载GPU版本SDK
    11. //    config.use_gpu = true;
    12. //    config.fraction_of_gpu_memory = 0.2;
    13. //    config.device = 0;

    14. //    config.model_dir = argv[1];
    15.     config.model_dir = "../../../../RES";

    16.     // 3. 加载
    17.     auto predictor = global_controller()->CreateEdgePredictor<PaddleFluidConfig>(config);

    18.     // 4. 初始化
    19.     if (predictor->init() != EDGE_OK)
    20.     {
    21.         exit(-1);
    22.     }

    23.     // 5.读取待识别图片路径
    24. //    std::stringstream img_path;
    25. ////    img_path << argv[2];
    26. //    img_path << "1.jpg";
    27. //    auto img = cv::imread(img_path.str().c_str());

    28.     cv::Mat rgbImageL;
    29.     cv::VideoCapture left_VideoCapture;
    30.     left_VideoCapture.set(cv::CAP_PROP_FRAME_WIDTH,640);
    31.     left_VideoCapture.set(cv::CAP_PROP_FRAME_HEIGHT,480);
    32.     if(!left_VideoCapture.isOpened())
    33.         left_VideoCapture.open(0);
    复制代码

    3-为了更好地展示,我将至保存为视频流
    1.     cv::Size size = cv::Size(640,480);
    2.     cv::VideoWriter Writer("dect_result2.avi", CV_FOURCC('D', 'I', 'V', 'X'), 1, size, true);
    复制代码


    4-识别时输出到视频流

    1.     struct timeval tpstart, tpend;
    2.     gettimeofday(&tpstart,NULL);

    3.     while(true)
    4.     {
    5.         cv::Mat img;
    6.         left_VideoCapture >> img;
    7.         if(img.empty()) break;
    8.         // 6.识别
    9.         std::vector<EdgeResultData> result2;
    10.         predictor->infer(img, result2);

    11.         if (result2.empty()) {
    12.             std::cerr << "Result is empty: " << std::endl;
    13.         }
    14.         int top = 0;
    15.         for (auto &v : result2)
    16.         {
    17.             std::cout << v.index << ", " << v.label << ", p:" << v.prob;
    18.             if (predictor->model_kind() == EdgeModelKind::kObjectDetection
    19.                     || predictor->model_kind() == EdgeModelKind::kImageSegmentation
    20.                     || predictor->model_kind() == EdgeModelKind::kFaceDetection)
    21.             {
    22.                 std::cout << " loc: "
    23.                           << v.x1 << ", " << v.y1 << ", " << v.x2 << ", " << v.y2;
    24.                 auto p1 = cv::Point(static_cast<int>(v.x1 * img.cols),
    25.                                     static_cast<int>(v.y1 * img.rows));
    26.                 auto p2 = cv::Point(static_cast<int>(v.x2 * img.cols),
    27.                                     static_cast<int>(v.y2 * img.rows));
    28.                 if(v.prob>0.8)
    29.                     cv::rectangle(img, p1, p2, RED, 2);
    30.                 else
    31.                     cv::rectangle(img, p1, p2, PINK, 2);
    32.                 if (predictor->model_kind() == EdgeModelKind::kFaceDetection) {
    33.                     cv::putText(img, std::to_string(v.prob), p1, cv::FONT_HERSHEY_PLAIN, 0.8, GREEN, 1);
    34.                 } else {
    35.                     cv::putText(img, v.label, p1, cv::FONT_HERSHEY_PLAIN, 1, BLUE, 2);
    36.                 }
    37.             }

    38.             // 图像分割画mask
    39.             if (predictor->model_kind() == EdgeModelKind::kImageSegmentation)
    40.             {
    41.                 cv::Mat tmp(img.rows, img.cols, CV_8UC3, cv::Scalar(0, 0, 0));
    42.                 cv::Vec3b random_color((v.index + 3) * 13 % 255,
    43.                                        (v.index + 7) * 19 % 255,
    44.                                        (v.index + 11) * 29 % 255);
    45.                 for(int y = 0; y < tmp.rows; ++y)
    46.                 {
    47.                     for(int x = 0; x < tmp.cols; ++x)
    48.                     {
    49.                         if (v.mask.at<uint8_t>(y, x) == 1)
    50.                         {
    51.                             tmp.at<cv::Vec3b>(y, x) = random_color;
    52.                         }
    53.                     }
    54.                 }

    55.                 // 图片融合
    56.                 cv::addWeighted(tmp, 0.95, img, 1, 0.0, img);
    57.             }
    58.             gettimeofday(&tpend,NULL);
    59.             std::cout << std::endl;
    60.         }
    61.         if (predictor->model_kind() == EdgeModelKind::kObjectDetection
    62.                 || predictor->model_kind() == EdgeModelKind::kImageSegmentation
    63.                 || predictor->model_kind() == EdgeModelKind::kFaceDetection)
    64.         {
    65. //            img_path << ".result.jpg";
    66. //            std::cout << "Write result to " << img_path.str() << std::endl;
    67. //            cv::imwrite(img_path.str(), img);
    68. //            cv::imwrite("dect_result.jpg", img);
    69.             Writer.write(img);
    70.             cv::imshow("dect result", img);
    71.             if(cv::waitKey(30)=='q') break;
    72.             static int i=0;
    73.             i++;
    74.             if(i>30) break;
    75.         }

    76.         std::cout << "\tuse time:"
    77.                   << (tpend.tv_sec-tpstart.tv_sec) * 1000000 + (tpend.tv_usec - tpstart.tv_usec);
    78.         tpstart = tpend;
    79.         std::cout << std::endl;
    80.     }
    81.     Writer.release();
    82.     std::cout << "Done" << std::endl;
    复制代码

    识别效果:
    dect.gif

    紫色部分是不足0.8置信度的,超过0.8置信度标为红色,可以看到效果还不错。
    深度截图_选择区域_20201206234628.png
    在识别图片的时候,PC端和设备端高性能模式下都是将近1s,但实际应用到视频的时候,只有开始的几帧耗时有些波动,其余都在300ms出头。



    (三)设备端视频流尝试
    设备端一上来就遭遇了滑铁卢:
    显示报了一个mmap错误,然后设备干脆利落地死机了。
    然后我改成录像再放到FZ3上,让opencv直接读avi视频文件,结果还是不行,依然死机:

    深度截图_mate-terminal_20201206233753.png
    估计是opencv的库在移植的时候没有适配解码部分的驱动。
    但是转念一想,之前的帖子测试螺丝识别的时候是可以用摄像头的,打开其源码一看,果然没有那么简单:
    1. int Camera::read_frame(void) {
    2.     struct v4l2_buffer buf;
    3.     unsigned int i = 0;

    4.     CLEAR(buf);
    5.     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    6.     buf.memory = V4L2_MEMORY_MMAP;

    7.     if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
    8.         switch (errno) {
    9.         case EAGAIN:
    10.             return 0;
    11.         case EIO:
    12.                 /* Could ignore EIO, see spec. */
    13.                 /* fall through */
    14.         default:
    15.                 errno_exit("VIDIOC_DQBUF");
    16.         }
    17.     }

    18.     process_image(buffers[buf.index].start, buf.bytesused);

    19.     if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) {
    20.         errno_exit("VIDIOC_QBUF");
    21.     }
    22.     return 0;
    23. }
    复制代码

    这是使用v4l2来读的,初始化的时候还要初始化mmap,门槛还挺高的。
    1. void Camera::init_mmap(void) {
    2.     struct v4l2_requestbuffers req;
    3.     CLEAR(req);

    4.     req.count = 3;
    5.     req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    6.     req.memory = V4L2_MEMORY_MMAP;

    7.     if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
    8.         if (EINVAL == errno) {
    9.             fprintf(stderr, "%s does not support "
    10.                      "memory mappingn", dev_name);
    11.             exit(EXIT_FAILURE);
    12.         } else {
    13.             errno_exit("VIDIOC_REQBUFS");
    14.         }
    15.     }

    16.     if (req.count < 2) {
    17.         fprintf(stderr, "Insufficient buffer memory on %s\n",
    18.                  dev_name);
    19.         exit(EXIT_FAILURE);
    20.     }
    21.     buffers = (struct buffer*)calloc(req.count, sizeof(*buffers));
    22.     if (!buffers) {
    23.         fprintf(stderr, "Out of memory\\n");
    24.         exit(EXIT_FAILURE);
    25.     }

    26.     for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
    27.         struct v4l2_buffer buf;
    28.         CLEAR(buf);

    29.         buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    30.         buf.memory      = V4L2_MEMORY_MMAP;
    31.         buf.index       = n_buffers;

    32.         if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
    33.             errno_exit("VIDIOC_QUERYBUF");

    34.         buffers[n_buffers].length = buf.length;
    35.         buffers[n_buffers].start =
    36.                 mmap(NULL /* start anywhere */,
    37.                       buf.length,
    38.                       PROT_READ | PROT_WRITE /* required */,
    39.                       MAP_SHARED /* recommended */,
    40.                       fd, buf.m.offset);

    41.         if (MAP_FAILED == buffers[n_buffers].start) {
    42.             errno_exit("mmap");
    43.         }         
    44.     }
    45. }
    复制代码





    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-4-20 10:21 , Processed in 0.124096 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.