Benchmark OpenCV en STM32

Hoy en día, el procesamiento de imágenes se ha convertido en parte de nuestra vida. A nadie le sorprende el reconocimiento de rostros o marcas viales. La biblioteca más común para estos fines en este momento es OpenCV . Hoy OpenCV se centra principalmente en grandes plataformas. Y aunque los modelos más antiguos de microcontroladores modernos tienen recursos comparables a los del Pentium II, ejecutar OpenCV en ellos sigue siendo un fenómeno muy raro, incluso exótico.



Hace algún tiempo, mostramos que existe una posibilidad fundamental de usar OpenCV en STM32(y otros microcontroladores de una clase similar). Entonces, nuestro objetivo era demostrar la posibilidad de utilizar esta biblioteca en plataformas de hardware similares. Por lo tanto, aunque obtuvimos un rendimiento muy bajo, no comenzamos a comprender sus razones. Hasta ahora, hemos solucionado las deficiencias obvias de la primera solución, lo que nos permitió lograr un rendimiento aceptable. Este artículo presenta los resultados de las mediciones de rendimiento para varios ejemplos de uso de OpenCV en la plataforma STM32F7.



Todos los ejemplos dados en el artículo están hechos sobre la base de Embox y se pueden reproducir de forma independiente siguiendo las instrucciones del repositorio con ejemplos . También usamos el indicador de optimización -Os para nuestros ejemplos en el tablero. Todos los ejemplos usan caché habilitado. Las imágenes se pueden ubicar en una tarjeta SD. En los ejemplos, almacenamos las imágenes en un flash QSPI, que se encuentra en la placa de demostración, para obtener instrucciones básicas más simples al reproducir los resultados.



Detección de bordes



Comencemos con el mismo ejemplo que se usó en el trabajo anterior, a saber, la definición de límites. El ejemplo usa el algoritmo de Canny .



Proporcionaremos un registro de la salida al ejecutar la aplicación de bordes en Embox, lo que nos permitirá comparar la mejora del rendimiento en comparación con nuestro trabajo anterior. Para otras aplicaciones, solo proporcionaremos tablas con resultados de medición.



Imagen de muestra para analizar:







Salida para imagen de 512x269



root@embox:(null)#edges fruits.png 20
Image: 512x269; Threshold=20
Detection time: 0 s 116 ms
Framebuffer: 800x480 32bpp
      
      





Salida para imagen de 512x480

root@embox:(null)#edges fruits.png 20
Image: 512x480; Threshold=20
Detection time: 0 s 254 ms
Framebuffer: 800x480 32bpp
      
      







resultados

Imagen tiempo desde ROM (ms) tiempo desde QSPI (ms)
frutas.png 512x269 116 120
frutas.png 512x480 254 260








K-significa



Este ejemplo de la composición de OpenCV, como resultado de su trabajo, debe determinar los grupos de puntos y rodear cada uno de ellos con un círculo del color correspondiente.



Para estimar la densidad de su distribución en OpenCV, se utiliza el concepto de "compacidad":

compacidad: Es la suma de la distancia al cuadrado de cada punto a sus centros correspondientes.




En otras palabras, la compacidad es una medida de qué tan cerca están los puntos del centro del grupo.



Como entrada, kmeans.cpp genera una imagen de 480 x 480 con varios grupos de puntos de diferentes colores. El centro de cada uno de estos grupos se elige al azar y se agregan puntos al grupo de acuerdo con la distribución normal.

Compacidad tiempo desde ROM (ms) tiempo desde QSPI (ms)
733589 34 98
160406 6 Dieciocho
331447 catorce 38
706280 13 36
399182 ocho 25








Cuadrícula



El reconocimiento de formas geométricas, en particular rectángulos, también es un ejemplo estándar en la biblioteca OpenCV.



Imagen de muestra para analizar:







Resultados para imágenes de 400x300:

Imagen tiempo desde ROM (ms) tiempo desde QSPI (ms)
pic1.png 1312 1668
pic2.png 4893 7268
pic3.png 1263 1571
pic4.png 2351 3590
pic5.png 1235 1515
pic6.png 1575 2202








Facedetect



