versiones usar studio for example descargas descarga curso java android opencv java-native-interface opencv4android

java - usar - La forma más eficiente de enviar imágenes en YUV_420_888 desde Android a JNI en OpenCV Mat



usar opencv en android studio (2)

Tengo una aplicación para Android en la que quiero ejecutar un proceso de procesamiento de imágenes OpenCV imágenes en vivo desde la API de Camera2 Android. Actualmente, si no hago ningún procesamiento, puedo recibir imágenes en la función OnImageAvailble a 30 fps para un marco regular de 1280x720 .

Ahora, como un truco sucio, solicito Imágenes de ImageReader en formato JPEG y luego paso el Bitmap a jni que reduce el rendimiento mucho.

¿Cuál es la forma más eficiente de pasar el marco YUV a jni en el objeto cv Mat ? Además, quiero convertir este marco a RGB para su posterior procesamiento. ¿Debo cambiar el formato en el lado de Java o debo pasar el objeto Mat a jni y convertir el espacio de color allí solo?


Tal vez sea útil para usted: ya que hacemos mucho procesamiento de imágenes, escribimos una biblioteca para ese propósito en nuestra empresa. No está escrito en C pero es bastante performante. Después de la conversión, simplemente puede pasar el puntero Mat a su código C a través de JNI.

Convierte YUVs (formato de cámara estándar de Android YUV_420_888) en alfombrillas RGB. Además, también permite un recorte eficiente del YUV antes de la conversión (importante para imágenes muy grandes, de lo contrario, sería necesario convertir toda la imagen y luego recortar, lo que es costoso). El uso es muy simple:

Mat mat = Yuv.toMat(image)

https://github.com/quickbirdstudios/yuvToMat


Todo lo que haga en C ++ es mucho más rápido que el equivalente de Java por razones obvias, incluidas las transformaciones de YUV a RGB (incluso si la implementación de Java se basa en bibliotecas compiladas).

Puede pasar directamente un puntero desde su Mat existente en java directamente a C ++ a través de JNI. Suponiendo que quiero hacer Canny () usando C ++ y JNI, y tengo una función JNI definida de esta manera:

// In Java public static native boolean nativeCanny(long iAddr);

Observe el parámetro iAddr largo , que es un puntero directo a mi Mat en Java. Lo invocas así:

// In Java nativeCanny(myImage.getNativeObjAddr());

La implementación de esta función en C ++ recibiría este puntero de forma similar a esta (reemplace con jlong ​​si esto no funciona):

// In C++ JNIEXPORT jboolean JNICALL VeryLongName_nativeCanny(JNIEnv *env, jobject instance, long iAddr) { cv::Mat* img = (cv::Mat*) iAddr; cv::Canny(*img, *img, 80, 100, 3); return true; }

Y todo lo que le hice al img Mat, también sucede en el java myImage Mat, después de todo es un indicador, por lo que nunca hicimos una copia.

Que yo sepa, eso es lo más rápido que puede ser.