android opencv,Android引入OpenCV的示例

本文详细介绍了如何在Android项目中集成OpenCV库进行图像处理。首先,将OpenCV的动态库和静态库放入jniLibs目录,接着在cpp文件夹下导入include文件。在build.gradle中配置c++支持,并在CMakeLists.txt中声明OpenCV库。然后,提供了一个简单的均值滤波的示例代码,展示如何在cpp中调用OpenCV进行图像模糊处理。最后,通过Java Native Interface调用C++代码并更新图片显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

在移动开发中,如果我们要实现一些图像处理相关的功能,难免要用到OpenCV。而OpenCV是用c++开发的。我们在Android中,需要使用jni的方法去使用它。

引入配置

我们引入jni开发的基本配置方法,已经在另一篇博客中介绍过了,不再赘述。这一次我们无非是要引入第三方的c++库。

首先,我们找到或新建jniLibs文件夹,然后将依赖的动态库和静态库(路径为OpenCV-android-sdk\sdk\native\libs)拷贝到\src\main\jniLibs下面。

然后,找到cpp文件夹。将include文件夹(路径OpenCV-android-sdk\sdk\native\jni\include)拷贝到cpp(路径\app\src\main\cpp)文件夹里。

接着,我们需要引入c++的相关支持。在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相关的声明。由于配置比较复杂,在此直接将demo的CMakeLists.txt的内容贴到这里。

# 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库了。在此贴一个简单的均值滤波:

#include

#include

#include

#include

#include

#include

#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;

}

}

这样我们就能看到一个基本的模糊效果的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);

}

});

}

}

82101358788f144adf30abe7cf99d2c5.png

导出.so

fd657159714b171425596a58da1ed656.png

在build中找到这个so,这就是我们需要的文件。此外,由于我们使用了opencv相关的库,我们还需要将opencv的相关文件复制出来。将其导入我们需要的工程。

78ce95175ba5b2c4ece7cb055e9ca4ea.png

导入之后,我们只需要在module的build.gradle里面加入:

android {

...

sourceSets {

main {

jniLibs.srcDirs = ['src/main/jniLibs']

aidl.srcDirs = ['src/main/aidl']

}

}

}

之后,我们就可以直接调用

System.loadLibrary("native-lib");

值得注意的是,JNI的方法是与路径名相关的,所以当我们以这样的方法调用native方法时,我们需要路径名匹配。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值