linux 上交叉编译android NDK调用opencv实现图像处理

背景

我们需要编一个可执行文件,实现图像在手机中的处理,最好做到直接通过调用adb 指令运行。
我的电脑的环境:
ubuntu 18
cmake 3.10

我选用的都是最新的版本的opencv 和最新的android sdk,
opencv:4.9.0
android sdk:android-ndk-r26d

STEP1 : 环境搭建

  1. 配置cmake
    • 由于opencv现在已经迭代到4.9了,其编译对cmake的版本也有要求,要求cmake必须要在3.19版本以上,我的本地版本是3.10的,于是需要更新到最新的,直接去 cmake 官网下载最最新的,编译安装:
cd cmake-3.30.0
mkdir build
cd build
cmake ..
make -j8
  1. 下载androd NDK
    • https://developer.android.google.cn/ndk/downloads?hl=zh-cn
  2. 下载opencv SDK
    • https://opencv.org/releases/
    • 直接下载android 版本的,解压到本地固定位置。在这里插入图片描述

STEP2:opencv配置

opencv由于直接下载的是SDK ,所以不需要过多的处理,cmake可以直接调用,我们只需要知道几个重点东西就可以了

  1. 库函数:
    包含了3大块,三方库,静态库,和其他的东西,这里静态库是个重点
    opencv库图片在这里插入图片描述
    静态库里core 和imgproc是最基础的,其他都是一些特殊功能。

  2. 头文件:

    • opencv-4.9.0-android-sdk/OpenCV-android-sdk/sdk/native/jni/include
    • 这个是主要的头文件路径
  3. cmake file

    • opencv-4.9.0-android-sdk/OpenCV-android-sdk/sdk/native/jni/abi-arm64-v8a
    • 这个路径是一会儿要自动配置三方库搜索的路径,也比较重要

STEP3:Cmake 配置

  1. CMakeLists.txt 的编写背景知识:
    参考一下我之前写的编写方法

https://editor.csdn.net/md/?articleId=140210286

  1. CMakeLists.txt 的编写
#****************************This is Project Info****************************
cmake_minimum_required(VERSION 3.4)

# 设置项目名称和版本  
project(app1 VERSION 1.0)

set(ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
set(OUT_PATH ${CMAKE_BINARY_DIR})

set(NDK_PATH /home/dzk/disk/android_ndk/android-ndk-r26d)


MESSAGE(STATUS "This is ROOT_PATH dir " ${ROOT_PATH})
MESSAGE(STATUS "This is OUT_PATH dir " ${OUT_PATH})
MESSAGE(STATUS "This is NDK_PATH dir " ${NDK_PATH})
MESSAGE(STATUS "This is OPENCV_PATH dir " ${OPENCV_PATH})
add_definitions("-Wall -g")

#设置交叉编译环境和工具
set(CMAKE_SYSTEM_NAME Android)            #要构建的目标平台,比如要构建成android平台的
set(CMAKE_SYSTEM_PROCESSOR arm)           #是要构建的目标体系结构,这个平台是什么架构,一般是arm
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)   #编译的二进制接口(armeabi-v7a、arm64-v8a、x86、x86_64)
set(CMAKE_ANDROID_NDK /home/dzk/disk/android_ndk/android-ndk-r26d)   #andorid ndk的位置,可以从https://developer.android.google.cn/ndk/downloads?hl=zh-cn 下载最新的

#选用编译器,我选用的是clang++ 的编译器,当然也可以选择g++的,只不过android NDK 后面好像不支持g++了
#这里有个重点,即尽量选用NDK 里面的clang++, 如果不使用NDK 的clang,就会出现生成的可执行文件64位和32位不匹配的问题
set(triple arm-linux-gnueabihf)
set(CMAKE_ANDROID_TOOLCHAIN /home/dzk/disk/android_ndk/android-ndk-r26d/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android33-clang++)
set(CMAKE_CXX_COMPILER /home/dzk/disk/android_ndk/android-ndk-r26d/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android33-clang++)
set(CMAKE_CXX_COMPILER_TARGET ${triple})
set(CMAKE_C_COMPILER /home/dzk/disk/android_ndk/android-ndk-r26d/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android33-clang)


set(CMAKE_SYSTEM_VERSION 21) # API level 21, 这里和上面的版本是一致的,也可以不一样
set(CMAKE_ANDROID_PLATFORM android-21)
set(CMAKE_BUILD_TYPE Release)

set(CMAKE_ANDROID_STL c++_shared)
#set(CMAKE_ANDROID_STL_TYPE gnustl_static) #制定的c++ stl 库类型,可以设置

#大概意思可能是选用NDK 里面的cmake,我试过不加好像也可以
set(CMAKE_TOOLCHAIN_FILE /home/dzk/disk/android_ndk/android-ndk-r26d/build/cmake/android.toolchain.cmake)

########################opencv start###############################
set(OPENCV_PATH ${ROOT_PATH}/lib/opencv-4.9.0)
#set(OpenCVSDK  /home/dzk/disk/android_ndk/opencv-install/sdk/native)
set(OpenCVSDK /home/dzk/disk/android_ndk/opencv-4.9.0-android-sdk/OpenCV-android-sdk/sdk/native)

set(CMAKE_PREFIX_PATH "/home/dzk/disk/android_ndk/opencv-4.9.0-android-sdk/OpenCV-android-sdk/sdk/native/jni/abi-arm64-v8a")
find_package(OpenCV REQUIRED)

include_directories(${OpenCVSDK}/jni/include)
link_directories(${OpenCVSDK}/staticlibs/arm64-v8a
                 ${OpenCVSDK}/3rdparty/libs/arm64-v8a
                 ${OpenCVSDK}/libs/arm64-v8a)


#我只用到了简单函数,就没有包含太多的库文件
link_libraries(
		log
		opencv_imgproc
		opencv_imgcodecs
		opencv_core
    )


########################opencv end###############################
add_executable(myapp 
			main.cpp
			)

target_link_libraries(myapp ${link_libraries})


  1. 重点
这里有几个重点,当时困惑了许久
重点1:应用引用opencv库的方法

set(CMAKE_PREFIX_PATH "/home/dzk/disk/android_ndk/opencv-4.9.0-android-sdk/OpenCV-android-sdk/sdk/native/jni/abi-arm64-v8a")
find_package(OpenCV REQUIRED)

这两个指令非常关键,上面一个是设置了opencv SDK 库的路径,下边一个是cmake会自动找这个路径下边的需要的opencv包。否则无法直接调用opencv sdk。

STEP4 : 实现效果

代码:实现一个图片转灰度图的功能:

#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main()
{
	printf("hello dzk");

    //read picture
    Mat img = cv::imread("/sdcard/0_0_2_4096x3072.jpeg");
    Mat gray_image;
    cvtColor(img, gray_image, COLOR_BGR2GRAY);  
    imwrite("/sdcard/gray.jpg", gray_image);
	printf("end");

	return 0;
}

先cmake … 再make 就可以编译出可执行文件,推到手机vendor/bin 目录下,通过

adb shell myapp

调用即可
在这里插入图片描述

处理后的两张图:
在这里插入图片描述

遇到的问题

  1. 找不到print 函数:
    在这里插入图片描述
    需要在cmake txt里面加入log库:
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值