Android Stuido 导入OpenCV 使用的三种方式实现并比较(填坑版)

一. 资料准备

Android Studio 3.6
OpenCv Sdk下载:https://opencv.org/releases/#
选 OpenCV – 4.3.0 android下载,比较慢,可以考虑使用迅雷下载
下载解压后有samples和sdk两个目录,主要关注sdk目录:
在这里插入图片描述

二.As使用opencv sdk的三种方式

2.1 在Java层使用 OpenCv Java API

  1. 新建普通的android app项目:
    在这里插入图片描述
    看到已经有libs文件夹,但main中比ndk项目少了cpp目录,且无cmakelist文件,先用着吧,后面看看是否可以手动添加.

  2. file->new->import module,选择下载解压后的opencv sdk的如下目录,导入opencv的java module,实际是opencv自己实现的调用JNI接口的java层:
    在这里插入图片描述

  3. 修改java_opencv的模块属性:如下
    在这里插入图片描述

  4. 打开openCvDemo的 project sturcture 设置库依赖,当然也可以在app的build gradle文件中dependencies {}中添加 " implementation project(path: ‘:java_opencv’)" 这一行
    在这里插入图片描述

  5. 将OpenCV-android-sdk/sdk/native/libs下的arm64-v8a 目录拷贝到Android studio OpenCvDemo的libs文件夹中,在app的build.gradle中的android节点下添加
    jniLib.srcDir,该变量指明了JNI所需要的动态库目录,如下:
    在这里插入图片描述
    注意需要将libc++shared.so拷贝到jnilib目录下,原因如图所示,可以从其他项目中拷贝过来,也可以从ndk的toolchain中寻找拷贝.

(

或者也可以这样处理:

新建如上图中的cpp目录,或自定义目录,写个空类似ndk项目初始化时的cpp文件,注意,如果是一开始建的是非ndk项目,建完自定义jni文件之后需要手动制定jni.srcDirs

否则自己写的cpp无法编译成动态库打包到apk中,具体cpp可以参考ndk项目默认初始时的native-lib文件.在android节点里的defaultConfig节点里的externalNativeBuild节点里添加" arguments “-DANDROID_STL=c++_shared” "

这样,在编译native-lib时便会自动拷贝libc++_static.so打包到apk中.如下图
在这里插入图片描述
这里有个小坑,从网上拷贝了一个

sourceSets.main{
XXXX
}

来写,结果死活没编到制定的jni.srcDirs目录下的代码,

改成

sourceSets {
    main{
XXXX
    }
}

醉了
)

  1. 开始写代码
    activity:
package com.chengang.opencvdemo;
 
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
 
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;
 
public class MainActivity extends AppCompatActivity  implements View.OnClickListener{
 
    String TAG="MainActivity";
 
    ImageView img_after;
    TextView text_togray;
    Bitmap srcBitmap;
    Bitmap grayBitmap;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        img_after=(ImageView)findViewById(R.id.imageView_after);
        text_togray=(TextView)findViewById(R.id.textView_togray);
        text_togray.setOnClickListener(this);
 
        System.loadLibrary("opencv_java4");
    }
 
    @Override
    public void onClick(View v) {
        switch(v.getId())
        {
            case R.id.textView_togray:
                procSrc2Gray();
                img_after.setImageBitmap(grayBitmap) ;
                break;
        }
    }
 
    public void procSrc2Gray(){
        Mat rgbMat = new Mat();
        Mat grayMat = new Mat();
        srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.iu);
        grayBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), Bitmap.Config.RGB_565);
        Utils.bitmapToMat(srcBitmap, rgbMat);//convert original bitmap to Mat, R G B.
        Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY);//rgbMat to gray grayMat
        Utils.matToBitmap(grayMat, grayBitmap); //convert mat to bitmap
        Log.i(TAG, "procSrc2Gray sucess...");
    }
 
    @Override
    public void onResume()
    {
        super.onResume();
    }
 
}

layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="0dp"
    android:paddingLeft="0dp"
    android:paddingRight="0dp"
    android:paddingTop="0dp"
    tools:context=".MainActivity">
 
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
 
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1">
 
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="原图"
                android:id="@+id/textView" />
 
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/imageView_before"
                android:src="@drawable/iu"
                />
        </LinearLayout>
 
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="3dp"
            android:background="@color/material_grey_900"></LinearLayout>
 
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1">
 
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="灰度化"
                android:id="@+id/textView_togray" />
 
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/imageView_after" />
        </LinearLayout>
 
    </LinearLayout>
 
</RelativeLayout>

