Cómo utilizar OpenCV en Android
Cómo usar OpenCV en programas de Android
Hay dos métodos (el énfasis está en el último):
1. Usar la API de OpenCV Java.
Hay dos carpetas en la ruta de instalación de OpenCV "F:\OpenCV-2.3.1-android-bin".
Copia la carpeta "OpenCV-2.3.1". el directorio de su espacio de trabajo de Eclipse. 1 "Carpeta al directorio donde se encuentra el espacio de trabajo de Eclipse, es decir, el directorio anterior del proyecto, luego impórtelo al espacio de trabajo, seleccione el proyecto en el explorador de paquetes, seleccione Propiedades en el menú emergente y haga clic derecho el proyecto, luego, en la ventana emergente de propiedades, abra
en el lado izquierdo de la ventana. En este momento, expanda el árbol del proyecto y podrá ver un nuevo OpenCV-2.3.1_src. Se ha agregado el directorio, como se muestra en la figura siguiente, por lo que se agrega correctamente la API OpenCV Java; de lo contrario, la ruta del directorio donde se coloca OpenCV-2.3.1 es incorrecta.
Entonces, puede importar el. Paquete API OpenCV en el archivo fuente de Java y use la API OpenCV. La forma del paquete API OpenCV es la siguiente:
Org.opencv.(nombre del módulo OpenCV).(nombre de la clase OpenCV)
Por ejemplo:
Org.opencv.core.Mat
2. Utilice JNI para escribir código C++ OpenCV y crear una biblioteca dinámica (.so) a través del NDK de Android.
Cree un nuevo espacio de trabajo, como "TestOpenCV", y créelo en Ventana->Preferencias. El siguiente espacio de trabajo y establezca la ruta al SDK de Android.
Luego cree un nuevo proyecto de Android. seleccione Android 2.2 como destino de compilación, asígnele el nombre "HaveImgFun", cambie el nombre de la actividad a HaveImgFun, complete el nombre del paquete como com.testopencv.haveimgfun y finalmente haga clic en Finalizar
Como con OpenCV. API de Java, copie la carpeta OpenCV-2.3.1 en el mismo directorio que el espacio de trabajo; además, cambie "F.:\OpenCV-2.3.1-android-bin/samples". Copie el archivo includeOpenCV.mk en "The". La ubicación de carpetas y archivos es muy importante porque OpenCV.mk en OpenCV-2.3.1 contiene una gran cantidad de rutas relativas. Si no se coloca de esta manera, es posible que no se encuentren archivos o carpetas al generar bibliotecas dinámicas en NDK. /p>
Seleccione el proyecto en el explorador de paquetes, haga clic derecho y seleccione nueva->carpeta, cree una nueva carpeta llamada jni para almacenar el código c/c++.
Luego cambie el contenido main.xml en res->layout al siguiente contenido:
1 ?
2 3 android:orientation="vertical"? 4 android: layout_width="fill_parent" ? 5 android:layout_height="fill_parent" ? 6 >> 7 8 android:layout_width="fill_parent" ? 9 android:id="@+id/btnNDK" ? 10 android:text="Procesamiento usando C++ OpenCV" /> ? 11
El código anterior es un diseño lineal, que incluye 2 botones y un ImageView que muestra imágenes
Cree una nueva clase en el paquete com.testopencv.haveimgfun en la carpeta src, use p>
Eclipse creará un nuevo archivo LibImgFun.java para usted, cambie el contenido a:
1 paquete com.testopencv.haveimgfun;?
2 clase pública LibImgFun { ?
3 estático { ?
4 System.loadLibrary("ImgFun"); ?
5 }?
6 ? *?
7 * @param width ¿El ancho de la vista actual?
10 public static nativo int[] ImgFun(int[] buf, int w, int h ?
11 }
Del código anterior, podemos saber que el nombre de nuestra biblioteca de enlaces dinámicos debe ser "libImgFun.so", preste atención a la palabra clave nativa en la palabra clave nativa de "public static nativo int [] ImgFun (int [] buf, int w, int h) " , indicando que la función proviene de código nativo.
Cree un archivo "ImgFun.cpp" en la carpeta jni con el siguiente contenido:
1 #include
2 #include
3 #incluir
4 #incluir
5 usando el espacio de nombres cv;
6 ?
7 externo "C"
8 {?
9 JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun(JNIEnv* env, objeto de trabajo, jintArray buf, int w, int h); ?
10 JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun(JNIEnv* env, objeto de trabajo, jintArray buf, int w, int h){? p>11 ?
12 jint *cbuf;?
13 cbuf = env->GetIntArrayElements(buf, false);?
14 if(cbuf = = NULL)?
15 {?
16 devuelve 0;?
17 }?
18 ?
19 Mat myimg(h, w, CV_8UC4, (unsigned char*)cbuf ?
20 for(int j=0;j 21 {? 22 myimg.row(j).setTo(Scalar(0,0,0,0));? 23 }? 24 ? 25 int tamaño=w * h;? 26 jintArray resultado = env->NewIntArray(tamaño);? 27 env->SetIntArrayRegion(resultado, 0, tamaño, cbuf);? 28 env->ReleaseIntArrayElements(buf, cbuf, 0);? 29 devuelve resultado;? p> 30 }? 31 } En el código anterior, #include La función a exportar desde la biblioteca de enlaces dinámicos se declara de la siguiente manera: JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun(JNIEnv* env, jobject obj.jintArray buf, int w, int h) ; JNIEXPORT y JNICALL son palabras clave que deben usarse jintArray es int[], donde el tipo de retorno es nulo o un tipo definido en jni, este último en realidad tiene el prefijo j El tipo C/C++, si es una matriz, agregue Array al final. Las reglas de nomenclatura para los nombres de funciones son las siguientes: Java_(package_path)_(class_name)_(function_name) (JNIEnv *env, jobject obj, parámetros personalizados...) p> El "." en la ruta del paquete reemplaza el "." en el nombre de la clase con "_" (guión bajo) en la ruta del paquete. Es la función de biblioteca de vínculos dinámicos empaquetada anteriormente. el nombre de la clase, y el último es el nombre real de la función; JNIEnv * Los dos parámetros env y jobject obj deben usarse para llamar a ciertas funciones en el entorno JNI. Aquí, jintArray buf representa los datos; de la imagen entrante, int w es el ancho de la imagen e int h es la altura de la imagen. La función de esta función es colorear la parte superior de la imagen de entrada de negro. /p> Luego cree dos archivos "Android.mk" en el archivo jni. "Application.mk". Estos dos archivos son en realidad un archivo Makefile simple. El contenido de Android.mk se modifica. de la siguiente manera: LOCAL_PATH?:=?$(call? my-dir)? ¿incluir?$(CLEAR_VARS)? ¿incluir?... /includeOpenCV.mk? ifeq?("$(comodín ?$(OPENCV_MK_PATH))","")? #intenta?cargar?OpenCV.mk?desde ?ubicación?de?instalación?predeterminada? incluir?$(TOOLCHAIN_PREBUILT_ROOT )/user/share/OpenCV/OpenCV.mk? ¿otro? ¿incluir? /p> endif? LOCAL_MODULE:=? ImgFun? LOCAL_SRC_FILES?:=?ImgFun.cpp? incluir?$(BUILD_SHARED_LIBRARY) ? El contenido de Application.mk se modifica de la siguiente manera: APP_STL:=gnustl_static? APP_CPPFLAGS:=-frtti?-fexceptions? APP_ABI:=armeabi?armeabi-v7a? Donde APP_ABI Especifica la arquitectura de CPU de la plataforma de destino. (Después de pruebas exhaustivas, android2.2 debe especificarse como armeabi, y android2.2 y superiores usan armeabi-v7a. Si no lo configura correctamente, es probable que falle la instalación en la máquina virtual de Android. Por supuesto , también debes escribir arriba Eso es todo) Después de completar los pasos anteriores, puede usar NDK para generar una biblioteca dinámica y abrir cygwin. Abra cygwin y cd en el directorio del proyecto: Ingrese el comando $NDK/ndk-build para comenzar a crear la biblioteca dinámica. Esta vez, al actualizar el Explorador de paquetes de Eclipse se mostrarán dos carpetas nuevas, obj y libs. Ahora sólo queda un último paso para completar el programa de prueba. Coloque una imagen, como "lena.jpg", en el directorio res->drawable-hdpi del proyecto y luego actualice el directorio. Luego cambie el contenido de HaveImgFun.java a: 1 paquete com.testopencv.haveimgfun;? 2 ? 3 importar android.app.Activity; ? 4 importar android.graphics.Bitmap ? 5 importar android.graphics.Bitmap.Config ? 6 importar android.graphics.drawable.BitmapDrawable; ? 7 importar android.os.Bundle ? 8 importar android.widget.Button ? 9 import android.view.View ? 10 import android.widget.ImageView ? 11 ? 12 clase pública HaveImgFun extiende Actividad{ ? p> 11 p> 13 /** Se llama cuando se crea la actividad por primera vez. */ ? 14 ImageView imgView ? 15 Botón btnNDK, btnRestore ? 16 ? 17 @Override ? 18 public void onCreate(Bundle saveInstanceState) { ? 19 super.onCreate(savedInstanceState); ? 20 setContentView(R.layout.main); 21 ? 22 this.setTitle("Conversión de mapas en escala de grises usando NDK"); ? 23 btnRestore=(Button)this.findViewById(R. id.btnRestore); ? 24 btnRestore.setOnClickListener(new ClickEvent()); ? 25 btnNDK=(Botón)this.findViewById(R.id.btnNDK); 26 btnNDK.setOnClickListener(new ClickEvent()); ? 27 imgView=(ImageView)this.findViewById(R.id.ImageView01 ? 28 Mapa de bits img=((BitmapDrawable) getResources().getDrawable(R.drawable.lena)).getBitmap() ? 29 imgView.setImageBitmap(img);
31 ?
32 clase ClickEvent implementa View.OnClickListener{ ?
33 public void onClick(View v){ ?
34 if(v == btnNDK){
35 long current=System.currentTimeMillis(); ?
36 Mapa de bits img1=((BitmapDrawable) getResources(). getDrawable (R.drawable.lena)).getBitmap(); ?
37 int w=img1.getWidth(),h=img1.getHeight() ?
38 int [ ] pix = nuevo int[w * h]; ?
39 img1.getPixels(pix, 0, w, 0, 0, w, h ?
40 int [); ] resultInt=LibImgFun.ImgFun(pix, w, h); ?
41 Mapa de bits resultImg=Bitmap.createBitmap(w, h, Config.RGB_565 ?
42 resultImg . setPixels(resultInt, 0, w, 0, 0,w, h); ?
43 rendimiento largo=System.currentTimeMillis()-current ?
44 imgView.setImageBitmap ( re
sultImg); ?
45 HaveImgFun.this.setTitle("w:"+String.valueOf(img1.getWidth())+",h:"+String.valueOf(img1.getHeight()) +"NDK lleva tiempo"+String.valueOf(rendimiento)+"milisegundos");?
46 } else if(v == btnRestore){ ?
47 Mapa de bits img2=((BitmapDrawable) getResources().getDrawable(R.drawable.lena)).getBitmap ( ?
48 imgView.setImageBitmap(img2); ?
49 HaveImgFun.this.setTitle("Procesamiento de imágenes con OpenCV");
50 } ?
51 }?
52 }?
53 }
Haga clic en Guardar todo, Aceptar, ahora puede seleccionar una ejecución de Android. la máquina virtual para ver los resultados, configure la configuración de ejecución y haga clic en Ejecutar, obtendrá los siguientes resultados:
Haga clic en Procesar con C++ OpenCV, obtendrá los siguientes resultados: