[安卓开发笔记一]Android开发配置opencv环境超详细教程

【更新于 2022年4月】 再次提醒,建议现在看到这篇文章的,仅仅把此文做一个流程参考,4年前android studio就使用cmakelist编译,直接使用cmakelist编译会方便很多的哈,使用cmakelist的方法建议去android studio的官网上看有中文的文档的,本文图片由于之前存的云空间公司倒闭了,年代久远 就无法恢复了。 使用cmakelist配置更简单,只需要下载opencv库和头文件,在cmakelist中编译时link对应的库,编译为可用的so,然后在jni中引用对应头文件就能使用对应函数了。

建议现在看到这篇文章的,仅仅把此文做一个流程参考,现在as支持cmakelist编译,直接使用cmakelist编译会方便很多的哈使用cmakelist的方法建议去as的官网上看有中文的文档的 -----17-9-29

开发安卓项目时要用到opencv,在网上找了很多教程,踩了很多坑才弄好,这里将自己亲自配置的过程记录如下,方便后人

1、前期准备

1 上opencv官网,下载opencv for android
2 安装 Android studio

2、方法一(使用C++实现底层算法再利用jni传递使用)

开始配置

1.安装Android NDK

新建项目,建完后可通过Android studio下载Android NDK环境
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RvNT83U5-1658222588150)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage001.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UGHpi4wu-1658222588151)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage003.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YaryxS6i-1658222588152)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage005.png)]
一般是没有Android NDK的,勾上后点Apply,然后等它下载,安装
PS:需要翻墙,不知道如何翻墙的,参考如下网址

google翻墙

2 添加opencv native包

将opencv官网上下载好的opencv for Android 中的native文件夹,拷贝到建好的工程根目录下,如图
拷贝前:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3gNI68Y7-1658222588152)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage007.png)]
拷贝后:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-diCs1kNI-1658222588153)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage009.png)]

3 配置编译环境

编辑gradle.properties文件,增加下面的属性使用旧版的ndk功能(不添加会使用实验性的ndk构建工具)
android.useDeprecatedNdk=true
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sNwWhERv-1658222588153)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage011.png)]

在local.properties文件中配置ndk目录
ndk.dir=D:\Android\sdk\ndk-bundle
sdk.dir=D:\Android\sdk
(如果是通过Android studio 来安装的Android NDK 这一步可以不用,因为Android studio安装NDK了)自动配置好

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4KE41p8B-1658222588153)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage013.png)]
编辑build.gradle,在android节点中增加下面的代码

sourceSets.main.jni.srcDirs = []
//禁止自带的ndk功能
sourceSets.main.jniLibs.srcDirs = ['src/main/libs','src/main/jniLibs']
//重定向so目录为src/main/libs和src/main/jniLibs,原来为src/main/jniLibstask ndkBuild(type: Exec, description: 'Compile JNI source with NDK') {Properties properties = new Properties()properties.load(project.rootProject.file('local.properties').newDataInputStream())def ndkDir = properties.getProperty('ndk.dir')if (org.apache.tools.ant.taskdefs.condition.Os.isFamily(org.apache.tools.ant.taskdefs.condition.Os.FAMILY_WINDOWS)) {commandLine "$ndkDir/ndk-build.cmd", '-C', file('src/main/jni').absolutePath} else {commandLine "$ndkDir/ndk-build", '-C', file('src/main/jni').absolutePath}
}tasks.withType(JavaCompile) {compileTask -> compileTask.dependsOn ndkBuild
}task ndkClean(type: Exec, description: 'Clean NDK Binaries') {Properties properties = new Properties()properties.load(project.rootProject.file('local.properties').newDataInputStream())def ndkDir = properties.getProperty('ndk.dir')if (org.apache.tools.ant.taskdefs.condition.Os.isFamily(org.apache.tools.ant.taskdefs.condition.Os.FAMILY_WINDOWS)) {commandLine "$ndkDir/ndk-build.cmd",'clean', '-C', file('src/main/jni').absolutePath} else {commandLine "$ndkDir/ndk-build",'clean', '-C', file('src/main/jni').absolutePath}
}clean.dependsOn 'ndkClean'