El reconocimiento facial fue el objetivo original de nuestra investigación. Queríamos evaluar qué tan bien funcionan algoritmos similares en tableros similares. Usemos el ejemplo estándar de detección de rostros con un conjunto de cinco imágenes. Los ejemplos utilizan la detección de Haar-cascade (https://docs.opencv.org/4.5.2/db/d28/tutorial_cascade_classifier.html)



Imagen analizada de muestra:







Para imágenes de 256x256:



Imagen tiempo desde ROM (ms) tiempo desde QSPI (ms)
seq_256x256 / img_000.png 3389 3801
seq_256x256 / img_001.png 4015 4454
seq_256x256 / img_002.png 4016 4464
seq_256x256 / img_003.png 3315 3717
seq_256x256 / img_004.png 3526 3952




Para imágenes de 480x480:

Imagen tiempo desde ROM (ms) tiempo desde QSPI (ms)
seq_256x256 / img_000.png 14406 16149
seq_480x480 / img_001.png 14784 16578
seq_480x480 / img_002.png 15106 16904
seq_480x480 / img_003.png 12695 14352
seq_480x480 / img_004.png 14655 16446








Detectar personas



Aumentando la complejidad, decidimos probar cómo funciona la definición de personas en la imagen. Puede usar el ejemplo peopledetect para esto.



Imagen de muestra:







Resultados

Imagen tiempo desde ROM (ms) tiempo desde QSPI (ms)
baloncesto2.png 640x480 40347 52587








Código QR



Los códigos QR son un ejemplo ampliamente utilizado de reconocimiento de patrones.



Un ejemplo de una imagen tomada al azar de Internet:







Resultados

Este ejemplo no cabía en la memoria interna, por lo tanto, los resultados son solo de QSPI

Imagen tiempo desde ROM (ms) tiempo desde QSPI (ms)
qrcode_600x442.png - 3092








Características del trabajo en microcontroladores.



Hay algunos puntos notables que encontramos al trabajar con OpenCV en microcontroladores. Primero, el código de la memoria interna funciona más rápido que el del flash QSPI externo, incluso con la caché habilitada.



El segundo, en nuestra opinión, también relacionado con la caché, es la dependencia del rendimiento de la ubicación del código. Descubrimos que cambios menores en el código, como agregar un comando que no se llama en el algoritmo principal, pueden aumentar o disminuir el rendimiento en un 5 por ciento o más.



En tercer lugar, una cantidad bastante limitada de memoria interna (2 MB). No pudimos ejecutar rápidamente un ejemplo con el reconocimiento de códigos QR desde la memoria interna.



Otra característica importante está relacionada con los núcleos ARM Cortex-M. Usamos kernels con soporte para instrucciones SIMD. Esta tecnología ayuda a aumentar el rendimiento al procesar múltiples instrucciones aritméticas en un solo registro. Para evaluar que esto ayuda para nuestras tareas, realizamos mediciones en Linux con y sin soporte de instrucciones SIMD y encontramos que en algunos ejemplos el uso de SIMD da un aumento de rendimiento del 80%.



Sin embargo, para nuestro procesador, gcc no puede generar código automáticamente usando las instrucciones SIMD. Solo hay soporte en forma de funciones intrínsecas. En otras palabras, debe insertar estos comandos manualmente. OpenCV admite este enfoque. Puede implementar el soporte SIMD para una arquitectura personalizada. Pero por el momento OpenCV está diseñado solo para trabajar con tipos de datos largos (128 bits y más). Por lo tanto, en el marco de este trabajo, no se evaluó la mejora en el rendimiento al usar SIMD en STM32. Esperamos que esta sea una dirección para futuras investigaciones.



Análisis de resultados



Estos resultados indican que un software tan complejo como OpenCV se puede utilizar en microcontroladores. Se lanzaron varios ejemplos y todos funcionaron con éxito. Sin embargo, el rendimiento es notablemente más bajo que el de las plataformas anfitrionas.



El uso de OpenCV en microcontroladores depende en gran medida de las tareas que deben resolverse. La mayoría de los algoritmos básicos funcionan de forma invisible a simple vista. El mismo algoritmo de detección de bordes funcionó en una fracción de segundo, este rendimiento puede ser suficiente para un robot autónomo. Se pueden utilizar algoritmos complejos como el procesamiento de códigos QR, pero es necesario evaluar los pros y los contras de la solución. Por un lado, 3 segundos es mucho para el reconocimiento, pero por otro lado, para algunos fines puede ser suficiente.



Por lo tanto, asumiré que tales plataformas aún no son lo suficientemente poderosas para reconocer objetos complejos, por ejemplo, para identificar a una persona. El retraso es muy notable en comparación con el reconocimiento de la misma imagen en el host. Pero también hay que tener en cuenta el hecho de que se comparó con un intel-i7 de 64 bits con 8 núcleos y una frecuencia fundamentalmente diferente, y, por tanto, el consumo de esta plataforma es completamente diferente. Y además, la comparación no involucró al microcontrolador más poderoso. Incluso el STM32 tiene la serie H7, que es dos veces más potente.



Los resultados se pueden ver en el video.





Reproducción de resultados



Puede reproducir los resultados obtenidos en el artículo. Esto requerirá dos repositorios. El repositorio principal de Embox y el repositorio con imágenes de muestra y configuraciones listas para usar para la placa de descubrimiento STM32F769i . Si sigue las instrucciones del archivo README del repositorio y los ejemplos, puede reproducir los resultados.



También puede usar otras placas, para esto necesita ensamblar la configuración requerida. Alternativamente, puede experimentar con otras imágenes o colocar imágenes en la tarjeta SD, lo que también solo requiere cambiar la configuración de Embox.



PD: Este artículo se publicó por primera vez en inglés en emedded.com.



All Articles