Ubuntu 编译 OpenCV SDK for Android + Linux

概述

      OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,它提供了很多函数,这些函数非常高效地实现了计算机视觉算法(最基本的滤波到高级的物体检测皆有涵盖)。
  OpenCV 的应用领域非常广泛,包括图像拼接、图像降噪、产品质检、人机交互、人脸识别、动作识别、动作跟踪、无人驾驶等。OpenCV 还提供了机器学习模块,你可以使用正态贝叶斯、K最近邻、支持向量机、决策树、随机森林、人工神经网络等机器学习算法。
Ubuntu 编译 OpenCV SDK for Android + Linux_第1张图片

OpenCV的应用非常广泛,在AI-新手玩转RKNN一文中虽然并未提及,当在demo、examples中,可以看到很多OpenCV的影子。
比如:

import cv2
img = cv2.imread(IMG_PATH)
#include "opencv2/core/core.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"

cv::Mat orig_img = cv::imread(image_name, 1);
cv::cvtColor(orig_img, img, cv::COLOR_BGR2RGB);

准备

名称 版本 备注
系统 Ubuntu 20.04
CMAKE 3.16.3
NDK版本 17.2.4988734 Android 系统的C/C++开发SDK
GCC 9.4.0 Linux 系统的SDK
OpenCV 4.7.0

下载OpenCV源码: 4.x.zip, 解压到指定目录
Ubuntu 编译 OpenCV SDK for Android + Linux_第2张图片

编译

  1. 创建build并使用cmake 构建目标平台的编译文件
  2. 真正编译make
  3. 安装

将过程简化并写入到脚本方便后续使用:

opencv-4.x/build/build-android.sh

# 一些变量
myDir=$(cd `dirname $0`; pwd)
# Android SDK 路径, 包含了各个版本的SDK 和 NDK
ANDROID_SDK_ROOT=/home/anson/Android/Sdk/
# DNK 路径
ANDROID_NDK_PATH=/home/anson/Android/Sdk/ndk/17.2.4988734/
BUILD_TYPE=Release
TARGET_SOC="rk356x"

# Android的编译会存到: build-rk356x
BUILD_DIR=${myDir}/build-${TARGET_SOC}

if [[ ! -d "${BUILD_DIR}" ]]; then
  mkdir -p ${BUILD_DIR}
fi

# 进入build-rk356x 并执行cmake构建
cd ${BUILD_DIR}
cmake ../.. \
        -DANDROID_TOOLCHAIN=clang \
        -DRKNN_DIR=${RKNN_DIR} \
        -DTARGET_SOC=${TARGET_SOC} \
       	-DCMAKE_SYSTEM_NAME=Android \
        -DANDROID_SDK_ROOT=$ANDROID_SDK_ROOT \
        -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_PATH/build/cmake/android.toolchain.cmake \
        -DANDROID_ABI="arm64-v8a" \
        -DANDROID_STL=c++_static \
        -DANDROID_PLATFORM=android-24 \
        -DBUILD_JAVA=OFF \
        -DWITH_V4L=1 \
        -DHAVE_CAMV4L2=ON \
        -DBUILD_ANDROID_EXAMPLES=OFF \
        -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
# 编译
make -j4
# 输出
make install

PS: 根据需要定制不同的cmake参数
比如需要是用v4l2打开摄像头需要打开: -DWITH_V4L=1 -DHAVE_CAMV4L2=ON


build-linux.sh Linux 的编译脚本相对简单
配置好GCC相关的环境即可

myDir=$(cd `dirname $0`; pwd)

GCC_COMPILER=aarch64-linux-gnu
export CC=${GCC_COMPILER}-gcc
export CXX=${GCC_COMPILER}-g++
BUILD_TYPE=Release
TARGET_SOC="linux"

BUILD_DIR=${myDir}/build-${TARGET_SOC}

if [[ ! -d "${BUILD_DIR}" ]]; then
  mkdir -p ${BUILD_DIR}
fi

cd ${BUILD_DIR}
cmake ../.. \
        -DCMAKE_SYSTEM_NAME=Linux \
        -DCMAKE_SYSTEM_PROCESSOR=aarch64 \
        -DCMAKE_C_COMPILER=$CC \
        -DCMAKE_CXX_COMPILER=$CXX \
        -DCMAKE_FIND_ROOT_PATH=/usr/aarch64-linux-gnu/bin \
        -DBUILD_opencv_python2=OFF \
        -DBUILD_opencv_python3=OFF \
        -DENABLE_NEON=ON \
        -DWITH_V4L=1 \
        -DHAVE_CAMV4L2=ON \
        -DCMAKE_INSTALL_PREFIX=${BUILD_DIR}/install \
        -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
