opencv-mobile
简介
opencv-mobile 是一个精简版的 OpenCV 库,通过调整编译参数,删减部分 OpenCV 源码,来最小化编译 OpenCV。
opencv-mobile 提供了 OpenCV 常用的功能,如读写图片,处理,矩阵操作等等,版本与上游同步,无第三方依赖。在绝大多数情况下,以 1/10 的体积无痛替换官方 OpenCV,尤其适合对体积有特殊要求的移动端和嵌入式环境。
源码包体积对比:
OpenCV 4.9.0 | The Official OpenCV | opencv-mobile |
---|---|---|
source zip | 93 MB | 10.7 MB |
android | 242 MB | 18.1 MB |
ios | 202 MB | 10.0 MB |
ios+bitcode | missing :( | 34.5 MB |
项目链接: https://github.com/nihui/opencv-mobile | 感谢 nihui
老师 !
opencv-mobile 已经在 Milk-V Duo/Duo256M/DuoS 上支持硬件加速 JPG 解码,以及 VPSS (Video Processing Subsystem) 硬件加速。
一、快速开始
我们可以直接下载其 release 的预编译包,来测试基础功能或者进行应用开发。
项目源码中提供了一个测试示例,演示如何使用 opencv-mobile 实现加载图片,缩放,并保存图片。
下面以该测试程序为例,介绍一下 opencv-mobile 在 Linux 环境下的编译方法以及如何在 Milk-V Duo 上运行。
下载适配 Milk-V Duo 的预编译包
opencv-mobile 的 release 链接: https://github.com/nihui/opencv-mobile/releases
下载当前最新的 Milk-V Duo 的预编译包:opencv-mobile-4.9.0-milkv-duo.zip
新建测试程序目录
新建目录 picture-resize
并进入该目录:
mkdir picture-resize
cd picture-resize
将前面下载的预编译包解压到当前目录:
unzip ../opencv-mobile-4.9.0-milkv-duo.zip
创建代码文件
新建一个名为 main.cpp
的文件:
vi main.cpp
添加如下内容:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
int main()
{
cv::Mat bgr = cv::imread("in.jpg", 1);
cv::resize(bgr, bgr, cv::Size(200, 200));
cv::imwrite("out.jpg", bgr);
return 0;
}
其功能就是将一张名为 in.jpg
的图片,缩放为 200x200
的大小后,输出为 out.jpg
文件。
创建 CMakeLists.txt
使用 cmake 方式来编译,需要创建 CMakeLists.txt 文件:
vi CMakeLists.txt
内容如下:
project(opencv-mobile-test)
cmake_minimum_required(VERSION 3.5)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_COMPILER "${CMAKE_CURRENT_SOURCE_DIR}/host-tools/gcc/riscv64-linux-musl-x86_64/bin/riscv64-unknown-linux-musl-gcc")
set(CMAKE_CXX_COMPILER "${CMAKE_CURRENT_SOURCE_DIR}/host-tools/gcc/riscv64-linux-musl-x86_64/bin/riscv64-unknown-linux-musl-g++")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -mcpu=c906fdv -march=rv64imafdcv0p7xthead -mcmodel=medany -mabi=lp64d")
set(OpenCV_DIR "${CMAKE_CURRENT_SOURCE_DIR}/opencv-mobile-4.9.0-milkv-duo/lib/cmake/opencv4")
find_package(OpenCV REQUIRED)
add_executable(opencv-mobile-test main.cpp)
target_link_libraries(opencv-mobile-test ${OpenCV_LIBS})
其中有三个变量需要注意一下,根据自己的文件路径来配置:
- OpenCV_DIR:前面解压到当前目录的预编译包对应的目录,注意路径中的版本号
- CMAKE_C_COMPILER:交叉编译工具链中 gcc 的路径
- CMAKE_CXX_COMPILER:交叉编译工具链中 g++ 的路径
交叉编译工具链的下载链接:host-tools.tar.gz。可以通过 wget 命令下载后解压:
wget https://sophon-file.sophon.cn/sophon-prod-s3/drive/23/03/07/16/host-tools.tar.gz
tar -xf host-tools.tar.gz
如果你曾经编译过 duo-buildroot-sdk,其根目录下的 host-tools
目录就是交叉工具链的目录,没必要重新下载,可以直接修改 OpenCV_DIR
指定到该目录即可。或者创建个软链接指向该目录。
编译
cmake 方式编译会创建一些中间目录和文件,所以我们新建一个 build 目录并进入该目录来完成编译:
mkdir build
cd build
cmake ..
make
编译正常输出如下:
$ make
[ 50%] Building CXX object CMakeFiles/opencv-mobile-test.dir/main.cpp.o
[100%] Linking CXX executable opencv-mobile-test
[100%] Built target opencv-mobile-test
当前 build
目录下生成的 opencv-mobile-test
就是测试程序:
$ ls
CMakeCache.txt CMakeFiles cmake_install.cmake Makefile opencv-mobile-test
此时目录的结构如下:
picture-resize/ # 测试程序根目录
├── build # 编译输出目录
├── CMakeLists.txt # CMake 配置文件
├── host-tools # Duo 交叉编译工具链目录
├── main.cpp # 测试程序源代码文件
└── opencv-mobile-4.9.0-milkv-duo/ # opencv-mobile 预编译库目录
把生成的 opencv-mobile-test
程序通过 scp
命令传送到 Duo 中:
scp opencv-mobile-test [email protected]:/root/
再将一张测试用大小为 1024x1024
的 jpg
图片也同样传送到 Duo 中:
scp in.jpg [email protected]:/root/
in.jpg
:
在 Duo 中运行测试程序
Duo 的固件请暂时使用 V1.0.8 的版本
通过串口或者 ssh 登陆到 Duo 的终端,进入 /root/ 目录:
cd /root/
为 opencv-mobile-test 添加可执行权限:
chmod +x opencv-mobile-test
运行测试程序:
./opencv-mobile-test
如果遇到 OOM
错误,可能是图片分辨率太大,内存使用超出了 Duo 的可用内存,换个尺寸小一些的图片就正常了。
Out of memory: Killed process 3718 (opencv-mobile-t) total-vm:31168kB, anon-rss:11384kB, file-rss:4kB, shmem-rss:0kB, UID:0
通过 ls
命令查看是否在当前目录下生成了 out.jpg
文件:
[root@milkv-duo]~# ls
in.jpg opencv-mobile-test out.jpg
在电脑上用 scp
命令将 out.jpg
文件取回本地查看大小是否为 200x200:
scp [email protected]:/root/out.jpg .
二、硬件加速 JPG 解码测试
opencv-mobile 已经支持 Milk-V Duo 中的硬件加速 JPG 解码
- opencv-mobile highgui 模块在运行时动态加载 cvi 库,JPG 硬件解码
- 无需修改代码,cv::imread() 与 cv::imdecode() 自动支持
- 支持 EXIF 自动旋转,支持直接解码为 grayscale
- 加速了 5~11 倍!
测试示例
验证 JPG 硬件加速实际效果的方法,可以同样使用前面的缩放 jpg 文件为 200x200 的示例程序,分别使用不带 JPG 硬件加速的 opencv-mobile 预编译包和带 JPG 硬件加速的预编译包来生成测试程序,通过其在 Duo 上运行的时间来做对比。
不带 JPG 硬件加速的预编译包 :opencv-mobile-4.8.0-milkv-duo.zip
带 JPG 硬件加速的预编译包:opencv-mobile-4.9.0-milkv-duo.zip
使用两个预编译包,分别编译出 opencv-mobile-test
转送到 Duo 中运行,我这里是在 Duo-256M 中测试的,in.jpg
使用的是一张分辨率为 3000x3000 大小为 3.2M 的 jpg 图片。
[root@milkv-duo]~# time ./opencv-mobile-test-4.8.0
real 0m 2.56s
user 0m 2.31s
sys 0m 0.24s
[root@milkv-duo]~# time ./opencv-mobile-test-4.9.0
this device is not whitelisted for jpeg encoder rkmpp
real 0m 0.37s
user 0m 0.13s
sys 0m 0.14s
可以看到,不带 JPG 硬件加速时运行时间为 2.56s
,带 JPG 硬件加速时运行时间只有 0.37s
,速度提高了约 6.92
倍。