El resultado buscado debe ser tal que así:
Vamos a ver los distintos pasos que he dado.
1) Capturar un fotograma con la webcam.
sudo apt-get install <programa>
guvcview -d /dev/video0 --nodisplay -m 1 -r 1 -f yuyv -i "snapshot.jpg" -c 2 --exit_on_close
uvccapture -d/dev/video0 -x320 -y240 -t300 -q75 -B31 -C29 -S80 -w -v -t0 -o"snapshot-1.jpg"
fswebcam --scale "320x240" "snapshot-1.jpg"
streamer -c /dev/video0 -o "snapshot-1.jpg"
- En mi portátil uvccapture deja el led de la webcam encendido al hacer la primera captura y ya se queda asi para siempre. Es bastante molesto.
- uvccapture, fswebcam o streamer a veces no hacen la captura y lo único que sacan es un jpeg con algunas rayas en la parte superior y el resto de la imagen en verde, quédandose en ocasiones así para siempre y obligándome a parar el script y entrar en guvcview, que resetea la cámara. Por lo que he visto es un problema del driver uvcvideo y depende de la cámara. De ellos, uvccapture es el que se mantiene mas estable, pero aún asi a veces falla.
- guvcview, que en principio no es un programa de captura de linea de comandos (ya que tiene entorno gráfico, aunque podemos anularlo) es el que mejor me ha funcionado de todos y el que menos tendencia tiene al error que deja la imagen capturada en verde, por eso es el que he dejado en el script. Es un poco aparatoso pero así garantizo que funciona con la cámara que voy a usar.
- Con la cámara Eyetoy no funcionan guvcview ni uvccapture, en cambio fswebcam funciona de una forma excepcionalmente estable.
En el caso de que la cámara no esté conectada o esté deshabilitada al ejecutar el script utilizo la siguiente imagen rellenar el hueco:
2) Configurar niveles brillo, contraste, etc, de la webcam desde línea de comandos.
- Permitirme hacer capturas desde la consola de texto, fuera de la sesión de las X, ya que el script se ejecuta en el arranque del sistema.
- Permitirme hacer capturas con el usuario root y con él capturar la sesión X de otro usuario distinto, que será el que habrá iniciado la sesión en el entorno gráfico.
chvt $tty; sleep 5; DISPLAY=:0 XAUTHORITY=$home/.Xauthority scrot "$ruta/screenshot.jpg"
user=$(who | grep "(:0)" | cut -f1 -d" ")
4) Juntando todo.
Adicionalmente he incluido estas otras características:
- Sólo se hacen capturas entre las 8 y las 23 horas.
- Si ningún usuario ha iniciado sesión en las X (busco usuarios con who que estén en el terminal "(:0)"), no hago captura de pantalla, sólo de webcam.
- Miro la existencia de un fichero llamado "semaforo" en el directorio donde guardo las imágenes. Antes de cada captura, se comprueba si no existe o existe y su contenido es "1", en cuyo caso se hacen las capturas. En caso contrario no se hacen. Esto es para poder entrar por ssh a la máquina y desactivar las capturas de una manera sencilla.
Aquí está el script resultante, con comentarios inline adicionales sobre diversos aspectos del funcionamiento:
#!/bin/bash dispositivo="/dev/video0" resolucion_snapshot="320x240"
#La resolución es mínima pero para mi suficiente. Por supuesto, es modificable sin problema.
resolucion_screenshot="426x240" delay=300s ruta="/root/capture" semaforo="$ruta/semaforo" #Resetea el dispositivo con valores de brillo, contraste, etc, que den mejor resultado #Esta orden pude meterse en el bucle para evitar que el usuario los manipule entre capturas. uvcdynctrl -d $dispositivo -L "$ruta/uvcvalues.txt" # Si el USB se pone en suspensión y apaga la cámara, hacer esto para evitarlo (hay que hacerlo como root): # echo -1 > /sys/module/usbcore/parameters/autosuspend while true do #Fecha y hora actual fichero=$(date +"%Y-%m-%d.%T") hora=$(date +"%H") #Mira en el fichero semaforo. Si su contenido es 1 o no existe, hace la captura. Si existe y es distinto de 1, no la hace capturar=1 test -f $semaforo && capturar=$(cat $semaforo) #Solo hacemos capturas entre las 8:00 y las 22:59, modificar según necesidades. if [ $hora -ge 8 -a $hora -le 23 ] && [ $capturar -eq 1 ] then #Limpia snapshot previos. cd $ruta rm -f snapshot*.jpg #Si existe el dispositivo de video (camara conectada y activada) if [ -e $dispositivo ] then guvcview -d $dispositivo --no_display -m 1 -r 1 -f yuyv -i "$ruta/snapshot.jpg" -c 2 --exit_on_close #La salida de guvcview se guarda en snapshot-1.jpg, ya que numera los ficheros de salida. #Otras opciones posibles: # uvccapture -d/dev/video0 -x320 -y240 -t300 -q75 -B31 -C29 -S80 -w -v -t0 -o"$ruta/snapshot-1.jpg" # fswebcam --scale $resolucion_snapshot "$ruta/snapshot-1.jpg" # streamer -c /dev/video0 -o "$ruta/snapshot-1.jpg" else #Si no encontramos la cámara, ponemos la carta de ajuste por poner algo. cp "$ruta/carta-ajuste.jpg" "$ruta/snapshot-1.jpg" fi #Mira si hay usuario logueado en las X, en el escritorio :0 user=$(who | grep "(:0)" | cut -f1 -d" ") if [ -n "$user" ] then #Hay usuario logueado, vamos a hacer una captura de la pantalla de la sesión X donde está tty=$(who | grep "(:0)" | awk '{print $2}') tty=${tty:3} # Quita los tres primeros caracteres del ttyX, o sea: "tty8" => "8" home=$(cat /etc/passwd | grep $user | cut -d":" -f6) #Cambia al tty donde está el usuario, espera un rato hasta que se carga, usa el XAUTHORITY del usuario para tener acceso a las X #y hace el screenshot mediante el comando "scrot". chvt $tty; sleep 5; DISPLAY=:0 XAUTHORITY=$home/.Xauthority scrot "$ruta/screenshot.jpg" #Ajusta las imagenes a la resolucion correcta convert "$ruta/screenshot.jpg" -resize $resolucion_screenshot "$ruta/${fichero}-screen.jpg" convert "$ruta/snapshot-1.jpg" -resize $resolucion_snapshot "$ruta/snapshot.jpg" #Une las imagenes y pone el banner. convert "$ruta/snapshot.jpg" "$ruta/${fichero}-screen.jpg" +append "$ruta/$fichero.jpg" etiqueta="$fichero - usuario: $user" convert "$ruta/$fichero.jpg" -background Orange label:"$etiqueta" +swap -gravity Center -append "$ruta/${fichero}-snap.jpg" #Limpieza rm "$ruta/snapshot.jpg" "$ruta/${fichero}-screen.jpg" "$ruta/$fichero.jpg" "$ruta/screenshot.jpg" else #No se hace captura de pantalla, solo se usa la de la cámara. etiqueta="$fichero - Sin usuario logueado"
#Une las imagenes y pone el banner.
convert "$ruta/snapshot-1.jpg" -resize $resolucion_snapshot "$ruta/snapshot.jpg" convert "$ruta/snapshot.jpg" -background Orange label:"$etiqueta" +swap -gravity Center -append "$ruta/${fichero}-snap.jpg" #Limpieza rm "$ruta/snapshot.jpg" fi fi #Espera antes de repetir sleep $delay done
El script debe ser arrancado como root en el inicio del sistema. La forma mas sencilla es poniéndolo en /etc/rc.local, antes del "exit 0". En este caso es necesario invocar al script añadiendo & al final, para que quede ejecutándose como root en el background.
/root/capture/capture.sh &
En el directorio /root/capture tendremos los siguientes ficheros:
- capture.sh: es el script mostrado hace unas líneas. Debe estar con permisos 750.
- carta-ajuste.jpg, descargable desde aquí.
- uvcvalues.txt, generado por nosotros a mano con el comando uvcdynctrl -d /dev/video0 -W uvcvalues.txt tras ajustar el brillo, contraste, etc, de la cámara a mano abriendo guvcview.
5) Ampliaciones interesantes.
6) Referencias.
Como siempre, me he subido a hombros de gigantes. De aquí he sacado las ideas para llevarlo todo a cabo:
- http://blog.retep.org/2013/01/13/setting-up-a-linux-weather-webcam/
- http://askubuntu.com/questions/226829/how-to-take-screenshot-of-an-x11-based-gui-from-a-text-terminal-such-as-tty1
- http://www.anthoniraj.com/taking-a-screenshot-from-a-daemonshell-scriptcommand-line/
- http://askubuntu.com/questions/177067/capture-login-screen-not-sucssecful
- http://stackoverflow.com/questions/1584411/how-to-run-an-x-program-from-outside-the-x-session-e-g-from-the-console-or-ssh
- http://en.it-usenet.org/thread/19349/128229/
Y ya está, como decía el Control Central de Programas en Tron:
Fin de impresión.
una pregunta...
ResponderEliminarpor que la linea guvcview -d /dev/video0 --nodisplay -m 1 -r 1 -f yuyv -i "snapshot.jpg" -c 2 --exit_on_close
las opciones --nodisplay --exit_on_close no me las reconoce????
claro al quitarlas pues el programa sale en primer plano y hasta que no lo cierro no hace otro ciclo...
me puedes ayudar??
Hola, prueba a hacer esto:
Eliminar# guvcview -?
guvcview 1.7.1
file guvcview_video.mkv has extension type 1
file guvcview_image.jpg has extension type 0
Uso:
guvcview [OPCIÓN…] - local options
Opciones de ayuda:
-?, --help Mostrar opciones de ayuda
--help-all Muestra todas las opciones de ayuda
--help-gtk Mostrar opciones GTK+
Opciones de la aplicación:
--version Imprimir versión
-v, --verbose Exhibir information de depuracion
-d, --device=VIDEO_DEVICE Dispositivo de video [pred: /dev/video0]
-a, --add_ctrls Salir después de añadir los controles de extensión UVC (requiere root/sudo)
-o, --control_only No hacer streaming de vídeo (sólo controles)
--no_display No mostrar interfaz gráfica
-r, --capture_method=[1 | 2] Método de captura (1-mmap (predeterminado) 2-read)
-g, --config=FILENAME Archivo de configuración
-w, --hwd_acel=[1 | 0] Accel. del hardware (habilitar(1)|deshabil.(0))
-f, --format=FORMAT Pixel format(mjpg|jpeg|yuyv|yvyu|uyvy|yyuv|yu12|yv12|nv12|nv21|nv16|nv61|y41p|grey|y10b|y16 |s501|s505|s508|gbrg|grbg|ba81|rggb|bgr3|rgb3)
-s, --size=WIDTHxHEIGHT Resolución (defect: 640x480)
-i, --image=FILENAME Archivo de Imagen
-c, --cap_time=TIME Intervalo de captura Imagen en segundos
-m, --npics=NUMPIC Número de imagens a capturar
-n, --video=FILENAME Archivo video (captura del arranque)
-t, --vid_time=TIME Tiempo de la captura video (segundos)
--exit_on_close Salir de guvcview después de cerrar el vídeo
-j, --skip=N_FRAMES Número de fotogramas iniciales a omitir
-p, --show_fps=[1 | 0] Exhibir FPS (habilitar(1) | deshabilitar(0))
-l, --profile=FILENAME Cargar perfil al inicio
--display=VISOR Visor [display] X que usar
Como puedes ver las opciones --nodisplay y --exit_on_close si que me salen con guvcview 1.7.1. ¿Cual tienes tu?.
Fijate que ambas comienzan por -- (dos guiones) en lugar de - (un solo guión), que suele ser lo normal.