nihui · 2 天前

【“星睿O6”评测】三套OpenCV,OpenCL/KleidiCV/JPG硬件编码加速测试

标题实在缩不到50个字,只好把开头的【“星睿O6”AI PC开发套件评测】简写了,远标题应该是

【“星睿O6”AI PC开发套件评测】三套OpenCV性能测试,OpenCL加速测试,KleidiCV加速测试,JPG硬件编码加速测试

安谋科技、此芯科技与瑞莎计算机联合打造了面向AI PC、边缘、机器人等不同场景的“星睿O6”开发套件

该套件异构集成了Arm®v9 CPU核心、Arm Immortalis™ GPU以及安谋科技“周易”NPU

三套OpenCV?

你没有看错,真的是三套!

OpenCV 是一个开源的计算机视觉和机器学习库,提供了各种图像处理和分析功能,比如滤镜、特征检测和对象识别,是我们实现炫酷视觉效果和聪明机器的好帮手

特性apt-opencvcix-opencvopencv-mobile
版本4.6.04.8.04.11.0
编译优化-O2-O3-O3
支持模块全部156
图片全部全部stb
视频ffmpeg+v4l2v4l2v4l2
多线程TBBOpenMPOpenMP
QT界面支持不支持不支持
OpenCL支持支持不支持
安装位置/usr/usr/share/cix需自己编译
  1. 从 apt 安装的 opencv

apt安装的opencv是最完整的,能直接在cmake中 find_package(OpenCV) 找到和使用

apt install libopencv-dev

cmake例子

find_package(OpenCV REQUIRED)
add_executable(test main.cpp)
target_link_libraries(test ${OpenCV_LIBS})
  1. 原系统自带 cix-opencv

无需额外安装,系统自带,但是没有包含cmake的target文件,无法通过标准 find_package(OpenCV REQUIRED) 找到,用起来会稍微麻烦些,要自己配置下include/lib目录

include_directories(/usr/share/cix/include/opencv4)
link_directories(/usr/share/cix/lib)
add_executable(test main.cpp)
target_link_libraries(test opencv_highgui opencv_imgcodecs opencv_imgproc opencv_core)
  1. nihui/opencv-mobile

opencv-mobile 通过调整编译参数,删减部分opencv源码,来最小化编译的 opencv 库
提供了 opencv 常用的功能,如读写图片,处理,矩阵操作等等,版本与上游同步,无第三方依赖
在绝大多数情况下,以 1/10 的体积无痛替换官方 opencv,尤其适合对体积有特殊要求的移动端和嵌入式环境

opencv-4.11支持了KleidiCV库集成,KleidiCV利用了最新Arm CPU中的高性能图像处理功能,可被集成至各类计算机视觉框架中,从而简化并加速计算机视觉工作负载的性能优化,而无需开发者执行额外操作。

开启 KleidiCV 编译步骤

wget https://github.com/nihui/opencv-mobile/releases/latest/download/opencv-mobile-4.11.0.zip
unzip -q opencv-mobile-4.11.0.zip
cd opencv-mobile-4.11.0
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../aarch64-linux-gnu.toolchain.cmake -DCMAKE_INSTALL_PREFIX=`pwd`/install -DCMAKE_BUILD_TYPE=Release `cat ../options.txt` -DBUILD_opencv_world=OFF -DWITH_KLEIDICV=ON ..
make -j12
make install

假设最后安装到了 /home/radxa/opencv-mobile-4.11.0/build/install 路径,那么这样配置即可使用,比apt版本多一行

set(OpenCV_DIR "/home/radxa/opencv-mobile-4.11.0/build/install/lib/cmake/opencv4")
find_package(OpenCV REQUIRED)
add_executable(test main.cpp)
target_link_libraries(test ${OpenCV_LIBS})

图像处理测试 CPU 版本

为防止多线程测速时的耗时不稳定,规定只使用单线程

cv::setNumThreads(1);

