2012-01-27 26 views
9

Estoy usando C++ y OpenCV para procesar algunas imágenes tomadas desde una cámara web en tiempo real y estoy buscando obtener la mejor velocidad posible de mi sistema.Mejorando la velocidad de procesamiento de imágenes

Aparte de cambiar el algoritmo de procesamiento (supongamos, por ahora, que no puede cambiarlo). ¿Hay algo que debería hacer para maximizar la velocidad de procesamiento?

Estoy pensando que quizás Multithreading podría ayudar aquí, pero me da vergüenza decir que realmente no sé los pormenores (aunque obviamente he usado multihilo antes, pero no en C++).

Suponiendo que tengo un procesador x-core, ¿dividir el procesamiento en x hilos realmente acelera las cosas? ... o la carga de administración de estos hilos lo negaría asumiendo que estoy buscando un rendimiento de 20 fps (I supongamos que afectará la respuesta que usted brinde, ya que debería darle una indicación de cuánto proceso se realizará por cada hilo)

¿Ayudaría el multihilo aquí?

¿Hay algún consejo para aumentar la velocidad de OpenCV específicamente, o cualquier trampa en la que pueda estar cayendo que reduzca la velocidad?

Gracias.

+1

Mezclar cada cuadro entrante a un grupo giratorio de hilos debería permitir el subprocesamiento múltiple simple muerto. –

Respuesta

6

La forma más fácil, creo, podría ser operaciones de tramas de canalización

Podría trabajar con un grupo de subprocesos, asignando secuencialmente un búfer de memoria de trama al primer subproceso disponible, que se lanzará al grupo cuando se completa el paso de algoritmo en el fotograma asociado.

Esto podría dejar prácticamente sin cambios el algoritmo actual (depurado :), pero requerirá una cantidad de memoria considerablemente mayor para almacenar los resultados intermedios.

Por supuesto, sin detalles sobre su tarea, es difícil decir si esto es apropiado ...

3

A menos que el algoritmo particular que está utilizando ya esté optimizado para una plataforma multiproceso/paralelo, lanzarlo a un procesador x-core no hará nada por usted. El algoritmo tiene que ser intrínsecamente modificable para beneficiarse de múltiples hilos. Pero si no fue diseñado con eso en mente, tendría que ser alterado. Por otro lado, muchos algoritmos de procesamiento de imágenes son "embarazosamente paralelos", al menos en concepto. ¿Puedes compartir más detalles sobre el algoritmo que tienes en mente?

+0

Bueno, en este momento estoy usando algoritmos estándar de OpenCV para "completar el vacío" de procesamiento. (¿Están multiproceso/optimizado por cierto?) ..... No he decidido realmente el algoritmo que voy a utilizar, pero probablemente será un análisis píxel por píxel que puedo dividir en x subprocesos si es necesario y hacer que todos devuelvan un resultado. – Cheetah

+0

Algoritmos implementados en código. El código es intrínsecamente seguro para subprocesos, por lo que depende de los datos. –

+0

@MartinJames, el código es * principalmente * seguro para subprocesos: debe evitar las variables estáticas variables en su código. –

4

Suponiendo que tengo un procesador x-core, ¿dividir el procesamiento en x hilos realmente acelera las cosas?

Sí, aunque depende en gran medida del algoritmo particular que se utilice, así como su habilidad para escribir código enhebrado para manejar cosas como la sincronización. Realmente no proporcionó suficientes detalles para hacer una mejor evaluación que eso.

Algunos algoritmos son extremadamente fáciles de poner en paralelo, como los que tienen la forma:

for (i=0; i < DATA_SIZE; i++) 
{ 
    output[i] = f(input[i]); 
} 

para alguna función f. Estos se conocen como vergonzosamente paralelizables; simplemente puede dividir los datos en N bloques y hacer que N hilos procesen cada bloque individualmente. Bibliotecas como OpenMP hacen que este tipo de enhebrado sea extremadamente simple.

5

Hay una cosa importante sobre el aumento de la velocidad en OpenCV no relacionado con el procesador ni el algoritmo, y es evitando la copia adicional al tratar con matrices. Le daré un ejemplo tomado de la documentación:.

" ... mediante la construcción de una cabecera para una parte de otra matriz que puede ser una sola fila , sola columna, varias filas, varias columnas, rectangular región en la matriz (llamada menor en álgebra) o una diagonal. Tales operaciones también son O (1), porque el nuevo encabezado hará referencia a los mismos datos . Puede modificar una parte de la matriz usando esta característica , p.ej"

// add 5-th row, multiplied by 3 to the 3rd row 
M.row(3) = M.row(3) + M.row(5)*3; 

// now copy 7-th column to the 1-st column 
// M.col(1) = M.col(7); // this will not work 
Mat M1 = M.col(1); 
M.col(7).copyTo(M1); 

Tal vez ya conocían este tema, pero creo que es importante destacar cabeceras en OPENCV como una herramienta de codificación importante y eficiente.

2

Si sus hilos pueden funcionar con diferentes datos, parecería razonable para enhebrar si fuera poco, tal vez haciendo cola cada cuadro objetar a un grupo de subprocesos Puede que tenga que agregar números de secuencia a los objetos de trama para asegurarse de que los fotogramas procesados ​​que salen del grupo se entreguen en el mismo orden en que ingresaron.

1

Como código de ejemplo para el procesamiento de imágenes de subprocesos múltiples con OpenCV, es posible que desee de revisar mi código:

https://github.com/vmlaker/sherlock-cpp

es lo que ocurrió con el deseo de tomar ventaja de la CPU x-core para mejorar el rendimiento de detección de objetos. El programa detect es básicamente un algoritmo paralelo que distribuye las tareas entre múltiples hilos, un hilo pipeline separado para cada tarea:

  1. Asignación de memoria de cuadros y captura de vídeo.
  2. Detección de objetos (un hilo por cada clasificador Haar)
  3. Aumentando la salida con el resultado de la detección y mostrando el marco.
  4. Desasignación de memoria.

Con memoria para cada cuadro capturado compartido entre todos los hilos, obtuve un gran rendimiento y utilización de la CPU.

+0

gracias por el código – CapelliC

Cuestiones relacionadas