加入前:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RWIw3aVT-1658222588154)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage015.png)]
加入后(代码太长截图没截完):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IWsyRuf8-1658222588154)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage017.png)]
在main中新建jni目录,并在jni中新建Android.mk和Application.mk
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gicuBSzm-1658222588155)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage019.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hqRbGXim-1658222588155)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage021.png)]
在Android.mk中加入如下代码

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)OpenCV_INSTALL_MODULES := on
OpenCV_CAMERA_MODULES := offOPENCV_LIB_TYPE :=STATICifeq ("$(wildcard $(OPENCV_MK_PATH))","")
include ..\..\..\..\native\jni\OpenCV.mk
else
include $(OPENCV_MK_PATH)
endifLOCAL_MODULE := OpenCVLOCAL_SRC_FILES :=LOCAL_LDLIBS +=  -lm -lloginclude $(BUILD_SHARED_LIBRARY)

在Application.mk中加入如下代码

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi armeabi-v7a
APP_PLATFORM := android-8

这时候,使用gradle构建一下,如果能成功构建出so,说明配置没问题,如下图,点击Android studio右侧的gradle展开,在app->other中找到ndkbuild(没有就刷新)进行构建
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gDeQJQNn-1658222588155)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage023.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-btzDJmqh-1658222588156)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage025.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NiW2TUul-1658222588156)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage027.png)]

4 实现jni调用

在建项目时自带的java文件所在的文件夹中,新建一个java文件,声明native方法,这里尝试实现灰度化方法,所以命名为gray
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wA3oeShf-1658222588156)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage029.png)]
使用javah命令生成头文件,利用AS(android studio)下方的terminal窗口
如图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N6SlxtAr-1658222588157)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage031.png)]
这里需要注意,有大坑,不会javah的人尤其注意,这里不能进入刚才新建的java文件所在那个目录进行生成,会出现找不到“XXX”类错误,使用javah命令时,必须进入java目录,即上图中cd进去的那个目录,然后使用
javah -d …/jni com.example.administrator.tryopencv.OpenCVHelper
其中中间的-d …/jni 是指定输出目录,后面需要生成头文件的java名称一定要写完整,要从com开始写,每一层包含关系都写出来,即写成这样com.example.administrator.tryopencv.OpenCVHelper
这样才没问题,在jni目录中会出现生成的头文件,如上图所示
头文件中内容如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rb3l1tXl-1658222588157)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage033.png)]
然后新建刚才生成的.h对应的cpp文件,注意文件名称和函数名称,一定要一致哦
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-75nYTDqp-1658222588158)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage035.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r4hM1Nzk-1658222588158)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage037.png)]
建好后就在里面写实现函数啦,灰度化图像

//
// Created by Administrator on 2015/12/22.
//
#include "com_example_administrator_tryopencv_OpenCVHelper.h"
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/opencv.hpp>using namespace cv;extern "C" {JNIEXPORT jintArray JNICALL Java_com_example_administrator_tryopencv_OpenCVHelper_gray(JNIEnv *env,jclass obj,jintArray buf,int w,int h);JNIEXPORT jintArray JNICALL Java_com_example_administrator_tryopencv_OpenCVHelper_gray(JNIEnv *env,jclass obj,jintArray buf,int w,int h)
{jint *cbuf;cbuf = env->GetIntArrayElements(buf,JNI_FALSE);if (NULL == cbuf){return 0;}Mat imgData(h,w,CV_8UC4,(unsigned char*) cbuf);u_char *ptr = imgData.ptr(0);for (int i = 0; i < w*h; ++i){//图像存储方式为:BGRAint grayScale = (int)(ptr[4*i+2]*0.299 + ptr[4*i+1]*0.587 + ptr[4*i+0]*0.144 );ptr[4*i+0] = grayScale;ptr[4*i+1] = grayScale;ptr[4*i+2] = grayScale;}int size = w * h;jintArray  result = env->NewIntArray(size);env->SetIntArrayRegion(result,0,size,cbuf);env->ReleaseIntArrayElements(buf,cbuf,0);return result;
}}

然后在Andorid.mk文件中加入
LOCAL_SRC_FILES :=com_example_administrator_tryopencv_OpenCVHelper.cpp
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5WMbEJEm-1658222588158)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage039.png)]
然后在java主代码中写测试代码调用就行啦
这时布局文件代码

