Porting and Application of opencv-mobile (Mini Version of OpenCV Library) on milkv-duo

TL;DR

Compile the pre-packaged zip file and get started!

  1. Open the website GitHub - nihui/opencv-mobile: The minimal opencv for Android, iOS, ARM Linux, Windows, Linux, MacOS, WebAssembly.
  2. Download opencv-mobile-4.8.0-milkv-duo.zip and unzip it.
  3. Use CMake with -DOpenCV_DIR=<unzip_directory>/lib/cmake/opencv4, find_package(OpenCV), and target_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:

https://github.com/nihui/opencv-mobile