Mejora del rendimiento de OpenCV Android: seguimiento rápido de objetos

Estoy intentando implementar una aplicación de seguimiento de objetos rápida en Android

Mi lógica es la siguiente

  1. Quite todos los colores excepto el rango de color deseado.
  2. Imagen suave usando GaussianBlur
  3. Encuentre el círculo de mayor radio con HoughCircles

El tipo de aplicación funciona bien, pero el rendimiento es malo y me gustaría acelerar mi rendimiento al menos 5 veces más rápido. Tomé prestada mucha de la lógica de este acoplamiento.

Ejemplo de seguimiento rápido de objetos

public void apply(Mat src, Mat dst) { Mat mIntermediateMat = new Mat(src.rows(), src.cols(), CvType.CV_8UC1); Mat mHsv = new Mat(src.size(), CvType.CV_8UC3); Mat mHsv2 = new Mat(src.size(), CvType.CV_8UC3); Imgproc.cvtColor(src, mHsv, Imgproc.COLOR_RGB2HSV, 3); Core.inRange(mHsv, new Scalar(0, 86, 72), new Scalar(39, 255, 255), mHsv); // red Core.inRange(mHsv, new Scalar(150, 125, 100), new Scalar(180,255,255), mHsv2); // red Core.bitwise_or(mHsv, mHsv2, mHsv); /// Reduce the noise so we avoid false circle detection Imgproc.GaussianBlur(mHsv, mHsv, new Size(7, 7), 2); Imgproc.HoughCircles(mHsv, mIntermediateMat, Imgproc.CV_HOUGH_GRADIENT,2.0,100); int maxRadious = 0; Point pt = new Point(0,0); if (mIntermediateMat.cols() > 0) { for (int x = 0; x < mIntermediateMat.cols(); x++) { double vCircle[] = mIntermediateMat.get(0,x); if (vCircle == null) break; int radius = (int)Math.round(vCircle[2]); if (radius > maxRadious) { maxRadious = radius; pt = new Point(Math.round(vCircle[0]), Math.round(vCircle[1])); } } int iLineThickness = 5; Scalar red = new Scalar(255, 0, 0); // draw the found circle Core.circle(dst, pt, maxRadious, red, iLineThickness); } } 

He estado pensando en maneras de aumentar mi rendimiento y me gustaría asesoramiento sobre lo que es probable que sea viable y significativo.

1) Uso de Multi Threading. Podría usar un hilo para capturar desde la cámara y otro para procesar la imagen. De OpenCV Android Notas de la versión veo "Habilitado multi-threading apoyo con TBB (sólo unas pocas funciones están optimizadas en este momento." Sin embargo, no entiendo esto. ¿Es TBB sólo para chips Intel? ¿Qué funciones están disponibles? ¿Existen ejemplos relevantes para Android y OpenCV?

2) Uso de un dispositivo Android más potente. Actualmente estoy corriendo en un Nexus 7 de 2012, usando la cámara frente a frente. Realmente no estoy muy clued sobre qué especificaciones son importantes para mí. Nexus 7 (2012) tiene una CPU Nvidia Tegra 3 de quad-core de 1,3 GHz; 416MHz Nvidia GeForce ULP GPU.

Si fuera a ejecutar en el teléfono Android más rápido en la actualidad, ¿cuánta diferencia haría?

Qué especificaciones son las más relevantes para este tipo de aplicación

  1. UPC.
  2. GPU.
  3. Numero de nucleos.
  4. Velocidad de fotogramas de la cámara.

3) ¿Utilizar código C ++ nativo impactaría positivamente mi rendimiento?

4) ¿Hay alternativas a OpenCV que podría usar?

    0) Yo perfil (o medir tiempo de ejecución) para todas las funciones que utiliza para comprobar lo que tiene que optimizar y luego planificar la optimización.

    1) Multi-threading puede mejorar la velocidad de fotogramas, pero no un retraso (un núcleo de proceso de un marco en x ms. Usted tiene N núcleos, por lo que tiene N cuadros muy rápido, entonces usted tiene que esperar de nuevo x ms). No estoy seguro acerca de OpenCV, pero por lo que sé, el desenfoque gaussiano y la transformación de Hough no utilizan multicore.

    2) Intel TBB no es sólo para los chips de Intel, la gente lo utiliza para ARMs, así como para los chips de AMD. Ver OpenCV configurar con TBB para ARM (Ubuntu, 3.0.63)

    3-4) Utiliza algoritmos bastante simples, todo puede ser implementado por usted mismo, sin OpenCV. Y OpenCV Hough transformar o borroso Gaussian son bastante rápidos. C ++ es más rápido que Python, pero en términos de "todo el tiempo de ejecución del programa". Python OpenCV es sólo wrappers sobre las bibliotecas C ++, por lo que su rendimiento "solo" es similar.

    En primer lugar, como se dijo antes, el perfil de su código. Android SDK profiler es impresionante, probablemente el mejor de los pocos que he probado.

    Aquí hay algunas cosas que le permitirán ver algunas mejoras:

    • No declare (instancia) las estructuras de datos (Mat, Scalar, Point) dentro de su código de procesamiento (el código que se llama para cada imagen que capture). Trate de reutilizarlos.

    • No es necesario utilizar la escala completa de la imagen para el seguimiento de objetos, puede cambiar el tamaño (escala hacia abajo) cada marco de imagen, o utilizar ROI de imagen: procesar una región más pequeña de la imagen.

    • Su Nexus 7 soporta las optimizaciones OpenCV NEON, son optimizaciones soportadas por el hardware de NVIDIA Tegra. Básicamente se necesita OpenCV compilado con soporte NEON, encontrará documentación si lo busca.

    Editar:

    Debido a que usted mencionó que GaussianBlur es un problema, puede probar otros tipos de desenfoque (mediana, caja normalizada) que son más rápidos y también puede aumentar el tamaño de la ventana deslizante (aka Kernel) (3er parámetro), mayor será el kernel más rápido Pasa por una imagen.

    http://docs.opencv.org/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.html

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.