再放一张IU的图片到res/drawable/下
在这里插入图片描述
7.ok编译运行可执行.
在这里插入图片描述

2.2 自定义JNI使用Native API实现

上面这种方式需要导入opencv的java module,相当于导入了opencv实现的调用native接口的jar包,有时候我们不需要那么多接口,也许只需要一个功能,导入这么多有点浪费空间啊,

因此可以避免使用java module 直接使用opencv的native api去使用.尝试一下,

看activity调用的opencv 方法:

/home/chengang/AndroidStudioProjects/OpenCvDemo/app/src/main/java/com/chengang/opencvdemo/MainActivity.java
public void procSrc2Gray(){
    Mat rgbMat = new Mat();
    Mat grayMat = new Mat();
    srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.iu);
    grayBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), Bitmap.Config.RGB_565);
    Utils.bitmapToMat(srcBitmap, rgbMat);//convert original bitmap to Mat, R G B.
    Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY);//rgbMat to gray grayMat
    Utils.matToBitmap(grayMat, grayBitmap); //convert mat to bitmap
    Log.i(TAG, "procSrc2Gray sucess...");
}

主要是该方法实现
Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY);//rgbMat to gray grayMat
在java_opencv module中搜cvColor

/home/chengang/AndroidStudioProjects/OpenCvDemo/java_opencv/src/main/java/org/opencv/imgproc/Imgproc.java
/**
 * Converts an image from one color space to another.
....
 *
 * SEE: REF: imgproc_color_conversions
 */
public static void cvtColor(Mat src, Mat dst, int code) {
    cvtColor_1(src.nativeObj, dst.nativeObj, code);
}

在这里插入图片描述
在sdk中搜头文件:
在这里插入图片描述

  1. 头文件准备
    在/home/chengang/AndroidStudioProjects/OpenCvDemo/app/src/main/cpp/下新建myIncludes文件夹将OpenCV-android-sdk/sdk/native/jni/include/下的opencv2目录拷贝到myIncludes下,目录在cmakelist.txt中要指明好,cpp下的CmakeList.txt修改如下图::
    在这里插入图片描述
    在这里插入图片描述
    app module的build.gradle修改:
    在这里插入图片描述
  2. 修改代码
    好,开始实现,基于上面已完成的Maincativity修改如下:
/home/chengang/AndroidStudioProjects/OpenCvDemo/app/src/main/java/com/chengang/opencvdemo/MainActivity.java
// 1.添加如下JNI函数定义,之后IDE会提示实现该定义,则会在native-lib.cpp中去实现,后面贴上
private native void cvtColorFromJNI2(Bitmap srcBitmap,Bitmap dstBitmap);
 
//改写procSrc2Gray为procSrc2Gray2
public void procSrc2Gray2(){
    srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.iu);
    grayBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), Bitmap.Config.RGB_565);
    cvtColorFromJNI2(srcBitmap,grayBitmap);
    Log.i(TAG, "procSrc2Gray sucess...");
}
 
 
//3.调用的地方改为使用procSrc2Gray2
@Override
public void onClick(View v) {
    switch(v.getId())
    {
        case R.id.textView_togray:
            //procSrc2Gray();
            procSrc2Gray2();
            img_after.setImageBitmap(grayBitmap) ;
            break;
    }
}

/home/chengang/AndroidStudioProjects/OpenCvDemo/app/src/main/cpp/native-lib.cpp实现如下:
主要完成:
a. native实现Bitmap2mat和mat2bitmap的实现,基于opencv基本是对mat数据结构处理的要求.
b.直接调用opencv的cv::cvtColor()函数实现置灰操作.

#include <jni.h>
#include <string>
#include <opencv2/imgproc.hpp>
#include <opencv2/core/mat.hpp>
#include <android/bitmap.h>
#include <opencv2/opencv.hpp>
#include <opencv2/imgcodecs/legacy/constants_c.h>
 
 
using namespace cv;
using namespace std;
 
