Android开发配置opencv环境超详细教程

原文:http://blog.csdn.net/u012341163/article/details/51065310

1、前期准备

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

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

开始配置

1.安装Android NDK

新建项目,建完后可通过Android studio下载Android NDK环境 
配置ndk
这里写图片描述
这里写图片描述
一般是没有Android NDK的,勾上后点Apply,然后等它下载,安装 
PS:需要翻墙,不知道如何翻墙的,参考如下网址

google翻墙

2 添加opencv native包

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

这里写图片描述
拷贝后: 
这里写图片描述

3 配置编译环境

编辑gradle.properties文件,增加下面的属性使用旧版的ndk功能(不添加会使用实验性的ndk构建工具) 
android.useDeprecatedNdk=true 

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

这里写图片描述
编辑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/jniLibs

task 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'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

加入前: 
这里写图片描述
加入后(代码太长截图没截完): 
这里写图片描述
在main中新建jni目录,并在jni中新建Android.mk和Application.mk 
这里写图片描述
这里写图片描述
在Android.mk中加入如下代码

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)


OpenCV_INSTALL_MODULES := on
OpenCV_CAMERA_MODULES := off

OPENCV_LIB_TYPE :=STATIC

ifeq ("$(wildcard $(OPENCV_MK_PATH))","")
include ..\..\..\..\native\jni\OpenCV.mk
else
include $(OPENCV_MK_PATH)
endif

LOCAL_MODULE := OpenCV

LOCAL_SRC_FILES :=

LOCAL_LDLIBS +=  -lm -llog

include $(BUILD_SHARED_LIBRARY)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在Application.mk中加入如下代码

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi armeabi-v7a
APP_PLATFORM := android-8
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

这时候,使用gradle构建一下,如果能成功构建出so,说明配置没问题,如下图,点击Android studio右侧的gradle展开,在app->other中找到ndkbuild(没有就刷新)进行构建 
这里写图片描述
这里写图片描述
这里写图片描述

4 实现jni调用

在建项目时自带的Java文件所在的文件夹中,新建一个java文件,声明native方法,这里尝试实现灰度化方法,所以命名为gray 
这里写图片描述
使用javah命令生成头文件,利用AS(android studio)下方的terminal窗口 
如图: 
这里写图片描述
这里需要注意,有大坑,不会javah的人尤其注意,这里不能进入刚才新建的java文件所在那个目录进行生成,会出现找不到“XXX”类错误,使用javah命令时,必须进入java目录,即上图中cd进去的那个目录,然后使用 
javah -d ../jni com.example.administrator.tryopencv.OpenCVHelper 
其中中间的-d ../jni 是指定输出目录,后面需要生成头文件的java名称一定要写完整,要从com开始写,每一层包含关系都写出来,即写成这样com.example.administrator.tryopencv.OpenCVHelper 
这样才没问题,在jni目录中会出现生成的头文件,如上图所示 
头文件中内容如下: 
这里写图片描述
然后新建刚才生成的.h对应的cpp文件,注意文件名称和函数名称,一定要一致哦 
这里写图片描述
这里写图片描述
建好后就在里面写实现函数啦,灰度化图像

//
// 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)
    {
        //图像存储方式为:BGRA
        int 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;
}

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

然后在Andorid.mk文件中加入 
LOCAL_SRC_FILES :=com_example_administrator_tryopencv_OpenCVHelper.cpp 
这里写图片描述
然后在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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="choose picture!"
        android:id="@+id/title"/>

    <Button
        android: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" />

    <ImageView
        android: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" />

    <Button
        android: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" />
    <ImageView
        android: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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

这里写图片描述
这是java文件中的代码 
这里写图片描述

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 {

    @Override
    protected 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这个Action
                myIntent.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这个Action
                myIntent.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);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135

然后就可以运行啦 
这里写图片描述

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

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

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)


OpenCV_INSTALL_MODULES := on
OpenCV_CAMERA_MODULES := off

OPENCV_LIB_TYPE :=SHARED

ifeq ("$(wildcard $(OPENCV_MK_PATH))","")
include ..\..\..\..\native\jni\OpenCV.mk
else
include $(OPENCV_MK_PATH)
endif


LOCAL_MODULE := OpenCV

LOCAL_SRC_FILES :=

LOCAL_LDLIBS +=  -lm -llog

include $(BUILD_SHARED_LIBRARY)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

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

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

这里写图片描述
在main文件夹下新建aidl文件夹 
将org/opencv/engine/XXX.aidl文件连同目录一起拷到刚才新建的文件夹中 
如图 
这里写图片描述
这里动态编译出的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会有变量不认识 
如图: 
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述 
布局文件:

<?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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="choose picture!"
        android:id="@+id/title"/>

    <Button
        android: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" />

    <ImageView
        android: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" />

    <Button
        android: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" />
    <ImageView
        android: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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

主程序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 {

    @Override
    protected 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这个Action
                myIntent.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这个Action
                myIntent.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);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150

运行即可,运行中会遇到,在opencv某个文件中出现找不到R包的错误,出现错误时,进入那个文件,导入自己的R包即可 
运行结果: 
这里写图片描述 
这里写图片描述

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

展开阅读全文

没有更多推荐了,返回首页