el 09-24-2012 08:18 AM
Hola!
Estoy programando una aplicación en la que se realiza una adquisicion de imágenes a alta velocidad (500 fps e incluso más en un futuro). Tengo la aplicación dividida en pluggins por funcionalidad, ya que es bastante extensa.
Para pasar las imágenes de un vi a otro utilizo una cola de imágenes, de manera que en un vi se adquieren y pasan a otro para ser analizadas. Dicho análisis es bastante más lento que la adquisicion asi que se acumulan bastantes imágenes en la cola. Hasta ahora había encolado referencias a la imagen, pero tengo motivos para pensar que esas referencias se sobreescribn de alguna manera, ya que cuadno se supone q se estan analizando imagenes acumuladas en la cosa, estas imagenes muestran sucesos en tiempo real a psear de que ya no se están actualizando los elementos de la cola, sino analizando los restantes.
Decidí enviar las imagenes en strings en lugar de sus referencias, ya que leí en algun foro que podrían darse race conditions en caso de que se liberara dicha referencia antes de procesarla.
Para ello utilizo la funcion Imaq flatten to string antes de encolarla, sin ningun tipo de compresion y unflaten to string en el destino. Se produce un aumento inviable en el cinsumo de la Ram, incluso llegando a las 15gb que además luego tras el análisis no se liberan.
¿Desecho directamente esta opción? ¿Realmente puede liberarse una referencia a una imagen antes de procesarla? ¿q enfoque me recomendais?
Gracias
el 09-24-2012 10:41 AM
Hola,
Lo primero que tienes que pensar es que si adquieres imagenes de forma constante y no eres capaz de procesarlas tan rapido como las adquieres, en algun lugar vas a tener un buffer con la cola de imágenes que eventualmente se va a desbordar. Te recomiendo medir a que velocidad haces el procesamiento de una imagen a ver si alcanzas los 500 fps, o sino analizar si puedes adquirir cierta cantidad de imagenes por un periodo de tiempo y luego procesarlas.
Suponiendo que solo adquieres rafagas por periodos determinados de tiempo o que tu procesamiento si es lo suficientemente rápido:
Las referencias no se deberían liberar a menos que tu las cierres o cierres el VI donde se crearon. El hecho de que digas que estas viendo sucesos en tiempo real me hace pensar que no estas creando una referencia para cada imagen, sino que estas usando siempre la misma referencia, prueba creando dos referencias y hazle un typecast a int y verifica si efectivamente son diferentes o la misma.
Respecto a pasarlas como string, pues 15Gb en RAM suena como bastante, es probable que en el proceso estes descomprimiendo la imagen de jpeg a un bitmap bmp, o algo similar, si ya la tienes comprimida no vale la pena que la descomprimas hasta que la vayas a procesar, sino esta comprimida tienes que evaluar si puedes comprimirla sin perder información útil. Si las imagenes son pesadas es probable que no puedas manejar todo el buff en la RAM y tengas que guardarlas en disco duro a través de un archivo por ejemplo, el acceso a disco duro es siempre mas lento, en caso de que te haga falta y no te alcance la velocidad con un disco convencional puedes hacer los calculos usando un disco duro de estado solido (SSD) y ver si te es factible.
Te recomiendo que revises lo de las referencias, y nos digas mas información como la resolución de las imágenes, si están comprimidas en algun formato, y que tanto demora tu procesamiento de una imagen.
Saludos Cordiales,
el 09-25-2012 01:24 AM
Buenos días!
Lo primero, muchas gracias por contestar tan rápido. Lo de las referencias me parece lo más lógico, algo raro tengo que estar haciendo, voy a revisarlo.
De momento te cuento, efectivamente el proceso de imágenes se hace a ráfagas a peticion de usuario y mi intentcion en un futuro es implementar el procesamiento de imagenes mediante CUDA para llegar a procesar a velocidad de adquisicion si fuera posible, pero de momento lo extraigo del buffer a la cola (q en principio esta sería la que actuara como buffer temporal hasta que fueran procesadas), de hecho tengo dos colas, una de comunicacion de vi's y otra como almacenamiento temporal en el vi de destino (probé debido a los fallos y me sorprendió que aumentara el rendimiento), de manera que al determinar el usuario que el análisis de imágenes ha terminado, las almacenadas en la cola serían analizadas hasta vaciarla.
Adjunto un pantallazo de la inicializacion de la adquisicion donde se crean las imágenes (imaq create) creo que es a eso a lo que te refieres no?
Por si vieras algo, de todas maneras yo hago el typecast, o con un probe normal valdría no?
Gracias!
09-25-2012 04:36 AM - editado 09-25-2012 04:40 AM
Hola!
Efectivamente en la cola tengo referencias repetidas, el tamaño del buffer que me cree es de 100, pero en la cola se acumulan más de 100... bastantes más. No había caído que son referencias a posiciones de memoria lo que se encola y no la imagen en sí, entonces a pesar de q tenga en la cola 3000 elementos, tan solo tengo 100 referencias repetidas, supongo.
El enfoque de comprimir las imágenes no creo que sea viable, ya que comprimir implica una pérdida de información y el trabajo que realizo la diferencia de intensidades entre pixeles es muy importante, asi q no creo que deba hacerlo. Yo utilizaba el vi de Imaq con compresion "none" pero claro las imagenes pesaran un montón, y a 500fps...
Las imágenes son de 1028X1024 transferidas mediante full camera link con 700/160 MB/seg, modelo EoSens MC1362
¿Alguna idea a parte de usar el disco duro como almacenamiento?
Gracias!
el 09-25-2012 07:46 AM
Estoy bastante confusa en este punto.... Si hago un typeCast a int me da el mismo valor imágenes con nombres distintos salidas directamente del vi extract buffer... ¿Esto que significa? Pensaba que si tenian nombres distintos serían entradas distintas al buffer list y por lo tanto referencias a posiciones de memoria distintas...
![]()
el 09-25-2012 10:30 AM
Hola,
1028x1024 = 1052672 pixeles, si usas para cada pixel una codificacion ARGB son 4 bytes por pixeles, que te dan 4210688 bytes, aproximadamente 4Mb por imagen, a una tasa de 500 fps en un segundo tendras 500*4Mb que son aproximadamente 2GB de datos por segundo, alli queda de tu parte definir cuanta memoria puedes manejar y limitar el tiempo de captura o ir sobreescribiendo las imagenes.
En cuanto a las referencias, es un identificador a un objeto, dos objetos diferentes que sean del mismo tipo tienen referencias diferentes, es decir, si creas dos controles/indicadores iguales cada uno tendra su propia referencia. Puede verse como algo similar a un apuntador, pero no es exactamente lo mismo, recuerda que LabVIEW es un lenguaje de alto nivel y es el mismo quien se encarga de gestionar la memoria, similar como ocurre con Java y .NET.
No he trabajado con los modulos de IMAQ por lo que se me hace dificil entender que hace tu VI con la imagen que colocaste, me gustaria saber que nombre tiene la referencia que tienes alli, porque tal vez no sea una referencia a la imagen sino a la conexion que tienes con la camara o tal vez una referencia al buffer que usas que contiene las 100 imagenes.
Si haces el typecast a int y te dan el mismo valor, una asegurate de poner el indicador lo suficientemente grande puede ser que estes ocultando los digitos menos significativos donde son diferentes, si revisas eso y son exactamente igual significa que ambas referencias se refieren al mismo objeto, por lo que deberias ver si hay una manera de generar referencias distintas a cada imagen o sino buscar alguna alternativa como crear tu objetos imagenes diferentes donde hagas una copia de los que vas adquiriendo y pases esas referencias que tu misma crees (es una idea, no se que tan factible o no pueda ser).
Espero ser de ayuda, cualquier prueba o avance avisame, igual no dejes de revisar en los restos de los foros en ingles que muchas veces alguien ya ha tenido algun problema similar.
Saludos Cordiales,
el 09-26-2012 06:02 AM
Se supone que Imaq Create.vi, hace una reserva de memoria para una imagen, y has de darle a cada una un nombre distinto, claro ,sobre las referencias es raro que todas estas reservas de memoria tengan la misma referencia, igual el type cast no da este resultado en este caso. Sin hacer el cast a int detecta también que hay imágenes iguales y coincide con las que se llaman igual, asi que parece un resultado más acertado, aunque el problema sigue siendo el mismo, que se sobreesccriben las imagenes.
Estaba pensando en implementar yo misma otra estructura adicional, de manera que en esta estructura de tamaño fijo se almacenara una copia de la imagen y un flag "Procesada", de manera que tras la adquisicion de la imagen se inserte en la primera posicion libre de la estructura auxiliar (comprobando el flag de cada posicion y marcando el buffer a "pendiente d proceso") y tras ser analizada dicho flag se pondrá a libre otra vez (procesada). Para respetar el orden de las imágenes deberá ser una estructura tipo fifo. estaba pensando un array de cluster (imagen,flag). ¿Q te parece?
gracias!
el 09-26-2012 09:56 AM
Hola,
Pues tu sabes mas de IMAQ que yo, y sabes que quieres lograr, asi que tu eres la experta jejeje ... Lo que dices suena razonable, la cosa es que una vez que llenes el buffer la adquisición va a dejar de ser a 500 fps sino que va a ser a la velocidad que liberes los espacios para almacenar una nueva imagen. Yo te diria que una vez que llenes el buffer detengas la adquisición hasta que se vacie por completo y luego la vuelvas a iniciar, asi garantizas que aunque sea por intervalos cortos de tiempo tengas los 500 fps, claro eso si necesitas 500 fps.
Saludos,
el 09-27-2012 02:19 AM
Jejeje, tengo un lio montado... 😜
Pues lo q necesito es que durante igual 10-15m que dura un experimento es que se adquiera a 500fps y q no sepierdan imágenes, asi q tengo que conseguir esto.... Voy a ver como me las apaño, os contaré!
el 09-27-2012 09:19 AM
Hola,
Como yo lo veo, tienes esto:
10min * 60seg/min * 500 imagenes/seg = 300.000 imagenes.
A 4Mb cada imagen son 1200 GB, osea que o lo procesas a 500 fps o lo guardas en un disco duro SSD (q de esa capacidad cuesta bastante).
De todas formas yo no soy un experto, trata de hablar con alguien con experiencia en el tema a ver si te da otras opciones.
Ya mediste a que velocidad estas procesando las imagenes?
Saludos,