domingo, 3 de mayo de 2015

Tasa de refresco

En las primeras pruebas al representar las imágenes con Python nos encontramos con el problema de que a pesar de que recibíamos varias imágenes tal y como le pedíamos a la cámara a través de Arduino, éstas eran durante varios ciclos del bucle la misma imágen. Aquí se puede ver un ejemplo tomando imágenes sin ninguna espera entre imágenes con un vídeo delante de la cámara.


Tras muchas pruebas se han llegado a las siguientes conclusiones.

  • La cámara es capaz de devolverte imágenes independientemente de el tiempo de espera entre cada imagen. Ahora bien, si no esperas entre cada toma de imagen un cierto tiempo, la cámara te devolverá una imagen, si, pero puede ser la misma imagen que la vez anterior ya que necesita un tiempo de refresco.
  • La cámara, aunque no hayamos esperado el tiempo suficiente para refrescar el frame, si le pedimos que tome otra foto y nos la mande nos responderá con las cabeceras correspondientes de que así se va a hacer, pero la imagen obtenida será la misma en varios ciclos. Esto quiere decir que la cámara ya está preparada para recibir nuevas peticiones, pero sin embargo el proceso de tomar una nueva imagen (en alguno de los pasos del proceso) no.
  • Es necesario realizar una espera entre cada toma de imagen para que la cámara se refresque, por lo que se ha probado con el código antes comentado, descomentando la línea que realiza una espera fija (delay(X);). Probando diferentes valores de X se ha llegado a la conclusión de que cuanto menor es la espera (X tiende a 0), mayor es el número de frames en los que la cámara envía la misma imagen. Sin embargo, si ponemos que X>=33 (milisegundos) los frames que obtenemos son siempre diferentes.

De las hipótesis manejadas la que más plausible nos ha parecido es pensar que esto se debe al software de la cámara y el comportamiento que establece. Se cree que en la primera imágen, puesto que la cámara aún no ha tomado ninguna imágen, hace una llamada bloqueante que no acaba hasta que ha terminado de tomar y procesar la imagen a JPEG, y obtenemos el primer frame. Sin embargo, para las peticiones sucesivas, se hacen 2 cosas, mandar orden de hacer foto y mandar orden de transmitir los datos. Al no haber ninguna espera entre estos 2 comandos y la cámara tener una imagen ya en memoria, al solicitarle datos del JPEG, la cámara nos devuelve la imagen que detecta que tiene en memoria (la del frame anterior) ya que aún no le ha dado tiempo a tomar el siguiente frame (necesita un tiempo para tomar la imagen de los sensores y hacer el procesado para pasar a JPEG). Esto ocurre durante varios ciclos, ya que el único momento que tiene la cámara para procesar la nueva imagen es el intervalo en el que arduino a recibido todos los datos y aún no le ha pedido la siguiente imagen (que son unos milisegundos en lo que tarda en volver al bucle). Durante ese periodo, continua el procesado del JPEG y cuando lo termina nos comienza a dar la nueva imágen.

Por todo lo anterior, la aproximación con un mejor rendimiento ha sido establecer una comunicación entre arduino y python para que el primero no pida una nueva imagen a la cámara hasta que el segundo no se lo diga. De esta forma podemos controlar la tasa de refresco con la espera que se utiliza para mostrar un frame en pantalla durante un tiempo (waitKey de OpenCV). De esta forma, hay que añadir al código de python y arduino la lógica bloqueante para la espera de intercambio de mensajes.

No hay comentarios:

Publicar un comentario