android开发在jni中使用Opencv进行图像处理,环境搭建篇

来源:互联网 发布:c盘里面windows.old 编辑:程序博客网 时间:2024/06/10 16:56

1、准备工作:

                        (1)JDK——官网下载:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html,添加系统环境变量,网上教程很多。。

                        (2)Eclipse+ADT——官网下载:http://developer.android.com/sdk/index.html  ,但本人倾向于22.3.0版本的。

                        (3)NDK——官网下载最新window x86或是window x86_64,自行选择:http://developer.android.com/tools/sdk/ndk/index.html

                        (4)OpenCV-2.4.8——官网下载:http://sourceforge.net/projects/opencvlibrary/files/opencv-android/(提醒:OpenCV-2.4.9测试过是不行的,想办法下载OpenCV-2.4.8版本)

2、建立一个Android应用程序:取名Time

3.

右键单击项目名称新建文件夹jni,在jni中新建三个文件,分别是time.cpp      Android.mk          Application.mk ,如图所示

        

4、在time中添加如下代码:

#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

jdouble duration;
extern "C"{
JNIEXPORT jintArray JNICALL Java_com_example_time_MyClass_sobel(
               JNIEnv* env, jobject obj, jintArray buf, int w, int h){
  jint* cbuf;
  cbuf = env->GetIntArrayElements(buf, NULL);
  if (cbuf == NULL) {
    return 0;
  }
  int size = w * h;
     int i=0;
     Mat myimg4(h,w,CV_8UC4,(uchar*) cbuf);
     Mat myimg3(h,w,CV_8UC3);
     for(i=0;i<size;i++)//四通道myimg4->三通道myimg3
    {
     myimg3.data[3*i]  = myimg4.data[4*i];
     myimg3.data[3*i+1]= myimg4.data[4*i+1];
     myimg3.data[3*i+2]= myimg4.data[4*i+2];
    }

     duration=static_cast<double>(getTickCount());
         Mat Ca;
   Canny(myimg3,Ca,50,150,3);
  duration=static_cast<double>(getTickCount())-duration;
  duration/=getTickFrequency();

  int j=0;
  int *outImage=new int[w*h];
     for(i=0;i<Ca.rows;i++)//输出最终图像
    {
     uchar*data=Ca.ptr<uchar>(i);
     for(j=0;j<Ca.cols;j++)
     outImage[i*Ca.cols+j]=255-data[j]<<16 | 255-data[j]<<8 | 255-data[j];
    }
     jintArray result = env->NewIntArray(size);
  env->SetIntArrayRegion(result, 0, size, outImage);
  env->ReleaseIntArrayElements(buf, cbuf, 0);
  return result;
}
JNIEXPORT jdouble JNICALL Java_com_example_time_MyClass_time(
  JNIEnv* env, jobject obj){
  return duration;
}
}

5、在Android.mk中添加如下代码:

LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS) 

OPENCV_INSTALL_MODULES:=on
OPENCV_CAMERA_MODULES:=off
OPENCV_LIB_TYPE:=STATIC
 
include F:\Backup\ADT\OpenCV-2.4.8\sdk\native\jni\OpenCV.mk 
//这是我 下载的Opencv-2.4.8中的OpenCV.mk文件的存放位置,用于对Opencv布局。

LOCAL_MODULE    := time 
LOCAL_SRC_FILES := time.cpp 

include $(BUILD_SHARED_LIBRARY)

 

6、在Application中添加如下代码:

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

7、在本项目包com.example.time下新建一个类MyClass如下:

并按右图添加代码。

 8、在MainActivity.java中添加如下代码:

package com.example.time;

import android.os.Bundle;
import android.view.View;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.drawable.BitmapDrawable;
import android.view.Menu;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

 ImageView imgView;
    Button btnNDK, btnRestore;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  this.setTitle("使用C++ OpenCV处理图像");
     btnRestore = (Button) this.findViewById(R.id.btnRestore);
     btnRestore.setOnClickListener(new ClickEvent());
     btnNDK = (Button) this.findViewById(R.id.btnNDK);
     btnNDK.setOnClickListener(new ClickEvent());
     imgView = (ImageView) this.findViewById(R.id.ImageView01);
     Bitmap img = ((BitmapDrawable) getResources().getDrawable(
         R.drawable.airplane)).getBitmap();
     imgView.setImageBitmap(img); 
 }
 class ClickEvent implements View.OnClickListener{
  public  void onClick(View v){
   if(v==btnNDK){
    Bitmap img1=((BitmapDrawable)getResources().getDrawable(
      R.drawable.airplane)).getBitmap();
    int w=img1.getWidth(),h=img1.getHeight();
    int[] pix=new int[w * h];
    img1.getPixels(pix, 0,w,0,0,w,h);
    int[] sobel=MyClass.sobel(pix, w, h);
    double duration=MyClass.time();
    Bitmap bit_sobel=Bitmap.createBitmap(w,h,Config.RGB_565);
    bit_sobel.setPixels(sobel,0,w,0,0,w,h);
    imgView.setImageBitmap(bit_sobel);
    MainActivity.this.setTitle("Canny耗时为:"+String.valueOf(duration));
   }
   
   if(v==btnRestore){
    Bitmap img2=((BitmapDrawable)getResources().getDrawable(
      R.drawable.airplane)).getBitmap();
    imgView.setImageBitmap(img2);
    MainActivity.this.setTitle("使用OpenCv进行图像处理");
   }
  }
 }
 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.main, menu);
  return true;
 }

}

 

9、在布局文件activity_main,xml中添加如下代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout   xmlns:android="
http://schemas.android.com/apk/res/android"
      android:orientation="vertical"
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent">

     <Button android:layout_height="wrap_content" 
         android:layout_width="fill_parent" 
         android:id="@+id/btnNDK" 
         android:text="使用C++ OpenCV进行处理" />     
     <Button android:layout_height="wrap_content" 
         android:layout_width="fill_parent" 
         android:id="@+id/btnRestore" 
         android:text="还原" /> 
     <ImageView android:layout_height="fill_parent"
         android:layout_width="fill_parent" 
         android:id="@+id/ImageView01" />     

</LinearLayout>

 

10、右键单击项目名Time,新建,选择最后一项other,然后选择如下:Convert to a C/C++ Project(Adds C/C++ Native)

(这样做是给该项目添加C属性),单击Next,然后选择项目Time,单击finish即可。


11、右键单击项目Time,然后选择属性:

 

 

 12、C的环境变量中添加ndk的根目录:

 

 13、将C的编译器改到ndk-build.cmd

14、在C/C++常规操作项下的Paths and Symbols中的GNU C++中添加C、C++、Opencv-2.4.8的库文件:(下面是我个人的路径,你按照你的路径改一改就可以了)

 

至此OPencv库已经导入,C++编译器也已经配置完成。

 

15、下一步新建一个Android程序编译器对整个程序进行编译:

右键单击项目Time属性,选择Builders,然后新建program

 

 

我们可以看到新建的New_Builder(2),其实之前我已经新建了一个New_Builder,所以New_Builder(2)只是做一次示范,我们应该将新建的builders  Up到最上端,如图中的New_Builder。

 

16、下面运行程序,右键单击项目Time,选择Run As中的第一个,如下:

 

17、在模拟器中可以看到运行时间及Canny的结果图:

 

 

0 0
原创粉丝点击