<?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="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="com.example.administrator.choosepic.PicActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="choose picture!"android:id="@+id/title"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="灰度图"android:id="@+id/GiveFaceButton"android:layout_below="@+id/title"android:layout_alignLeft="@+id/GetFaceButton"android:layout_alignStart="@+id/GetFaceButton"android:layout_marginTop="71dp" /><ImageViewandroid:adjustViewBounds="true"android:maxHeight="400dp"android:maxWidth="200dp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:scaleType="fitStart"android:id="@+id/IV01" /><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="原图"android:id="@+id/GetFaceButton"android:layout_centerVertical="true"android:layout_alignParentRight="true"android:layout_alignParentEnd="true" /><ImageViewandroid:adjustViewBounds="true"android:maxHeight="400dp"android:maxWidth="200dp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:scaleType="fitStart"android:id="@+id/IV02"android:layout_below="@id/IV01" />
</RelativeLayout>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nh9p5cpf-1658222588159)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage041.png)]
这是java文件中的代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KjYGgHcH-1658222588159)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage043.png)]

package com.example.administrator.tryopencv;import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;import java.io.FileNotFoundException;
import java.io.InputStream;public class tryOpenCvActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_try_open_cv);Button GiveFaceButton = (Button)findViewById(R.id.GiveFaceButton);GiveFaceButton.setOnClickListener(new Button.OnClickListener(){public void onClick(View v){Intent myIntent = new Intent();//开启picture画面Type设置为image*myIntent.setType("image/*");//使用Intent.ACTION_GET_CONTENT这个ActionmyIntent.setAction(Intent.ACTION_GET_CONTENT);/*取得相片后返回本画面*/startActivityForResult(myIntent,1);}});Button GetFaceButton = (Button)findViewById(R.id.GetFaceButton);GetFaceButton.setOnClickListener(new Button.OnClickListener(){public void onClick(View v){Intent myIntent = new Intent();//开启picture画面Type设置为image*myIntent.setType("image/*");//使用Intent.ACTION_GET_CONTENT这个ActionmyIntent.setAction(Intent.ACTION_GET_CONTENT);/*取得相片后返回本画面*/startActivityForResult(myIntent,2);}});}protected void onActivityResult(int requestCode,int resultCode,Intent data){switch (requestCode){case 1 :Uri uri = data.getData();Log.e("uri",uri.toString());ContentResolver cr = this.getContentResolver();try{InputStream input = cr.openInputStream(uri);BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeStream(input, null, options);if (options.outWidth > 1024 || options.outHeight > 1024){options.inSampleSize = Math.max(options.outWidth / 1024, options.outHeight/1024);}options.inJustDecodeBounds = false;Bitmap bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri), null, options);/*以下进行灰度化处理*/int w = bitmap.getWidth();int h = bitmap.getHeight();int[] pix = new int[w * h];bitmap.getPixels(pix, 0, w, 0, 0, w, h);int[] resultPixels = OpenCVHelper.gray(pix, w, h);Bitmap result = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);result.setPixels(resultPixels,0,w,0,0,w,h);ImageView imageView = (ImageView)findViewById(R.id.IV01);/*将处理好的灰度图设定到ImageView*/imageView.setImageBitmap(result);}catch(FileNotFoundException e){Log.e("Exception",e.getMessage(),e);}break;case 2:Uri uri2 = data.getData();Log.e("uri2",uri2.toString());ContentResolver cr2 = this.getContentResolver();try{InputStream input = cr2.openInputStream(uri2);BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeStream(input, null, options);if (options.outWidth > 1024 || options.outHeight > 1024){options.inSampleSize = Math.max(options.outWidth / 1024, options.outHeight/1024);}options.inJustDecodeBounds = false;Bitmap bitmap = BitmapFactory.decodeStream(cr2.openInputStream(uri2), null, options);ImageView imageView = (ImageView)findViewById(R.id.IV02);/*将Bitmap设定到ImageView*/imageView.setImageBitmap(bitmap);}catch(FileNotFoundException e){Log.e("Exception",e.getMessage(),e);}break;default:break;}super.onActivityResult(requestCode, resultCode,data);}
}

然后就可以运行啦
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KwTnpn6j-1658222588159)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage045.png)]

