Toma la foto de la cámara desde la cáscara con un retraso mínimo

2

Estoy buscando una herramienta de línea de comandos que pueda tomar una foto de una cámara web tan rápido como sea posible y escribelo a la salida estándar. Además, me gustaría poder especificar configuraciones como el formato de entrada, la resolución y el formato de salida.

Mi primer intento fue ffmpeg:

ffmpeg -f video4linux2 -video_size 1920x1080 -input_format yuyv422 -i /dev/video0 -f image2 -frames:v 1 -qscale:v 2 pipe:1

Sin embargo, esto tiene dos inconvenientes:

  1. Se tarda unos 3 segundos hasta que la imagen se escribe en la salida estándar, lo que parece deberse al tiempo que la cámara web necesita para iniciarse.

  2. La imagen tomada de esta manera es bastante oscura, probablemente la cámara web necesite capturar los fotogramas de un video para ajustar el brillo, etc.

Mi siguiente idea es capturar continuamente los cuadros de video de la cámara web (es decir, "mantener la cámara web activa"), transmitir estos cuadros de video algun lado y, a continuación, tome fotogramas de vídeo individuales y conviértalos en una imagen bajo demanda. Sin embargo, no sé cómo hacer esto (y si hay una manera mejor).

EDITAR: Necesito un comando único que escriba la imagen en la salida estándar, por lo que puedo usarlo en un servidor http para servir una solicitud GET de http. Debe ser rápido, porque tomar la fotografía está bloqueando un proceso mecánico en una máquina.

x-ray
fuente

Respuestas:

3

Para mi webcam, fswebcam Toma una foto en menos de medio segundo:

$ time fswebcam test1.jpg
...
real    0m0.491s
user    0m0.024s
sys     0m0.000s

Se tarda un poco más en escribir en la salida estándar y luego guardarlo:

$ time fswebcam - > test2.jpg
...
real    0m0.538s
user    0m0.029s
sys     0m0.000s

También puedes tomar imágenes cada norte segundos ( --loop n ), si esto es lo que necesitas (no explicaste por qué lo desea lo más rápido posible, y si un bucle puede ayudarlo, o cómo lo puede ayudar.

Puede iluminar la imagen o ajustar el contraste, etc. con los controles que se muestran con fswebcam --list-controls.

dirkt
fuente
1
Para el "retraso mínimo", también puede enviar la señal SIGUSR1 a fswebcam para que se capture de inmediato, cuando esté en modo de bucle temporizado.
meuh
Gracias Dirkt y @meuh. Actualicé mi pregunta para explicar por qué necesito esto. Ahora veo que mi cámara web es simplemente lenta al obtener la primera imagen. Veré si usar fswebcam con la opción de bucle en combinación con SIGUSR1 ayuda. Encontré otra solución (la publicaré aquí), pero tampoco es óptima (baja las cámaras).
x-ray
1

Yo mismo encontré una solución posible, aunque no es óptima, porque en la Raspberry Pi, donde quiero implementar esto, reduce el FPS a la mitad del valor que admite la cámara (y un menor FPS = mayor retardo posible hasta el próximo cuadro de video que puede extraerse como imagen).

Uso ffmpeg para copiar los datos de video desde el dispositivo de hardware en / dev / video0 a un v4l2-loopback dispositivo en / dev / video1. De esta manera, la cámara se mantiene activa porque ffmpeg está leyendo en / dev / video0, mientras que puedo usar otra instancia de ffmpeg para extraer imágenes de / dev / video1.

Para instalar v4l2-loopback en Raspbian GNU / Linux 9 (extensible):

  1. Instalar encabezados del kernel: apt-get install raspberrypi-kernel-headers ( Re: Cómo instalar encabezados de kernel )
  2. Instalar v4l2-loopback: apt-get install v4l2loopback-dkms ( Distribuciones v4l2-loopback )
  3. Añadir dispositivo de bucle invertido: modprobe v4l2loopback o con mas dispositivos modprobe v4l2loopback devices=2 ( v4l2-loopback run )

Para copiar el video de / dev / video0 a / dev / video1:

 ffmpeg -f video4linux2 -video_size 1920x1080 -input_format yuyv422 -i /dev/video0 -codec copy -f video4linux2 /dev/video1

Mi cámara es compatible con los formatos mjpeg y yuyv422, pero solo se puede copiar un formato "en bruto" al dispositivo de bucle de retorno, por lo que debo usar yuyv422. La cámara admite hasta 6 fps con yuyv422 y 1920x1080, pero la Raspberry Pi 2 Model B solo logra copiar aproximadamente 3 fps al dispositivo de bucle invertido.

Ahora puedo usar el comando que ya mencioné en la pregunta para extraer las imágenes, como JPEG:

ffmpeg -f video4linux2 -video_size 1920x1080 -input_format yuyv422 -i /dev/video1 -f image2 -frames:v 1 -qscale:v 2 pipe:1

O como mapa de bits:

 ffmpeg -f video4linux2 -video_size 1920x1080 -input_format yuyv422 -i /dev/video1 -c:v bmp -f image2 -pix_fmt bgr24 -frames:v 1 pipe:1

Con estos comandos que se leen desde el dispositivo de bucle invertido, las imágenes no son oscuras y demora aproximadamente 1.3 segundos (JPEG) o 1.1 segundos (mapa de bits) para enviarlas a la salida estándar.

x-ray
fuente