Android引入OpenCV的示例
簡(jiǎn)介
在移動(dòng)開發(fā)中,如果我們要實(shí)現(xiàn)一些圖像處理相關(guān)的功能,難免要用到OpenCV。而OpenCV是用c++開發(fā)的。我們?cè)贏ndroid中,需要使用jni的方法去使用它。
引入配置
我們引入jni開發(fā)的基本配置方法,已經(jīng)在另一篇博客中介紹過了,不再贅述。這一次我們無非是要引入第三方的c++庫。
首先,我們找到或新建jniLibs文件夾,然后將依賴的動(dòng)態(tài)庫和靜態(tài)庫(路徑為OpenCV-android-sdk\sdk\native\libs)拷貝到\src\main\jniLibs下面。
然后,找到cpp文件夾。將include文件夾(路徑OpenCV-android-sdk\sdk\native\jni\include)拷貝到cpp(路徑\app\src\main\cpp)文件夾里。
接著,我們需要引入c++的相關(guān)支持。在module的build.gradle里面加入:
externalNativeBuild { cmake { //arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static' cppFlags "-std=c++11","-frtti", "-fexceptions" } } ndk{ abiFilters 'armeabi-v7a' }
最后,我們需要在CMakeLists.txt中,加入opencv相關(guān)的聲明。由于配置比較復(fù)雜,在此直接將demo的CMakeLists.txt的內(nèi)容貼到這里。
# For more information about using CMake with Android Studio, read the # documentation: https://d.android.com/studio/projects/add-native-code.html # Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds them for you. # Gradle automatically packages shared libraries with your APK. set(CMAKE_VERBOSE_MAKEFILE on) set(libs "${CMAKE_SOURCE_DIR}/src/main/jniLibs") include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include) add_library(libopencv_java3 SHARED IMPORTED ) set_target_properties(libopencv_java3 PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_java3.so") add_library(libopencv_calib3d STATIC IMPORTED ) set_target_properties(libopencv_calib3d PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_calib3d.a") add_library(libopencv_core STATIC IMPORTED ) set_target_properties(libopencv_core PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_core.a") add_library(libopencv_features2d STATIC IMPORTED ) set_target_properties(libopencv_features2d PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_features2d.a") add_library(libopencv_flann STATIC IMPORTED ) set_target_properties(libopencv_flann PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_flann.a") add_library(libopencv_highgui STATIC IMPORTED ) set_target_properties(libopencv_highgui PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_highgui.a") add_library(libopencv_imgcodecs STATIC IMPORTED ) set_target_properties(libopencv_imgcodecs PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_imgcodecs.a") add_library(libopencv_imgproc STATIC IMPORTED ) set_target_properties(libopencv_imgproc PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_imgproc.a") add_library(libopencv_ml STATIC IMPORTED ) set_target_properties(libopencv_ml PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_ml.a") add_library(libopencv_objdetect STATIC IMPORTED ) set_target_properties(libopencv_objdetect PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_objdetect.a") add_library(libopencv_photo STATIC IMPORTED ) set_target_properties(libopencv_photo PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_photo.a") add_library(libopencv_shape STATIC IMPORTED ) set_target_properties(libopencv_shape PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_shape.a") add_library(libopencv_stitching STATIC IMPORTED ) set_target_properties(libopencv_stitching PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_stitching.a") add_library(libopencv_superres STATIC IMPORTED ) set_target_properties(libopencv_superres PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_superres.a") add_library(libopencv_video STATIC IMPORTED ) set_target_properties(libopencv_video PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_video.a") add_library(libopencv_videoio STATIC IMPORTED ) set_target_properties(libopencv_videoio PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_videoio.a") add_library(libopencv_videostab STATIC IMPORTED ) set_target_properties(libopencv_videostab PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_videostab.a") add_library(libopencv_ts STATIC IMPORTED ) set_target_properties(libopencv_ts PROPERTIES IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_ts.a") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -fexceptions -frtti") #include_directories(D:/Projects/Android/CLMAndroid/OpenCV-android-sdk/sdk/native/jni/include ) #set(OpenCV_DIR D:/Projects/Android/CLMAndroid/OpenCV-android-sdk/sdk/native/jni) #find_package(OpenCV REQUIRED) #target_link_libraries(${OpenCV_LIBS}) 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 android log libopencv_java3 libopencv_calib3d libopencv_core libopencv_features2d libopencv_flann libopencv_highgui libopencv_imgcodecs libopencv_imgproc libopencv_ml libopencv_objdetect libopencv_photo libopencv_shape libopencv_stitching libopencv_superres libopencv_video libopencv_videoio libopencv_videostab # Links the target library to the log library # included in the NDK. ${log-lib} )
這樣配置之后,我們就可以在cpp中,直接使用OpenCV庫了。在此貼一個(gè)簡(jiǎn)單的均值濾波:
#include <jni.h> #include <string> #include <opencv2/opencv.hpp> #include <bits/stdc++.h> #include <android/log.h> #include<opencv2/core/core.hpp> #include"opencv2/imgproc/imgproc.hpp" using namespace cv; using namespace std; #define MAKE_ARGB(a, r, g, b) ((a&0xff)<<24) | ((r&0xff)<<16) | ((g&0xff)<<8) | (b&0xff) #define MAKE_RGB565(r, g, b) ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3)) extern "C" { JNIEXPORT jintArray JNICALL Java_com_live_longsiyang_opencvdemo_OpenCVNativeManager_getBlurImage(JNIEnv *env, jobject thiz, jintArray pixels_, jint w, jint h) { int colorType = CV_8UC4; jint *pixels = env->GetIntArrayElements(pixels_, NULL); Mat imgMat(h, w, colorType, pixels); Mat out(h, w, colorType); blur(imgMat, out, Size(20, 20)); env->ReleaseIntArrayElements(pixels_, pixels, 0); int *outIntImage = new int[w * h]; for (int i = 0; i < w * h; i++) { int a, r, g, b; for (int j = 0; j < 4; j++) { a = out.data[i * 4 + 3]; r = out.data[i * 4 + 2]; g = out.data[i * 4 + 1]; b = out.data[i * 4 + 0]; outIntImage[i] = (int) out.data[i * 4 + j]; } outIntImage[i] = MAKE_ARGB(a,r,g,b); } jintArray result = env->NewIntArray(w * h); env->SetIntArrayRegion(result, 0, w * h, outIntImage); return result; } }
這樣我們就能看到一個(gè)基本的模糊效果的demo。
import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; public class MainActivity extends AppCompatActivity { static { System.loadLibrary("native-lib"); } ImageView mIvTest; Button mBtnTest; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mIvTest = (ImageView) findViewById(R.id.img_test); mIvTest.setImageResource(R.drawable.beauty_steward_course_video_thumb_icon); mBtnTest = (Button) findViewById(R.id.btn_test); mBtnTest.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.beauty_steward_course_video_thumb_icon); int w = srcBitmap.getWidth(); int h = srcBitmap.getHeight(); int[] pixels = new int[w*h]; srcBitmap.getPixels(pixels,0,w,0,0,w,h); int[] outPixels = OpenCVNativeManager.getBlurImage(pixels ,w,h); Bitmap destBitmap = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888); destBitmap.setPixels(outPixels,0,w,0,0,w,h); mIvTest.setImageBitmap(destBitmap); } }); findViewById(R.id.btn_reset).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mIvTest.setImageResource(R.drawable.beauty_steward_course_video_thumb_icon); } }); } }
導(dǎo)出.so
在build中找到這個(gè)so,這就是我們需要的文件。此外,由于我們使用了opencv相關(guān)的庫,我們還需要將opencv的相關(guān)文件復(fù)制出來。將其導(dǎo)入我們需要的工程。
導(dǎo)入之后,我們只需要在module的build.gradle里面加入:
android { ... sourceSets { main { jniLibs.srcDirs = ['src/main/jniLibs'] aidl.srcDirs = ['src/main/aidl'] } } }
之后,我們就可以直接調(diào)用
System.loadLibrary("native-lib");
值得注意的是,JNI的方法是與路徑名相關(guān)的,所以當(dāng)我們以這樣的方法調(diào)用native方法時(shí),我們需要路徑名匹配。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android使用lottie加載json動(dòng)畫的示例代碼
本篇文章主要介紹了Android使用lottie加載json動(dòng)畫的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01android 自定義圓角button效果的實(shí)例代碼(自定義view Demo)
這篇文章主要介紹了android 自定義圓角button(自定義View Demo),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12Android中SparseArray性能優(yōu)化的使用方法
這篇文章主要為大家詳細(xì)介紹了Android中SparseArray性能優(yōu)化的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-04-04Android中RecyclerView實(shí)現(xiàn)橫向滑動(dòng)代碼
這篇文章主要介紹了Android中RecyclerView實(shí)現(xiàn)橫向滑動(dòng)代碼的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-07-07Android Studio實(shí)現(xiàn)井字游戲
這篇文章主要為大家詳細(xì)介紹了Android Studio實(shí)現(xiàn)井字游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01Flutter桌面開發(fā)windows插件開發(fā)
這篇文章主要為大家介紹了Flutter桌面開發(fā)windows插件開發(fā)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11Android 中Seekbar詳解及簡(jiǎn)單實(shí)例
這篇文章主要介紹了Android 中Seekbar詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-04-04