TL;DR
Compile the pre-packaged zip file and get started!
- Open the website GitHub - nihui/opencv-mobile: The minimal opencv for Android, iOS, ARM Linux, Windows, Linux, MacOS, WebAssembly.
- Download opencv-mobile-4.8.0-milkv-duo.zip and unzip it.
- Use CMake with
-DOpenCV_DIR=<unzip_directory>/lib/cmake/opencv4
,find_package(OpenCV)
, andtarget_link_libraries(your-program ${OpenCV_LIBS})
.
opencv-mobile
opencv-mobile minimizes the compiled OpenCV library by adjusting compilation parameters and removing some OpenCV source code.
- It offers common OpenCV functionalities, such as reading and writing images, image processing, and matrix operations.
- It stays synchronized with the upstream OpenCV version and has no third-party dependencies.
In most cases, it can replace the official OpenCV with a size reduction of approximately 90%, making it particularly suitable for mobile and embedded environments with special size requirements.
Compared to the modified version of OpenCV in the FlatGeek community, opencv-mobile can directly benefit from upstream RVV optimization, providing a more authentic, lightweight, and convenient experience.
Compiling opencv-mobile for milkv-duo
milkv-duo’s small board has very limited hardware resources.
- Prepare a cross-compilation toolchain, for example, unzip it to
/home/nihui/osd/host-tools
, which needs to be set as an environment variable later.
https://github.com/milkv-duo/duo-buildroot-sdk/tree/develop
- Download the latest OpenCV source code.
https://github.com/opencv/opencv/releases
- Download the compilation configuration and patches for opencv-mobile.
https://github.com/nihui/opencv-mobile
Follow the compilation steps of opencv-mobile, set the toolchain directory as an environment variable, modify the highgui module, apply patches, and use riscv64-unknown-linux-musl.toolchain.cmake
.
export RISCV_ROOT_PATH=/home/nihui/osd/host-tools/gcc/riscv64-linux-musl-x86_64
git clone https://github.com/nihui/opencv-mobile.git
cd opencv-mobile
wget -q https://github.com/opencv/opencv/archive/4.8.0.zip
unzip -q opencv-4.8.0.zip
cd opencv-4.8.0
truncate -s 0 cmake/OpenCVFindLibsGrfmt.cmake
rm -rf modules/gapi
patch -p1 -i ../opencv-4.8.0-no-rtti.patch
patch -p1 -i ../opencv-4.8.0-no-zlib.patch
patch -p1 -i ../opencv-4.8.0-link-openmp.patch
rm -rf modules/highgui
cp -r ../highgui modules/
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../../toolchains/riscv64-unknown-linux-musl.toolchain.cmake -DCMAKE_C_FLAGS="-fno-rtti -fno-exceptions" -DCMAKE_CXX_FLAGS="-fno-rtti -fno-exceptions" -DCMAKE_INSTALL_PREFIX=install -DCMAKE_BUILD_TYPE=Release `cat ../../opencv4_cmake_options.txt` -DBUILD_opencv_world=OFF -DOPENCV_DISABLE_FILESYSTEM_SUPPORT=ON ..
make -j4
make install
After this compilation, opencv-mobile is ready in the opencv-mobile/build/install directory.
It’s worth noting that during the compilation, CMake successfully checks and enables RVV (RISC-V Vector Extension) support, which provides acceleration for the milkv-duo chip.
-- Performing Test HAVE_CPU_RVV_SUPPORT (check file: cmake/checks/cpu_rvv.cpp)
-- Performing Test HAVE_CPU_RVV_SUPPORT - Success
The toolchains/riscv64-unknown-linux-musl.toolchain.cmake
that comes with opencv-mobile globally enables compilation parameters related to the c906 kernel and optimizes it for c906. These parameters will be automatically applied to the compilation of all opencv-mobile modules, providing the best performance.
-- General configuration for OpenCV 4.8.0 =====================================
-- Version control: v18-dirty
--
-- Platform:
-- Timestamp: 2023-08-30T09:37:40Z
-- Host: Linux 6.4.12-200.fc38.x86_64 x86_64
-- Target: Linux riscv64
-- CMake: 3.27.3
-- CMake generator: Unix Makefiles
-- CMake build tool: /usr/bin/gmake
-- Configuration: Release
--
-- CPU/HW features:
-- Baseline: RVV
-- requested: DETECT
--
-- C/C++:
-- Built as dynamic libs?: NO
-- C++ standard: 11
-- C++ Compiler: /home/nihui/osd/host-tools/gcc/riscv64-linux-musl-x86_64/bin/riscv64-unknown-linux-musl-g++ (ver 10.2.0)
-- C++ flags (Release): -march=rv64gcv0p7_zfh_xtheadc -mabi=lp64d -mtune=c906 -fsigned-char -W -Wall -Wreturn-type -Wnon-virtual-dtor -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -fvisibility=hidden -fvisibility-inlines-hidden -fopenmp -O3 -DNDEBUG -DNDEBUG
-- C++ flags (Debug): -march=rv64gcv0p7_zfh_xtheadc -mabi=lp64d -mtune=c906 -fsigned-char -W -Wall -Wreturn-type -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -fvisibility=hidden -fvisibility-inlines-hidden -fopenmp -g -O0 -DDEBUG -D_DEBUG
-- C Compiler: /home/nihui/osd/host-tools/gcc/riscv64-linux-musl-x86_64/bin/riscv64-unknown-linux-musl-gcc
-- C flags (Release): -march=rv64gcv0p7_zfh_xtheadc -mabi=lp64d -mtune=c906 -fsigned-char -W -Wall -Wreturn-type -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -fvisibility=hidden -fopenmp -O3 -DNDEBUG -DNDEBUG
-- C flags (Debug): -march=rv64gcv0p7_zfh_xtheadc -mabi=lp64d -mtune=c906 -fsigned-char -W -Wall -Wreturn-type -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -fvisibility=hidden -fopenmp -g -O0 -DDEBUG -D_DEBUG
-- Linker flags (Release): -Wl,--gc-sections -Wl,--as-needed -Wl,--no-undefined
-- Linker flags (Debug): -Wl,--gc-sections -Wl,--as-needed -Wl,--no-undefined
-- ccache: NO
-- Precompiled headers: NO
-- Filesystem support is disabled
-- Extra dependencies: /home/nihui/osd/host-tools/gcc/riscv64-linux-musl-x86_64/riscv64-unknown-linux-musl/lib64v0p7_xthead/lp64d/libgomp.so /home/nihui/osd/host-tools/gcc/riscv64-linux-musl-x86_64/sysroot/usr/lib64v0p7_xthead/lp64d/libpthread.a /home/nihui/osd/host-tools/gcc/riscv64-linux-musl-x86_64/riscv64-unknown-linux-musl/lib64v0p7_xthead/lp64d/libatomic.so dl m pthread rt
-- 3rdparty dependencies:
--
-- OpenCV modules:
-- To be built: core features2d highgui imgproc photo video
-- Disabled: calib3d dnn flann imgcodecs ml objdetect stitching videoio world
-- Disabled by dependency: -
-- Unavailable: java python2 python3 ts
-- Applications: -
-- Documentation: NO
-- Non-free algorithms: NO
--
-- GUI:
--
-- Media I/O:
-- ZLib: build (ver )
--
-- Video I/O:
-- DC1394: NO
--
-- Parallel framework: OpenMP
--
-- Other third-party libraries:
-- Lapack: NO
-- Custom HAL: NO
--
-- Python (for build): /usr/bin/python2.7
--
-- Install to: /home/nihui/dev/opencv-mobile/opencv-4.8.0/build/install
-- -----------------------------------------------------------------
Using opencv-mobile milkv-duo optimized version for image scaling
opencv-mobile comes with a sample project that demonstrates how to use opencv-mobile to load images, scale them, and save the images.
Key code:
#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;
}
CMake project key code:
project(opencv-mobile-test)
cmake_minimum_required(VERSION 3.5)
# opencv4 requires c++11
set(CMAKE_CXX_STANDARD 11)
# set OpenCV_DIR to where OpenCVConfig.cmake resides
find_package(OpenCV REQUIRED)
add_executable(opencv-mobile-test main.cpp)
target_link_libraries(opencv-mobile-test ${OpenCV_LIBS})
Compilation process:
export RISCV_ROOT_PATH=/home/nihui/osd/host-tools/gcc/riscv64-linux-musl-x86_64
cd opencv-mobile/test
mkdir build
cd
build
cmake -DCMAKE_TOOLCHAIN_FILE=../../toolchains/riscv64-unknown-linux-musl.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DOpenCV_DIR=/home/nihui/dev/opencv-mobile/opencv-4.8.0/build/install/lib/cmake/opencv4 ..
make
(Optional) The compiled binary can be further reduced in size using the strip
utility from the cross-compilation toolchain:
/home/nihui/osd/host-tools/gcc/riscv64-linux-musl-x86_64/bin/riscv64-unknown-linux-musl-strip opencv-mobile-test
Once the latest milkv-duo image is installed and the device is connected via USB, make sure you can SSH into it:
https://github.com/milkv-duo/duo-buildroot-sdk/releases
Copy opencv-mobile-test and a test image in.jpg to root@192.168.42.1:/root/
.
If you encounter the “libgomp.so.1” not found error, copy it from the toolchain to the device:
[root@milkv]~# LD_LIBRARY_PATH=. ./opencv-mobile-test
If you encounter a “Killed” error, it means the image resolution is too large and exceeds the memory limits of milkv-duo. Use a smaller image to resolve the issue.
Finally, if you find this information useful, please star and share it: