martes, 8 de enero de 2013

Carga de la librería OpenCV en tiempo de ejecución y eventos onResume, onPause y onDestroy (pasos 6 y 7)

Implementar la función de callback de la carga asíncrona de la librería OpenCV

Un cambio importante introducido desde que usaba la versión 2.4.1 a la versión que estamos usando en estos ejemplos, la 2.4.3, ha sido la carga asíncrona de la librería OpenCV. Esto es debido a que ahora las librerías se encuentran concentradas y centralizadas en una aplicación de "Google Play".

La principal ventaja que tiene este nuevo sistema es que las aplicaciones que usan OpenCV ya no son tan pesadas (no contienen todas las librerías OpenCV dentro de ellas para su distribución). Antes tener dos aplicaciones OpenCV instaladas en el móvil requería tener en cada una de ellas las librerías, ocupando el doble de espacio (o el triple si fueran tres aplicaciones las que usan OpenCV).

Por otro lado tenemos la desventaja de que todas aquellas aplicaciones que hayamos desarrollado previamente con OpenCV van a necesitar ciertas modificaciones para que funcionen con las versiones actuales de OpenCV.

En el manual oficial de OpenCV disponemos del proceso de inicialización de la librería y/o instalación de todo lo necesario:

http://docs.opencv.org/android/service/doc/BaseLoaderCallback.html

Crearemos, bajo la definición de "mOpenCvCameraView", una nueva propiedad, que llamaremos "mLoaderCallback", que será la encargada de contener una nueva clase del tipo "BaseLoaderCallback" cuya función es activar la vista "mOpenCvCameraView" cuando la librería OpenCV termine su carga:

 /* Creamos el cargador de OpenCV Manager que usaremos más adelante en OpenCVLoader.initAsync */
 private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS:
                {
                    mOpenCvCameraView.enableView();
                } break;
                default:
                {
                    super.onManagerConnected(status);
                } break;
            }
        }
    };

Al teclear el código anterior se resaltará la clase "BaseLoaderCallback" en rojo indicando que ha aparecido un error. Para solucionarlo pulsamos en "Import 'BaseLoaderCallback' (org.opencv.android)":

Localización archivo activity_main.xml

Por último, en el case, habrá un error en "LoaderCallbackInterface" en rojo indicando que no reconoce la clase cuya propiedad "SUCCESS" intentamos obtener. Para solucionar este error pulsamos en "Import 'LoaderCallbackInterface' (org.opencv.android)":

Localización archivo activity_main.xml

Ahora deberemos programar en "onResume" la inicialización asíncrona de la librería OpenCV. Esto conseguirá que se inicialice no sólo durante la carga inicial de la actividad, si no también cuando la volvamos a poner en primer plano o tras apagar la pantalla del móvil:

    /* Cuando cargue la actividad deberemos realizar una inicialización asíncrona de OpenCV */
    @Override
    public void onResume()
    {
        super.onResume();
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
    }

También aprovecharemos para implementar los métodos onPause y onDestroy para que deshabiliten la vista cuando la actividad pierda el foco, apaguemos la pantalla, etc:

    /* Desactivamos la vista cada vez que la actividad se pause o se destruya */
    @Override
    public void onPause()
    {
        if (mOpenCvCameraView != null) {
            mOpenCvCameraView.disableView();
        }
        super.onPause();
    }
    
    public void onDestroy() {
        super.onDestroy();
        if (mOpenCvCameraView != null) {
            mOpenCvCameraView.disableView();
        }
    }

También aprovecharemos para implementar los métodos onPause y onDestroy para que deshabiliten la vista cuando la actividad pierda el foco, apaguemos la pantalla, etc:

3 comentarios:

  1. Buenas.

    Estoy precisamente ahora comenzando a utilizar OpenCV en entorno Android, aprendiendo a utilizar la biblioteca y a la vez cómo se inserta y utiliza en un proyecto de Android.

    Me he topado con estos posts que son justo lo que necesito, así que te felicito y te animo a que cuanto antes puedas terminar esta serie que has comenzado, para ver cómo se capturan las imágenes desde la cámara y se tratan con OpenCV.

    Ánimo y felicidades!

    ResponderEliminar
    Respuestas
    1. He completado la entrada uniendo el paso 6 con el 7 (el paso 6 requiere de la implementación del onResume, que lo puse en el paso 7 junto con el resto de eventos del ciclo de vida de la actividad).

      Voy a darle un empujón para terminarlo, tengo un seguidor del blog que me pidió implementar un algoritmo, se lo hice, pero no quiero publicar el código de algo sin haber terminado esto :)

      Eliminar
    2. Por cierto, gracias por los ánimos. Voy a ver si avanzo más rápido sin tomar capturas de pantalla, luego subiré el código a mi cuenta de github y, al menos, espero hacer un filtro Canny en Android :)

      Eliminar