¿Cómo grabar en cámara lenta desde una Raspberry Pi?

Anuncio
RaspberryPi

Los proyectos más populares en una Rapsberry Pi son los que utilizan la cámara PiCam. Desde cabinas para tomar fotos y cámaras web a través de IP hasta sistemas de seguridad y proyectos de visión de computadora. En esta entrada te mostraremos un proyecto ligeramente diferente, que se trata de una cámara de alta velocidad, con la que podrás capturar eventos muy veloces. Para desarrollar este proyecto puedes usar cualquier versión de la PiCam, nosotros preferimos usar la versión de 8MP, pero también puedes usar una anterior o la versión HQ.

Este proyecto fue probado con una Raspberry Pi 3B con una PiCam V1 y V2, con una instalación fresca de Raspberry Pi OS. El proceso general para crear videos de alta velocidad es este:

  • Usar una derivación de Raspiraw para capturar imágenes RAW y guardarlas directamente en la memoria RAM de la tarjeta. Esto se hará a un promedio de 660 FPS, dependiendo de la cámara utilizada.
  • Postprocesar las imágenes capturadas y añadirles un header
  • Usar una derivación de dcraw para convertir las imágenes RAW en archivos .tiff
  • Usar el encoder ffmpeg y los archivos anteriores para producir un video

Configuración

Primero conecta tu PiCam y asegurate que funciona a velocidad estándar con los comandos raspivid o raspistill después instala los siguientes paquetes que serán necesarios para usar dcraw.

sudo apt-get install libjasper-dev libjpeg8-dev liblcms2-dev # required for dcraw.
sudo apt-get install ffmpeg
sudo apt-get install git

Después, clona y compila los repositorios requeridos por dcraw y raspiraw. Los URL de los repositorios que se proporcionan a continuación son ramas sin modificar de los programas mencionados para que sea posible repetir los experimentos sin complicaciones. Los hashes que se usaron son los mismos con los que se probó el funcionamiento del experimento

Anuncio
RaspberryPi
cd ~/
git clone https://github.com/RobertElderSoftware/fork-raspiraw && cd fork-raspiraw && git checkout 18fac55136f98960ccd4dcfff95112134e5e45db
./buildme
cd ~/
git clone https://github.com/RobertElderSoftware/dcraw && cd dcraw && git checkout 8d2bcbe8f9d280a5db8da30af9b6eb034f7f2859
./buildme

Durante la compilación de dcraw, se observó el siguiente mensaje, que puede ser ignorado sin mayor inconveniente

/usr/bin/ld: warning: libjpeg.so.62, needed by /usr/lib/gcc/arm-linux-gnueabihf/6/../../../arm-linux-gnueabihf/libjasper.so, may conflict with libjpeg.so.8

Ahora hay que instalar las dependencias de raspiraw

sudo apt-get install wiringpi
sudo apt-get install i2c-tools

Agrega esta línea en el archivo /boot/config.txt

dtparam=i2c_vc=on

Y la siguiente línea en el archivo de configuración /etc/modules-load.d/modules.conf

i2c-dev

Ahora solo resta reiniciar la Raspberry Pi para que los cambios tengan efecto

sudo reboot now

Grabando un video

Los siguientes pasos muestran el proceso para crear un video simple de 1 segundo en cámara lenta con una ralentización de 50x a una resolución de 640×64. Primero habilitamos la conexión I2C con la cámara con el siguiente comando:

cd ~/fork-raspiraw
./camera_i2c

Ahora con este comando podemos capturar un segundo de imagenes sin procesar, guardándolas en la memoria RAM a 660 FPS

./raspiraw -md 7 -t 1000 -ts /dev/shm/tstamps.csv -hd0 /dev/shm/hd0.32k -h 64 -w 640 --vinc 1F --fps 660 -sr 1 -o /dev/shm/out.%06d.raw

Este comando va a concatenar todos las capturas que tomamos en un solo archivo

ls /dev/shm/*.raw | while read i; do cat /dev/shm/hd0.32k "$i" > "$i".all; done     # add headers

Ahora hay que correr este comando para usar dcraw para convertir cada toma RAW en un archivo .tiff con el cual pueda trabajar el programa ffmpeg

ls /dev/shm/*.all | while read i; do ~/dcraw/dcraw -f -o 1 -v  -6 -T -q 3 -W "$i"; done # Convert to .tiff

Ejecuta este comando para crear el video y para crear un script de python que convierta los datos de tiempo en un archivo util que le permita a ffmpeg mostrar los cuadros en la posición correcta. Nótese que esta es un comando en shell multilínea que tienes que copiar y pegar por completo para que funcione

cat << EOF > /dev/shm/make_concat.py
# Use TS information:
import csv

slowdownx = float(50)
last_microsecond = 0
with open('/dev/shm/tstamps.csv') as csv_file:
  csv_reader = csv.reader(csv_file, delimiter=',')
  line_count = 0
  for row in csv_reader:
    current_microsecond = int(row[2])
    if line_count > 0:
      print("file '/dev/shm/out.%06d.raw.tiff'\nduration %08f" % (int(row[1]), slowdownx * float(current_microsecond - last_microsecond) / float(1000000)))
    line_count += 1
    last_microsecond = current_microsecond
EOF

Ahora corre el script que procesa las marcas de tiempo

python /dev/shm/make_concat.py > /dev/shm/ffmpeg_concats.txt

Y ahora corre ffmpeg para crear el video final

ffmpeg -f concat -safe 0 -i /dev/shm/ffmpeg_concats.txt -vcodec libx265 -x265-params lossless -crf 0 -b:v 1M -pix_fmt yuv420p -vf "pad=ceil(iw/2)*2:ceil(ih/2)*2" /dev/shm/output.mp4

El archivo final de salida se encuentra en /deb/shm/output.mp4. Recuerda copiarlo en otra direccion y borrar el archivo output para que la memoria RAM no tenga problemas de escritura.

Ejemplos

El autor original de este artículo publicó una serie de videos en los que graba una copa de vidrio destruyéndose, monedas cayendo, entre otros videos interesantes. Es importante tomar en cuenta que la iluminación puede ser un poco difícil de ajustar en las primeras capturas debido a que el sensor está ajustando la exposición dinámicamente.

Referencias:

A Guide to Recording 660FPS Video On A $6 Raspberry Pi Camera