一篓足、下載opencv源碼包
官網(wǎng)下載Android版帽馋,最新版本為V4.3.0
二蕉汪、CMAKE構(gòu)建項(xiàng)目
-
前提:環(huán)境已安裝好CMAKE和LLDB煌集,可在SdkManager查看
-
解壓源碼包,得到文件夾OpenCV-android-sdk
1辛藻、Android studio新建Module碘橘,命名為opencvlib
2、將“OpenCV-android-sdk\sdk\native\libs”下的文件復(fù)制到opencvlib/libs
3吱肌、opencvlib/src/main下新建文件夾cpp,cpp下新建C++文件痘拆,例如native-lib.cpp。
將“OpenCV-android-sdk\sdk\native\jni”下的整個(gè)include文件夾復(fù)制到cpp文件夾下氮墨,因?yàn)镃MakeLists需要引用到該路徑纺蛆,頭文件最好存放在項(xiàng)目中
4、opencvlib目錄下新建文件CMakeLists.txt
5规揪、配置當(dāng)前Module下的buidl.gradle
- 節(jié)點(diǎn)android下添加
externalNativeBuild {
cmake {
path"CMakeLists.txt"
}
}
- 節(jié)點(diǎn)android.defaultConfig下添加
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions"
abiFilters 'x86' ,'armeabi-v7a','x86_64','arm64-v8a' //CPU架構(gòu)
arguments "-DANDROID_STL=c++_shared" //解決"libc++_shared.so" not found
}
}
6桥氏、配置CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
#支持-std=gnu++11
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
#配置加載native依賴
#以下路徑就是上述第3步提到的頭文件路徑
include_directories(${PROJECT_SOURCE_DIR}/src/main/cpp/include)
#動(dòng)態(tài)方式加載
add_library(lib_opencv STATIC IMPORTED ) #表示創(chuàng)建一個(gè)導(dǎo)入庫,靜態(tài)方式
#引入libopencv_java4.so文件
set_target_properties(lib_opencv
PROPERTIES
IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libopencv_java4.so
)
#自己的源文件
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp )
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} android -ljnigraphics lib_opencv)
需要修改的地方
- include_directories 路徑變量 根據(jù)實(shí)際頭文件路徑進(jìn)行編譯
- set_target_properties的libopencv_java4.so實(shí)際路徑
- add_library中的native-lib.cpp實(shí)際路徑
7猛铅、新建JNI工具類OpenCVUtil.java字支,聲明native方法
private static native int[]grey(int[] pixels, int width, int height);
8、在native-lib.cpp編寫C++代碼
例如
#include <jni.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
extern "C"
JNIEXPORT jintArray JNICALL
Java_czb_com_opencvlib_OpenCVUtil_grey(JNIEnv *env, jobject instance, jintArray buf, jint w, jint h) {
jint *cbuf = env->GetIntArrayElements(buf, JNI_FALSE );
if (cbuf == NULL) {
return 0;
}
Mat imgData(h, w, CV_8UC4, (unsigned char *) cbuf);
uchar* ptr = imgData.ptr(0);
for(int i =0; i < w*h; i ++){
//計(jì)算公式:Y(亮度) = 0.299*R + 0.587*G + 0.114*B
//對(duì)于一個(gè)int四字節(jié)奸忽,其彩色值存儲(chǔ)方式為:BGRA
int grayScale = (int)(ptr[4*i+2]*0.299 + ptr[4*i+1]*0.587 + ptr[4*i+0]*0.114);
ptr[4*i+1] = grayScale;
ptr[4*i+2] = grayScale;
ptr[4*i+0] = grayScale;
}
int size = w * h;
jintArray result = env->NewIntArray(size);
env->SetIntArrayRegion(result, 0, size, cbuf);
env->ReleaseIntArrayElements(buf, cbuf, 0);
return result;
}
其中函數(shù)名 Java_czb_com_opencvlib_OpenCVUtil_grey堕伪,表示OpenCVUtil的包名為
czb.com.opencvlib,類下有g(shù)rey方法栗菜,需根據(jù)實(shí)際進(jìn)行改動(dòng)
9欠雌、點(diǎn)擊運(yùn)行
opencvlib的文件目錄為
運(yùn)行成功的話,可在該路徑下查看所編譯的so庫
app\build\intermediates\cmake\debug\obj
三疙筹、編寫demo
1桨昙、工具類實(shí)現(xiàn)
public class OpenCVUtil {
static {
System.loadLibrary("native-lib");
}
private static native int[]grey(int[] pixels_, int width, int height);
public static Bitmap bmpGrey(Bitmap bm) {
int width = bm.getWidth();
int height = bm.getHeight();
int[] ps =new int[width * height];
bm.getPixels(ps, 0, width, 0, 0, width, height);
long time = System.currentTimeMillis();
int[] newPs =grey(ps, width, height);
Log.e("CZB","C++ 執(zhí)行:" + (System.currentTimeMillis() - time));
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(newPs, 0, width, 0, 0, width, height);
return bitmap;
}
}
2、在app中引用該Module
- app.gradle的節(jié)點(diǎn)dependencies添加
implementation project(':opencvlib')
3腌歉、調(diào)用工具類
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);
Bitmap bm=OpenCVUtil.bmpGrey(srcBitmap);//關(guān)于圖形處理步驟建議在子線程運(yùn)行
imageView.setImageBitmap(bm);
最后 問題匯總(持續(xù)更新)
- 錯(cuò)誤信息:java.lang.UnsatisfiedLinkError: dlopen failed: library "libopencv_java4.so" not found
解決辦法: 手動(dòng)加載libopencv_java4.so 蛙酪。由于本人是放在opencvlib模塊下,所以在
opencvlib/build.gradle的android節(jié)點(diǎn)添加
sourceSets.main {
jniLibs.srcDir 'libs'
jni.srcDirs = []
}
JAVA代碼JNI類添加
static {
System.loadLibrary("native-lib");
System.loadLibrary("opencv_java4");
}