为防止大小核心之间被调度导致耗时不稳定,用 taskset 命令绑定大核/小核

taskset -c 0 ./test
taskset -c 1 ./test

简单造了一套opencv图像处理,包含常用的缩放,旋转,高斯模糊,锐化,颜色空间转换,边缘检测,图像叠加,输入1920x1080的BGR图片,重复200轮取最小耗时

double mint = 999999;

cv::Mat out;
cv::Mat grad_x;
cv::Mat grad_y;
cv::Mat abs_grad_x;
cv::Mat abs_grad_y;
for (int i = 0; i < 200; i++)
{
    double t0 = get_current_time();

    cv::resize(bgr, out, cv::Size(1000, 800));
    cv::rotate(out, out, cv::ROTATE_90_CLOCKWISE);
    cv::GaussianBlur(out, out, cv::Size(5, 5), 0, 0);
    cv::addWeighted(out, 2.f, out, -1.f, 0, out);
    cv::cvtColor(out, out, cv::COLOR_BGR2GRAY);
    cv::Sobel(out, grad_x, -1, 1, 0);
    cv::Sobel(out, grad_y, -1, 1, 0);
    cv::convertScaleAbs(grad_x, abs_grad_x);
    cv::convertScaleAbs(grad_y, abs_grad_y);
    cv::addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, out);

    double t1 = get_current_time();

    mint = std::min(mint, t1 - t0);
}

fprintf(stderr, "mint %.2fms\n", mint);

图像处理测试 OpenCL 版本

apt和cix版opencv都支持OpenCL加速,经测试发现在orion o6上默认可用,结果和CPU一致

同样的过程用 UMat 跑一次

cv::ocl::setUseOpenCL(true);
double cl_mint = 999999;

cv::UMat cl_bgr = bgr.getUMat(cv::ACCESS_READ);
cv::UMat cl_out;
cv::UMat cl_grad_x;
cv::UMat cl_grad_y;
cv::UMat cl_abs_grad_x;
cv::UMat cl_abs_grad_y;
for (int i = 0; i < 200; i++)
{
    double t0 = get_current_time();

    cv::resize(cl_bgr, cl_out, cv::Size(1000, 800));
    cv::rotate(cl_out, cl_out, cv::ROTATE_90_CLOCKWISE);
    cv::GaussianBlur(cl_out, cl_out, cv::Size(5, 5), 0, 0);
    cv::addWeighted(cl_out, 2.f, cl_out, -1.f, 0, cl_out);
    cv::cvtColor(cl_out, cl_out, cv::COLOR_BGR2GRAY);
    cv::Sobel(cl_out, cl_grad_x, -1, 1, 0);
    cv::Sobel(cl_out, cl_grad_y, -1, 1, 0);
    cv::convertScaleAbs(cl_grad_x, cl_abs_grad_x);
    cv::convertScaleAbs(cl_grad_y, cl_abs_grad_y);
    cv::addWeighted(cl_abs_grad_x, 0.5, cl_abs_grad_y, 0.5, 0, cl_out);

    double t1 = get_current_time();

    cl_mint = std::min(cl_mint, t1 - t0);
}

fprintf(stderr, "cl_mint %.2fms\n", cl_mint);

out = cl_out.getMat(cv::ACCESS_READ).clone();

图像处理性能测试结果

1.png

耗时(ms),越小越好

debian opencvcix-opencvopencv-mobile + KleidiCV
大核cpu16.2415.0913.65
大核opencl3.643.57n/a
小核cpu82.6885.8673.06
小核opencl5.895.89n/a

结论如下

  • CPU大核性能全面显著优于小核
  • OpenCL性能显著优于CPU
  • KleidiCV为opencv-mobile提供了有效的加速

因此

  • CPU做图像处理,推荐使用 opencv-mobile + KleidiCV
  • GPU做图像处理,apt和cix的区别不大

基于V4L2的JPG硬件编码

