1. 什么是OpenCV
    OpenCV是一个开源的视觉库,它实现了图像处理和计算机视觉方面的很多通用算法。
    OpenCV主要用C++语言编写,但是依然保留了大量的C语言接口,但是 所有新的开发和算法都是用C++接口。

  2. 在Android平台如何使用OpenCV
    2.1. 使用Java OpenCV API
    这种方法是直接通过Java 语言编写算法的实现部分,相对应的特点在于:
    1.环境搭建简单:直接引入官方OpenCV-for-Android的对应jar包即可
    2.运行效率低:Java代码会在内部进行C++翻译,运行时性能损耗较大

2.2. 使用C++ OpenCV API
直接采用C++代码的特点在于:
1.环境搭建复杂:往往需要现自行编译对应的库,再进行NDK、Cmakelists配置
2.代码维护简单:由于直接采用C++实现算法部分,与其他平台的兼容性极好,能与Android程序员分离开发 => 算法升级时替换对应的算法库文件即可
3.运行效率高:不存在内部执行时的代码转换问题,性能最好

2.2.1. 直接使用官网提供的OpenCvSdk
使用步骤:

1、下载地址:https://opencv.org/releases.html

2、把AndroidOpenCvSdk的顶层目录设置到全局环境变量里:

vim ~/.bashrc

#add android opencv top dir
ANDROID_OPENCV_SDK_TOP_PATH=/home/public/opencv/OpenCV-android-sdk
export ANDROID_OPENCV_SDK_TOP_PATH=$ANDROID_OPENCV_SDK_TOP_PATH

3、在C++代码里,使用opencv的接口:

//包含头文件和使用opencv接口的命名空间;
#include <opencv2/opencv.hpp>
using namespace cv;

//接下来就可以调用opencv的相关接口了,例如:imread、threshold 等;

4、在NDK的Android.mk里 使用OpenCV的方法:

############## OpenCv_Sdk.mk start ##############
OpenCV_INSTALL_MODULES := on
OpenCV_CAMERA_MODULES := off

#连接opencv的动态库;
#OPENCV_LIB_TYPE := SHARED
#连接opencv的静态库;
OPENCV_LIB_TYPE := STATIC

#指定opencv的Makefile;
OPENCV_MK_PATH=$(ANDROID_OPENCV_SDK_TOP_PATH)/sdk/native/jni/OpenCV.mk

#加载opencv的Makefile;
include $(OPENCV_MK_PATH)
############## OpenCv_Sdk.mk end ##############

5、一个完整的NDK Android.mk 配置:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include OpenCv_Sdk.mk

LOCAL_SRC_FILES :=
DecodeNativeInterface.cpp

LOCAL_C_INCLUDES +=
$(LOCAL_PATH) /include

LOCAL_MODULE := libnexgo_decode_jni

include $(BUILD_SHARED_LIBRARY)

2.2.2. 把OpenCV源码,编译成OpenCvSdk

既然官网已经提供了opencv的sdk,为什么还要自己编译呢?
1、官网提供的这个SDK将绝大多数opencv的功能打到了一个so包里,所以so的体积较大,从而造成使用该so的apk也大,如果有些apk的发布,对于大小有限制,那么就需要做裁剪,把无用的功能删除;
2、裁剪/添加功能到opencv的so里;

对于开发android可用的so库,我可以通过ndk 编译得到。

Opencv的源码是由多个模块构成的,如下:

opencv-3.4.2/modules$ tree -L 1
├── calib3d
├── CMakeLists.txt
├── core
├── cudaarithm
├── cudabgsegm
├── cudacodec
├── cudafeatures2d
├── cudafilters
├── cudaimgproc
├── cudalegacy
├── cudaobjdetect
├── cudaoptflow
├── cudastereo
├── cudawarping
├── cudev
├── dnn
├── features2d
├── flann
├── highgui
├── imgcodecs
├── imgproc
├── java
├── js
├── ml
├── objdetect
├── photo
├── python
├── shape
├── stitching
├── superres
├── ts
├── video
├── videoio
├── videostab
├── viz
└── world

1、编译环境:
1.Linux系统:Ubuntu 14.04
2.NDK:android-ndk-r12b
3.SDK:android-sdk_r24.4.1-linux
4.OpenCV-SrcCode:opencv-3.4.2
5.cmake和ninja编译器

2、编译方法:
方法1:手动编译(最小模块):
1. 过cmake 命令,创建 Makefile:
mkdir build && cd build

build_android_version_cmd=“cmake
-DANDROID_ABI=armeabi
-DCMAKE_TOOLCHAIN_FILE=…/platforms/android/android.toolchain.cmake
-DANDROID_NDK=KaTeX parse error: Expected 'EOF', got '\ ' at position 12: {NDK_ROOT} \̲ ̲ -DANDROID_S…{SDK_ROOT}
-DBUILD_ANDROID_PROJECTS=OFF
…”

2.开始编译:
make -j28

3.开始安装:
make install
执行完之后,编译生成的库文件,在opencv-src-code/build/install/ 目录下;

方法2:自动编译:编译和和官网release一样的完整的opencv_for_android_sdk:
./platforms/android/build_sdk.py


–sdk_path=
–ndk_path=
–extra_modules_path=

  1. Android如何使用OpenCV处理后的数据
    在Android系统里,App 加载一张图片后,一般是以bitmap的数据结构来保存图片数据,而bitmap 是一个 BGRA 的 四通道数据,每一通道都是一个无符号的8位数据。
    如果OpenCV把一个图片处理为灰度图像之后,要通过Android系统显示,那么需要把这个单通道的灰度图像转换为4通道的BGRA,方法如下:

int * bitmap_buffer = (int *)malloc(pixes_cnt);
unsigned char * only_y = (unsigned char *)malloc(pixes_cnt);
……….

    unsigned char* ptr = (unsigned char*)bitmap_buffer;
    for(int i = 0; i < size; i ++){
        ptr[4*i+0] = only_y[i];
        ptr[4*i+1] = only_y[i];
        ptr[4*i+2] = only_y[i];
        ptr[4*i+3] = 0xff;
    } 

注意:
透明度的设置, 范围 0~255, 0:完全透明, 255:完全不透明;

  1. OpenCV里常用的API
    后续补充;

  2. 参考文档

https://blog.csdn.net/lantishua/article/details/21182965
https://bobo892589.github.io/2017/03/03/ios-android-opencv-build-usage/
https://ricky.moe/2017/07/03/opencv-contrib-for-android/

https://blog.csdn.net/CoolGirl__/article/details/80997264
https://blog.csdn.net/Dream_go888/article/details/80435199?utm_source=blogxgwz0

https://blog.csdn.net/sz76211822/article/details/82428295

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