方法二 (使用opencv封装的jar包,纯java层代码处理)

前期准备和方法一相同,实际上,按照方法一做到“3 配置编译环境”中的编辑Android.mk和Application.mk这一步
这里需要编译出动态库,所以Android会有所不同
其中内容如下:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)OpenCV_INSTALL_MODULES := on
OpenCV_CAMERA_MODULES := offOPENCV_LIB_TYPE :=SHAREDifeq ("$(wildcard $(OPENCV_MK_PATH))","")
include ..\..\..\..\native\jni\OpenCV.mk
else
include $(OPENCV_MK_PATH)
endifLOCAL_MODULE := OpenCVLOCAL_SRC_FILES :=LOCAL_LDLIBS +=  -lm -lloginclude $(BUILD_SHARED_LIBRARY)

主要改的这两个地方
OPENCV_LIB_TYPE :=SHARED(静态改动态)
LOCAL_SRC_FILES :=(没有c++底层代码所以这里为空)

然后在项目中加入opencv的jar包,将之前下好的,opencv for Android sdk中的org文件夹拷贝到main文件夹中
如图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AHTQoe5p-1658222588160)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage047.png)]
在main文件夹下新建aidl文件夹
将org/opencv/engine/XXX.aidl文件连同目录一起拷到刚才新建的文件夹中
如图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yl0qOzaH-1658222588160)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage049.png)]
这里动态编译出的libopencv.so还依赖于libopencv_java3.so文件,这个文件在native/libs中可以找到,一般添加armeabi和armeabi-v7a中的即可,然后在main文件夹中新建jnilibs文件夹,将armeabi和armeabi-v7a中的libopencv_java3.so连同文件夹一起拷贝到jnilibs,还有一个资源文件,将sdk\java\res\values下的attrs.xml拷贝到工程目录res\values目录下,不然camera会有变量不认识
如图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FiMZv43o-1658222588160)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage051.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QJJU6Rb3-1658222588161)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage053.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vTQpO5uH-1658222588161)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage055.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HnQGxEcA-1658222588162)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage057.png)]
布局文件:

<?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="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="com.example.administrator.tryopencv2.tryOpenCv2Activity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="choose picture!"android:id="@+id/title"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="原图"android:id="@+id/GiveFaceButton"android:layout_below="@+id/title"android:layout_alignLeft="@+id/GetFaceButton"android:layout_alignStart="@+id/GetFaceButton"android:layout_marginTop="71dp" /><ImageViewandroid:adjustViewBounds="true"android:maxHeight="400dp"android:maxWidth="200dp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:scaleType="fitStart"android:id="@+id/IV01" /><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="灰度图"android:id="@+id/GetFaceButton"android:layout_centerVertical="true"android:layout_alignParentRight="true"android:layout_alignParentEnd="true" /><ImageViewandroid:adjustViewBounds="true"android:maxHeight="400dp"android:maxWidth="200dp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:scaleType="fitStart"android:id="@+id/IV02"android:layout_below="@id/IV01" />
</RelativeLayout>

主程序java文件