void BitmapToMat2(JNIEnv *env, jobject& bitmap, Mat& mat, jboolean needUnPremultiplyAlpha) {
    AndroidBitmapInfo info;
    void *pixels = 0;
    Mat &dst = mat;
 
    try {
        //LOGD("nBitmapToMat");
        CV_Assert(AndroidBitmap_getInfo(env, bitmap, &info) >= 0);
        CV_Assert(info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 ||
                  info.format == ANDROID_BITMAP_FORMAT_RGB_565);
        CV_Assert(AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0);
        CV_Assert(pixels);
        dst.create(info.height, info.width, CV_8UC4);
        if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
           // LOGD("nBitmapToMat: RGBA_8888 -> CV_8UC4");
            Mat tmp(info.height, info.width, CV_8UC4, pixels);
            if (needUnPremultiplyAlpha) cvtColor(tmp, dst, COLOR_mRGBA2RGBA);
            else tmp.copyTo(dst);
        } else {
            // info.format == ANDROID_BITMAP_FORMAT_RGB_565
           // LOGD("nBitmapToMat: RGB_565 -> CV_8UC4");
            Mat tmp(info.height, info.width, CV_8UC2, pixels);
            cvtColor(tmp, dst, COLOR_BGR5652RGBA);
        }
        AndroidBitmap_unlockPixels(env, bitmap);
        return;
    } catch (const cv::Exception &e) {
        AndroidBitmap_unlockPixels(env, bitmap);
       // LOGE("nBitmapToMat catched cv::Exception: %s", e.what());
        jclass je = env->FindClass("org/opencv/core/CvException");
        if (!je) je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, e.what());
        return;
    } catch (...) {
        AndroidBitmap_unlockPixels(env, bitmap);
        //LOGE("nBitmapToMat catched unknown exception (...)");
        jclass je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, "Unknown exception in JNI code {nBitmapToMat}");
        return;
    }
}
 
void BitmapToMat(JNIEnv *env, jobject& bitmap, Mat& mat) {
    BitmapToMat2(env, bitmap, mat, false);
}
 
void MatToBitmap2
        (JNIEnv *env, Mat& mat, jobject& bitmap, jboolean needPremultiplyAlpha) {
    AndroidBitmapInfo info;
    void *pixels = 0;
    Mat &src = mat;
 
    try {
       // LOGD("nMatToBitmap");
        CV_Assert(AndroidBitmap_getInfo(env, bitmap, &info) >= 0);
        CV_Assert(info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 ||
                  info.format == ANDROID_BITMAP_FORMAT_RGB_565);
        CV_Assert(src.dims == 2 && info.height == (uint32_t) src.rows &&
                  info.width == (uint32_t) src.cols);
        CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8UC3 || src.type() == CV_8UC4);
        CV_Assert(AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0);
        CV_Assert(pixels);
        if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
            Mat tmp(info.height, info.width, CV_8UC4, pixels);
            if (src.type() == CV_8UC1) {
              //  LOGD("nMatToBitmap: CV_8UC1 -> RGBA_8888");
                cvtColor(src, tmp, COLOR_GRAY2RGBA);
            } else if (src.type() == CV_8UC3) {
               // LOGD("nMatToBitmap: CV_8UC3 -> RGBA_8888");
                cvtColor(src, tmp, COLOR_RGB2RGBA);
            } else if (src.type() == CV_8UC4) {
               // LOGD("nMatToBitmap: CV_8UC4 -> RGBA_8888");
                if (needPremultiplyAlpha)
                    cvtColor(src, tmp, COLOR_RGBA2mRGBA);
                else
                    src.copyTo(tmp);
            }
        } else {
            // info.format == ANDROID_BITMAP_FORMAT_RGB_565
            Mat tmp(info.height, info.width, CV_8UC2, pixels);
            if (src.type() == CV_8UC1) {
               // LOGD("nMatToBitmap: CV_8UC1 -> RGB_565");
                cvtColor(src, tmp, COLOR_GRAY2BGR565);
            } else if (src.type() == CV_8UC3) {
               // LOGD("nMatToBitmap: CV_8UC3 -> RGB_565");
                cvtColor(src, tmp, COLOR_RGB2BGR565);
            } else if (src.type() == CV_8UC4) {
                //LOGD("nMatToBitmap: CV_8UC4 -> RGB_565");
                cvtColor(src, tmp, COLOR_RGBA2BGR565);
            }
        }
        AndroidBitmap_unlockPixels(env, bitmap);
        return;
    } catch (const cv::Exception &e) {
        AndroidBitmap_unlockPixels(env, bitmap);
        //LOGE("nMatToBitmap catched cv::Exception: %s", e.what());
        jclass je = env->FindClass("org/opencv/core/CvException");
        if (!je) je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, e.what());
        return;
    } catch (...) {
        AndroidBitmap_unlockPixels(env, bitmap);
        //LOGE("nMatToBitmap catched unknown exception (...)");
        jclass je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, "Unknown exception in JNI code {nMatToBitmap}");
        return;
    }
}
 
void MatToBitmap(JNIEnv *env, Mat& mat, jobject& bitmap) {
    MatToBitmap2(env, mat, bitmap, false);
}
 
