android studio之OpenCV(native)使用
阿新 • • 發佈:2019-01-22
- 拷貝OpenCV SDK下的native到工程的根目錄下,如下圖:
- 在main下建立jni目錄,如圖所示:
- jni下建立android.mk和application.mk,編輯檔案,內容如下:
android.mk
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
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 := IDCardRecognizeUtil.cpp\ com_hodi_hodi_opencv_OpenCVHelper.cpp
*[注意:所有要呼叫的C++/C類都要在這新增才可以使用]*
LOCAL_LDLIBS += -lm -llog
LOCAL_LDLIBS += -landroid
*【注意:landroid 可以除錯打印出android的log資訊,否則不行】*
include $(BUILD_SHARED_LIBRARY)
application.mk
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := all
【App_ABI:宣告針對哪些cpu架構的.so】
- 修改app/build.gradle,內容如下:
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.hodi.hodi_opencv"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets.main.jni.srcDirs = []
//禁止自帶的ndk功能
*【新增這行jni目錄由藍色變位黃色】*
sourceSets.main.jniLibs.srcDirs = ['src/main/libs','src/main/jniLibs']
//重定向so目錄為src/main/libs,原來為src/main/jniLibs
clean.dependsOn 'ndkClean'
}
task ndkBuild(type:Exec, group:'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, group:'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",'clean', '-C', file('src/main/jni').absolutePath
} else {
commandLine "$ndkDir/ndk-build",'clean', '-C', file('src/main/jni').absolutePath
}
}
- 建立一個native類,內容如下:
public class OpenCVHelper {
static {
System.loadLibrary("OpenCV");
}
public static native int[] gray(int[] buf, int w, int h);
public static native int[] imageToGray(String path);
}
- **再terminal ,輸入javah -d jni -classpath [class路勁]
com.hodi.hodi_opencv.OpenCVHelper生成.h**
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_hodi_hodi_opencv_OpenCVHelper */
#ifndef _Included_com_hodi_hodi_opencv_OpenCVHelper
#define _Included_com_hodi_hodi_opencv_OpenCVHelper
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_hodi_hodi_opencv_OpenCVHelper
* Method: recognizeIDCard
* Signature: (Ljava/lang/String;Ljava/lang/String;)Z
*/
JNIEXPORT jstring JNICALL Java_com_hodi_hodi_1opencv_OpenCVHelper_recognizeIDCard
(JNIEnv *, jclass, jobject,jstring, jstring);
#ifdef __cplusplus
}
#endif
#endif
- 建立對應.h的實現類.cpp或.c
//
// Created by AA on 2016/11/18.
//
#include "com_hodi_hodi_opencv_OpenCVHelper.h"
#include "IDCardRecognizeUtil.h"
#include <string.h>
#include <Android/log.h>
#include <Android/asset_manager.h>
#include <Android/asset_manager_jni.h>
#define TAG "cn.linjk.ihouse.jni"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__)
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__)
////////////////////////////////////////////////////////////////////////////////
extern "C" {
JNIEXPORT jstring JNICALL Java_com_hodi_hodi_1opencv_OpenCVHelper_recognizeIDCard
(JNIEnv *, jclass, jobject,jstring, jstring);
////////////////////////////////////////////////////////////////////////////
JNIEXPORT jintArray JNICALL Java_com_hodi_hodi_1opencv_OpenCVHelper_gray(
JNIEnv *env, jclass obj, jintArray buf, int w, int h) {
jint *cbuf;
cbuf = env->GetIntArrayElements(buf, JNI_FALSE );//將JNI陣列轉換為基本型別陣列
if (cbuf == NULL) {
return 0;
}
Mat imgData(h, w, CV_8UC4, (unsigned char *) cbuf);
uchar* ptr = imgData.ptr(0);
for(int i = 0; i < w*h; i ++){
//計算公式:Y(亮度) = 0.299*R + 0.587*G + 0.114*B
//對於一個int四位元組,其彩色值儲存方式為:BGRA
int grayScale = (int)(ptr[4*i+2]*0.299 + ptr[4*i+1]*0.587 + ptr[4*i+0]*0.114);
ptr[4*i+1] = grayScale;
ptr[4*i+2] = grayScale;
ptr[4*i+0] = grayScale;
}
int size = w * h;
jintArray result = env->NewIntArray(size);//生成新的陣列
env->SetIntArrayRegion(result, 0, size, cbuf);//為result賦值
env->ReleaseIntArrayElements(buf, cbuf, 0);//釋放記憶體
return result;
}
}
- 執行task ndkBuild,生成.so庫
task ndkBuild(type:Exec, group:'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
}
}
- 在測試類呼叫,呼叫成功即可
package com.hodi.hodi_opencv;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
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;
public class MainActivity extends AppCompatActivity {
private Button btn;
private ImageView img;
private Button btn_id;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
btn= (Button) findViewById(R.id.btn);
img= (ImageView) findViewById(R.id.img);
btn_id = (Button) findViewById(R.id.bt_id_card);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(
R.drawable.im)).getBitmap();
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int[] pix = new int[w * h];
bitmap.getPixels(pix, 0, w, 0, 0, w, h);
int [] resultPixes = OpenCVHelper.gray(pix,w,h);
Bitmap result = Bitmap.createBitmap(w,h, Bitmap.Config.RGB_565);
result.setPixels(resultPixes, 0, w, 0, 0,w, h);
img.setImageBitmap(result);
}
});
}
}