package com.example.administrator.tryopencv2;import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;import java.io.FileNotFoundException;
import java.io.InputStream;import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;public class tryOpenCv2Activity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_try_open_cv2 );Button GiveFaceButton = (Button)findViewById(R.id.GiveFaceButton);GiveFaceButton.setOnClickListener(new Button.OnClickListener(){public void onClick(View v){Intent myIntent = new Intent();//开启picture画面Type设置为image*myIntent.setType("image/*");//使用Intent.ACTION_GET_CONTENT这个ActionmyIntent.setAction(Intent.ACTION_GET_CONTENT);/*取得相片后返回本画面*/startActivityForResult(myIntent,1);}});Button GetFaceButton = (Button)findViewById(R.id.GetFaceButton);GetFaceButton.setOnClickListener(new Button.OnClickListener(){public void onClick(View v){Intent myIntent = new Intent();//开启picture画面Type设置为image*myIntent.setType("image/*");//使用Intent.ACTION_GET_CONTENT这个ActionmyIntent.setAction(Intent.ACTION_GET_CONTENT);/*取得相片后返回本画面*/startActivityForResult(myIntent,2);}});}protected void onActivityResult(int requestCode,int resultCode,Intent data){switch (requestCode){case 1 :Uri uri = data.getData();Log.e("uri",uri.toString());ContentResolver cr = this.getContentResolver();try{InputStream input = cr.openInputStream(uri);BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeStream(input, null, options);if (options.outWidth > 1024 || options.outHeight > 1024){options.inSampleSize = Math.max(options.outWidth / 1024, options.outHeight/1024);}options.inJustDecodeBounds = false;Bitmap bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri), null, options);/*以下进行灰度化处理(使用C++写底层函数jni调用)*//*int w = bitmap.getWidth();int h = bitmap.getHeight();int[] pix = new int[w * h];bitmap.getPixels(pix, 0, w, 0, 0, w, h);int[] resultPixels = OpenCVHelper.gray(pix, w, h);Bitmap result = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);result.setPixels(resultPixels,0,w,0,0,w,h);*/ImageView imageView = (ImageView)findViewById(R.id.IV01);/*将处理好的灰度图设定到ImageView*/imageView.setImageBitmap(bitmap);}catch(FileNotFoundException e){Log.e("Exception",e.getMessage(),e);}break;case 2:Uri uri2 = data.getData();Log.e("uri2",uri2.toString());ContentResolver cr2 = this.getContentResolver();try{InputStream input = cr2.openInputStream(uri2);BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeStream(input, null, options);if (options.outWidth > 1024 || options.outHeight > 1024){options.inSampleSize = Math.max(options.outWidth / 1024, options.outHeight/1024);}options.inJustDecodeBounds = false;Bitmap bitmap = BitmapFactory.decodeStream(cr2.openInputStream(uri2), null, options);/*使用opencv包进行灰度化处理*/OpenCVLoader.initDebug();Mat rgbMat = new Mat();Mat grayMat = new Mat();Bitmap grayBitmap = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),Bitmap.Config.RGB_565);Utils.bitmapToMat(bitmap,rgbMat);Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY);Utils.matToBitmap(grayMat,grayBitmap);/*将grayBitmap设定到ImageView*/ImageView imageView = (ImageView)findViewById(R.id.IV02);imageView.setImageBitmap(grayBitmap);}catch(FileNotFoundException e){Log.e("Exception",e.getMessage(),e);}break;default:break;}super.onActivityResult(requestCode, resultCode, data);}
}

运行即可,运行中会遇到,在opencv某个文件中出现找不到R包的错误,出现错误时,进入那个文件,导入自己的R包即可
运行结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H1yJlavy-1658222588162)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage059.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BAubuIIT-1658222588162)(http://7xqqmr.com1.z0.glb.clouddn.com/opencv_androidimage061.png)]

终于写完了,好累!!!项目所需还研究过android的在android studio中的jni调用,网上的资源也很少且不清楚,过段时间再写那篇教程!!

[安卓开发笔记一]Android开发配置opencv环境超详细教程相关推荐

  1. JNI开发笔记(一)--Android Studio安装与环境搭建

    Android Studio安装与环境搭建 1. 前言 1.1 什么是JNI 1.2 JNI从零开发流程 2. Java环境配置 3. Android Studio安装 参考链接 1. 前言 工作中需 ...

  2. 【C++】VSCode配置C++环境(详细教程)

    前言 本人环境: win10专业工作站版 64位 VSCode 配置C++环境 下载安装MinGW-w64及环境变量配置 MinGW:可以理解成包含多种编译环境的可自由选择安装的其中的部分的软件 下载 ...

  3. VS Code搭建C/C++开发环境超详细教程

    目录 一.下载配置MinGW 1. 下载解压 MinGW 2. 配置环境变量 3. 测试是否配置成功 二.安装 C/C++ 插件 三.第一个程序 四.相关插件推荐 1. Visual Studio I ...

  4. Struts2 注解开发实现简单的增删改查,超详细教程

    声明:此文是原创,如果需要转载请注明出处:https://blog.csdn.net/hunter_max/article/details/80575542 上一篇博客<Struts2 注解开发 ...

  5. 树莓派python开发教程_树莓派Raspberry开发从基础到进阶视频+设计资料超详细教程下载...

    课程内容 [初级篇]重点推荐:树莓派开发实战视频教程+文档教程(含源码) 课程目录 教学视频与源代码 1.[进阶篇]Raspberry详细视频教程 树莓派基础 安装树莓派的操作系统 远程登录和使用树莓 ...

  6. VS2017搭建OpenCV环境(新手详细教程)

    整体流程如下: 下载Visual Studio2017版本 下载OpenCV3.4.1版本 配置环境变量 在Visual Studio2017中引入头文件.库文件.链接库 环境测试 说明:没有必要根据 ...

  7. sublime怎么配置python环境_在Sublime Editor中配置Python环境的详细教程

    导语在工作场景遇到了这么一个场景,就是需要定期去执行一个缓存接口,用于同步设备配置.首先想到的就是Linux上的crontab,可以定期,或者间隔一段时间去执行任务.但是如果你想要 2020-12-1 ...

  8. OpenCV android sdk配置OpenCV android NDK开发实例

    OpenCV android sdk配置OpenCV android NDK开发实例 [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/det ...

  9. [安卓开发笔记二]android Studio通过jni调用C++代码

    [安卓开发笔记二]android Studio通过jni调用C++代码 16/12/11 更新 此博客基于安卓android studio 1.5所写,现在已经有了android studio2.2的 ...

最新文章

  1. signature=94f3cd0155e1d8c8ff09aa94177adccd,研擬顆粒流與連體數值耦合方法模擬山崩產生之震動訊號...
  2. 获取所有某格式文件到文件
  3. 企业自助分析难以推动?我用这套四步走方案解决了这个难题
  4. Jeecg 平台开发手册下载(20151014)
  5. 关于ECMAScript6 的学习01-ES6 的六种变量声明方式===关于常量const
  6. 平台抗住日访问量 7 亿次,研发品控流程全公开
  7. 09. 斐波那契数列(C++版本)
  8. java 接口 单元测试_java单元测试之如何实现异步接口的测试案例
  9. 安装Numpy的简单方法
  10. python自动下载邮件附件
  11. FPGA三段式状态机的思维陷阱
  12. 帝云CMS内容管理系统
  13. Window10屏幕亮度无法调节尝试解决方法
  14. 如何在码云上面上传本地项目
  15. 三菱FX3UFX2NFX1N PLC 模拟器模拟通信功能,模拟PLC实体,FX3U仿真器,仿真PLC服务器
  16. java+单子_Java单子模式
  17. 中国地质大学计算机研究生考试目录,2017年中国地质大学(武汉)资源学院考研专业目录及考试科目...
  18. 微信小程序 本地存储
  19. win10系统如果更改战网服务器,win10系统无法登录战网的四种解决方法
  20. 8421码,5421码,2421码,余3码课后学习及整理

热门文章

  1. js 自定义图片上传
  2. 对高考选志愿的一点看法
  3. 动态规划问题之求解数列中递增数列的长度
  4. kitti数据集_超全的3D视觉数据集汇总
  5. Android-X5WebView封装(Cookie管理、进度监听、适配8.1系统等策略)
  6. CDH6.2.0安装教程
  7. 使用iBatis的自动化代码生成工具Abator
  8. m6000查看端口状态_M6000常用维护命令.doc
  9. Unity3D - 【Terrain】树木与草地
  10. 基于stm32物联网开发板(1)