extern "C"
JNIEXPORT void JNICALL
Java_com_chengang_opencvdemo_MainActivity_cvtColorFromJNI2(JNIEnv *env, jobject thiz,
                                                           jobject src_bitmap, jobject dst_bitmap) {
    // TODO: implement cvtColorFromJNI2()
    Mat srcImageMat;
    BitmapToMat(env,src_bitmap,srcImageMat);
    Mat dstImageMat;
    cv::cvtColor(srcImageMat,dstImageMat,COLOR_RGB2GRAY);
    MatToBitmap(env,dstImageMat,dst_bitmap);
}

这样,是没有使用java的api的,我们自定义了一个JNI函数来自己实现调用opencv的native接口函数处理,
这时,将app module的build.gradle中的dependencies节点中的"implementation project(path: ‘:java_opencv’)"给删掉或注释掉,去掉依赖java module,
再在MainActivity中关于java_opencv module的使用地方给删掉或注释掉,
即不再使用opencv提供的java module api.

  1. 可以编译成功,安装运行成功.

2.3 使用openCv静态库编译动态库实现

opencv sdk中有提供静态库及所依赖的3rdparty的静态库,可以利用这些静态库链接实现功能的动态库native-lib.so

基于上一步的代码这么干:
1.把OpenCV-android-sdk/sdk/native/3rdparty/libs 下需要的arm64-v8a 架构的文件夹拷贝到app目录下的libs文件夹下

2.把OpenCV-android-sdk/sdk/native/下的staticlibs文件夹拷贝到app目录下的libs文件夹下.当然,可以只保留我们需要的arm64-v8a 架构,其他架构的可以删掉(基于手上有的机型abi架构是arm64的,只需要arm64的即可).

3.在cpp目录下cmakelist.txt文件进行配置如下图:
在这里插入图片描述
在这里插入图片描述
4.修改代码,把libs下的opencv的动态库libopencv_java4.so删掉,不需要啦,opencv的功能已经通过静态链接从opencv的静态库中链接到了
我们自己的native-lib.so中了,最终只需一个native-lib.so动态库.
在这里插入图片描述
activty:

/home/chengang/AndroidStudioProjects/OpenCvDemo/app/src/main/java/com/chengang/opencvdemo/MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
 
    img_after=(ImageView)findViewById(R.id.imageView_after);
    text_togray=(TextView)findViewById(R.id.textView_togray);
    text_togray.setOnClickListener(this);
 
    //System.loadLibrary("opencv_java4");//记得不需要load opencv_java4了
    System.loadLibrary("native-lib"); //记得需要load 包含opencv功能的native-lib 动态库
}
  1. 运行吧,安装成功,运行成功.

三.对比Apk size

第一种使用Java Module实现Java API调用OpenCv 动态库Native API方式:
apk size:20.7MB
在这里插入图片描述
第二种使用自定义JNI So 调用 OpenCv 动态库Native API方:
apk size:20.4MB
在这里插入图片描述
第三种使用opencv 静态库链接JNI 动态库native-lib.so方式:
apk size:5.6MB
在这里插入图片描述
看出前两种相差不大,都包含一个完整的opencv动态库,而第三种只有一个libnative-lib.so,而libnative-lib.so包含的是静态链接来的cpp中仅仅使用到的opencv的功能模块,我们这个demo仅仅用了下置灰功能,
看样子还是第三种比较实在,在size上完胜前两种.

