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.