make -j4
make install

一些编译的问题
OpenCv4.x + opencv_contrib-4.x交叉编译

#/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: ../../3rdparty/lib/liblibpng.a(pngrtran.c.o): in function `png_do_read_transformations':
#pngrtran.c:(.text.png_do_read_transformations+0x1aec): undefined reference to `png_do_expand_palette_rgba8_neon'
#/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: pngrtran.c:(.text.png_do_read_transformations+0x1ca8): undefined reference to `png_riffle_palette_neon'
#/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: pngrtran.c:(.text.png_do_read_transformations+0x3660): undefined reference to `png_do_expand_palette_rgb8_neon'
#/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: ../../3rdparty/lib/liblibpng.a(pngrutil.c.o): in function `png_read_filter_row':
#pngrutil.c:(.text.png_read_filter_row+0xac): undefined reference to `png_init_filter_functions_neon'
#collect2: error: ld returned 1 exit status
#make[2]: *** [modules/imgcodecs/CMakeFiles/opencv_imgcodecs.dir/build.make:423: lib/libopencv_imgcodecs.so.4.7.0] Error 1

cmake增加参数: -DENABLE_NEON=ON

使用

OpenCV-Android SDK 输出的文件: build-rk356x/install/sdk

sdk
├── etc
│   ├── haarcascades
│   ├── lbpcascades
│   └── licenses
└── native
    ├── 3rdparty
    │   └── libs
    │       └── arm64-v8a
    ├── jni
    │   ├── abi-arm64-v8a
    │   └── include
    │       └── opencv2
    │           ├── calib3d
    │           ├── core
    │           │   ├── cuda
    │           │   │   └── detail
    │           │   ├── detail
    │           │   ├── hal
    │           │   ├── opencl
    │           │   │   └── runtime
    │           │   │       └── autogenerated
    │           │   ├── parallel
    │           │   │   └── backend
    │           │   └── utils
    │           ├── dnn
    │           │   └── utils
    │           ├── features2d
    │           │   └── hal
    │           ├── flann
    │           ├── gapi
    │           │   ├── cpu
    │           │   ├── fluid
    │           │   ├── gpu
    │           │   ├── infer
    │           │   ├── oak
    │           │   ├── ocl
    │           │   ├── own
    │           │   ├── plaidml
    │           │   ├── python
    │           │   ├── render
    │           │   ├── s11n
    │           │   ├── streaming
    │           │   │   ├── gstreamer
    │           │   │   └── onevpl
    │           │   └── util
    │           ├── highgui
    │           ├── imgcodecs
    │           │   └── legacy
    │           ├── imgproc
    │           │   ├── detail
    │           │   └── hal
    │           ├── ml
    │           ├── objdetect
    │           ├── photo
    │           │   └── legacy
    │           ├── stitching
    │           │   └── detail
    │           ├── video
    │           │   ├── detail
    │           │   └── legacy
    │           └── videoio
    │               └── legacy
    └── staticlibs
        └── arm64-v8a

所有的头文件和lib库已经有了, 只需要在CMakeLists.txt声明对应的变量即可导入使用:

#OPEN_CV_SDK=
# opencv
#Android NDK OpenCVConfig.cmake 所在路径
set(OpenCV_DIR ${OPEN_CV_SDK}/sdk/native/jni/abi-arm64-v8a)
# LINUX OpenCVConfig.cmake 所在路径
set(OpenCV_DIR ${OPEN_CV_SDK}/sdk/lib/cmake/opencv4)

find_package(OpenCV REQUIRED)

#......
# OpenCV_LIBS 在sdk/native/jni/abi-arm64-v8a/OpenCVConfig.cmake 中有定义
target_link_libraries(myapp
  ${OpenCV_LIBS}
)

OpenCV_DIR若没有赋值,则有可能找不到lib而报错:

   Add the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH or set
  "OpenCV_DIR" to a directory containing one of the above files.  If "OpenCV"
  provides a separate development package or SDK, be sure it has been
  installed.

参考

Linux上编译OpenCV的Android库
Android OpenCV基础(一、OpenCV入门)
OpenCV的Android使用指南
How to enable logging for OpenCV
我的Opencv4Android添加V4L2支持的移植记录(1)
OpenCV调用V4L相机记录
嵌入式开发板 aarch64 opencv库 交叉编译
Cross compilation for ARM based Linux systems

你可能感兴趣的:(android,Linux,linux,opencv,NDK,GCC)