### 回答1: 要在Android Studio中导入OpenCV,您需要执行以下步骤: 1. 下载OpenCV Android SDK并解压缩。 2. 打开Android Studio并创建一个新项目。 3. 在项目的根目录下创建一个名为“libs”的文件夹。 4. 将解压缩的OpenCV Android SDK中的“libs”文件夹中的所有文件复制到您创建的“libs”文件夹中。 5. 在项目的根目录下创建一个名为“jniLibs”的文件夹。 6. 将解压缩的OpenCV Android SDK中的“jni”文件夹中的所有文件复制到您创建的“jniLibs”文件夹中。 7. 在项目的根目录下创建一个名为“build.gradle”的文件。 8. 在“build.gradle”文件中添加以下代码: ``` dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation fileTree(dir: 'jniLibs', include: ['*.so']) } ``` 9. 在您的项目中使用OpenCV库。 以上就是在Android Studio中导入OpenCV的步骤。 ### 回答2: Android Studio是一款广泛使用Android应用程序开发工具,而OpenCV是一个开放源代码的计算机视觉和机器学习库,通过它可以在Android应用中实现许多现实世界的计算机视觉应用。目前,越来越多的开发者开始使用OpenCVAndroid应用中实现激进建模、人脸识别、物体检测等功能。接下来,将详细介绍如何在Android Studio中导入OpenCV。 1.下载OpenCV SDK:首先需要到OpenCV官网下载OpenCV SDK,下载页面提供了多个本的OpenCV SDK,我们需要选择最适合我们的本; 2.创建Android工程:在Android Studio上创建一个空白Android工程,依次选择File -> New -> New Project,填写工程名、包名、保存路径等信息,最后点击Finish完成创建; 3.导入OpenCV SDK:将下载好的OpenCV SDK解压,复制其中的两个文件夹(Java和native)到新建的Android工程的主模块目录下; 4.配置工程:在build.gradle配置文件中添加OpenCV库; 在build.gradle(Module:app)中添加以下代码: ``` import org.gradle.internal.os.OperatingSystem def opencvdir = "$rootDir/OpenCV-android-sdk" def libname_first = "libopencv_java4" android { // ... } dependencies { // ... if (!isWindows()) { implementation files("$opencvdir/native/libs/${getOpenCvArch()}/$libname_first.so") } else { implementation files("$opencvdir/native/libs/${getOpenCvArch()}/$libname_first.dll") } } static def isWindows() { return OperatingSystem.current().windows } static def getOpenCvArch() { def arch = System.getProperty('os.arch') switch (arch) { case 'x86': case 'i386': case 'i486': case 'i586': case 'i686': return "x86" case 'amd64': case 'x86_64': return "x86_64" case 'arm': case 'armv5': return "armeabi-v7a" case 'armv6': return "armeabi-v6" case 'arm64': case 'aarch64': return "arm64-v8a" default: println "WARNING: CPU arch '$arch' was not recognized as official OpenCV arch" return null } } ``` 5.测试OpenCV:在MainActivity中测试导入OpenCV库,例如调用OpenCV中的imread函数读取一张图像: ``` public void testOpenCV() { String imagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.jpg"; Mat srcMat = Imgcodecs.imread(imagePath, Imgcodecs.CV_LOAD_IMAGE_COLOR); if (srcMat.empty()) { return; } Bitmap srcBitmap = Bitmap.createBitmap(srcMat.width(), srcMat.height(), Bitmap.Config.ARGB_8888); Utils.matToBitmap(srcMat, srcBitmap); ImageView imageView = findViewById(R.id.imageView); imageView.setImageBitmap(srcBitmap); } ``` 通过以上方法,我们可以成功在Android Studio中导入OpenCV实现相应的计算机视觉应用。在使用过程中,需要根据自己的需求调用OpenCV中的相应函数,实现自己的功能。 ### 回答3: Android Studio是一个用于开发Android应用程序的集成开发环境(IDE)。如果你想使用图像处理功能,例如人脸识别或条形码扫描,就可以使用OpenCV库。 以下是在Android Studio中导入OpenCV的步骤: 1. 下载OpenCV安卓库 首先,在OpenCV网站上下载OpenCV安卓库。打开下载页面,选择适合你的OpenCV本和Android Studio本的库,然后下载该压缩文件。 2. 新建Android studio工程 在Android Studio中新建工程。 3. 在app的gradle文件中添加OpenCV库 解压下载的OpenCV安卓压缩文件后,在Android Studio工程的app的gradle文件中添加代码: ``` dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation project(':opencv') } ``` 其中'opencv'表示OpenCV库的名称。 4. 将OpenCV库文件放入工程中 在解压后的OpenCV安卓库文件夹中,找到libs文件夹。在Android Studio工程的app的main文件夹中,创建一个文件夹名为'jniLibs',随后把OpenCV库文件复制/剪切粘贴到该文件夹中。 5. 配置OpenCV库文件路径 在工程目录下,找到build.gradle文件,并在文件中添加如下代码: ``` sourceSets { main{ jniLibs.srcDirs=[ 'src/main/jniLibs', 'src/main/jniLibs/<平台对应的OpenCV文件夹>' ] } } ``` 将<>里的内容替换为你所下载的OpenCV本对应的平台文件夹。 6. 在Java代码中调用OpenCV库 在你想要使用OpenCV库的Java文件中,导入OpenCV库并使用相关函数,例如: ``` import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.CvType; ... Mat m = new Mat(5, 5, CvType.CV_8UC1, new Scalar(0)); Log.i(TAG, "OpenCV Mat: " + m); Core.transpose(m, m); Log.i(TAG, "OpenCV Mat after transpose: " + m); ``` 以上是在Android Studio中导入OpenCV的步骤。导入后,你可以使用OpenCV的函数进行图像处理,例如图像滤波、图像平滑、边缘检测等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值