图像读写也是十分耗时的过程,这里再用三套opencv分别测试下 1920x1080 BGR JPG图片的编解码

cv::Mat bgr = cv::imread("in.jpg", 1);
cv::imwrite("out.jpg", bgr);

opencv-mobile之前做过一些soc的硬件编解码功能集成

通过 v4l2 工具发现,orion o6支持的硬件编解码能力十分全面!其中就包含了JPEG编解码

但遗憾的是,isp并没有单独暴露出来,无法利用isp硬件加速 RGB2YUV 这类的颜色空间转换

orion o6 支持的硬件解码

radxa@orion-o6:~/opencv/build$ v4l2-ctl -d 3 --list-formats-out
ioctl: VIDIOC_ENUM_FMT
        Type: Video Output Multiplanar

        [0]: 'AVS1' (AVS, compressed)
        [1]: 'AVS2' (AVS2, compressed)
        [2]: 'H263' (H.263, compressed)
        [3]: 'H264' (H.264, compressed)
        [4]: 'HEVC' (HEVC, compressed)
        [5]: 'MPG2' (MPEG-2 ES, compressed)
        [6]: 'MPG4' (MPEG-4 Part 2 ES, compressed)
        [7]: 'VC1G' (VC-1 (SMPTE 412M Annex G), compressed)
        [8]: 'VC1L' (VC-1 (SMPTE 412M Annex L), compressed)
        [9]: 'VP80' (VP8, compressed)
        [10]: 'VP90' (VP9, compressed)
        [11]: 'AV01' (AV1, compressed)
        [12]: 'JPEG' (JFIF JPEG, compressed)
        [13]: 'MJPG' (Motion-JPEG, compressed)

orion o6 支持的硬件编码

radxa@orion-o6:~/opencv/build$ v4l2-ctl -d 4 --list-formats
ioctl: VIDIOC_ENUM_FMT
        Type: Video Capture Multiplanar

        [0]: 'H264' (H.264, compressed)
        [1]: 'HEVC' (HEVC, compressed)
        [2]: 'VP80' (VP8, compressed)
        [3]: 'VP90' (VP9, compressed)
        [4]: 'JPEG' (JFIF JPEG, compressed)
        [5]: 'MJPG' (Motion-JPEG, compressed)

沿用之前做树莓派v4l2 jpg编码的经验 https://zhuanlan.zhihu.com/p/...

可以在 orion o6 上类似的实现 jpg 编码,区别在于不再需要 isp 中转,直接对编码器喂 RGB 数据就能得到 JPEG 数据

原本是要把jpg解码也一起实现,可惜倒腾了半天总是无法获取解码后的数据,由于没有技术资料,又缺乏相关参考代码,暂时放弃了 qaq

只测试了 1920x1080 的图片,代码写的比较粗糙,后续等有空整理后再 pull request 到 opencv-mobile 仓库中吧

JPG图像编解码性能测试结果

2.png

耗时(ms),越小越好

debian opencvcix-opencvopencv-mobile + KleidiCV + v4l2
JPG解码 大核cpu11.3520.1512.88
JPG解码 小核cpu38.1872.2739.04
JPG编码 大核cpu13.2915.094.64 (v4l2)
JPG编码 小核cpu49.3584.1210.73 (v4l2)

结论如下

  • cix版opencv的jpg编解码性能显著差于apt和opencv-mobile,即便都是用cpu处理
  • 基于V4L2的JPG硬件编码能获得大幅加速!

小小的总结

  1. orion o6 的 armv9 cpu 能享受到 ARM KleidiCV 的优化成果,有加速效果
  2. orion o6 的 opencv opencl 整合很不错,没有遇到什么坑,使用 UMat 有加速效果
  3. orion o6 的 v4l2 视频编解码硬件适配全面,JPEG编码性能也很好,这对摄像头直播推流很有帮助
推荐阅读
关注数
19
文章数
11
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息