Cómo tomar una captura de pantalla (alto fps) en Linux (progtwigción)

Antes que nada quiero decir que he estado leyendo mucho sobre esto y que he aprendido muchas formas de hacerlo, pero no he podido hacerlo en Linux.

Mi proyecto es un ambilight con arduino, por lo que necesito tomar una captura de pantalla del escritorio y analizar su color.

Al principio usé Processing 2.0 con la clase ‘Robot’ de ‘java.awt’. Inicialmente podía tomar 5 cuadros por segundo y luego obtuve 13 fps. Esto funciona pero quiero más rendimiento, así que empiezo a leer.

En Windows o Mac, tiene bibliotecas que le permiten acceder directamente al ‘frameBuffer’, por lo que puede tomar una captura de pantalla realmente ‘fácil’ y realmente rápida.

En Ubuntu probé python con Gtk, PIL, Qt … y la forma más rápida es GTK, pero solo puedo tener unos 15 fps.

Mi problema es: quiero hacerlo en varias plataformas, pero prefiero que mi progtwig funcione en Linux al principio y luego en Windows (no me gusta demasiado: P).

Entonces, la primera pregunta: ¿Python es capaz de ofrecer esa perfomance? Porque creo que C ++ puede ser una mejor opción.

Y la segunda pregunta: ¿qué necesito para hacerlo? He leído sobre Xlib (X11) pero no puedo encontrar documentación que me permita hacer una captura de pantalla. También sé, por ejemplo, FFmpeg que es una herramienta poderosa pero no sé cómo implementarla.

Espero que puedas ayudarme (y perdóname si he cometido algún error).

Hacer que este trabajo sea multiplataforma es probable que sea un poco de trabajo. Si su objective final son las ventanas, ¿por qué no usar el proyecto amblone, que parece hacer exactamente lo que quiere?

http://amblone.com/guide

En cualquier caso, aquí hay una solución con ffmpeg y graphicsmagick que es bastante rápida (en mi portátil i7 de 8GB). ffmpeg captura exactamente una pantalla, la reduce al tamaño cuadrado más pequeño que puede, canaliza la salida a graphicsmagick convert, donde se redimensiona a 1×1 píxeles y luego informa los valores rgb de la imagen.

#!/bin/bash mkfifo /tmp/screencap.fifo while true do # this version will send the info to a fifo # ffmpeg -y -loglevel error -f x11grab -s 1920x1080 -i :0.0 -s 32x32 \ # -vframes 1 -f image2 -threads 2 - | gm convert - -resize 1x1 \ # txt:- > /tmp/screencap.fifo # this version will write out the info to the command line # and will show you what is going on. ffmpeg -y -loglevel error -f x11grab -s 1920x1080 -i :0.0 -s 32x32 \ -vframes 1 -f image2 -threads 2 - | gm convert - -resize 1x1 txt:- done exit 

Esto te dará algo como lo siguiente:

 0,0: ( 62, 63, 63) #3E3F3F 0,0: (204,205,203) #CCCDCB 0,0: ( 77, 78, 76) #4D4E4C 

El 0,0 es la ubicación del píxel que se está leyendo. Los números entre paréntesis son los valores R, G, B respectivos, y los números al final son los valores hexadecimales típicos de html-esque. En el caso anterior, solo hay 1 píxel, pero usted podría (si quisiera tener las direcciones cardinales como valores RGB generalizados) simplemente cambie la parte de -resize 1x1 anterior a -resize 3x3 y obtendrá algo como:

 0,0: ( 62, 63, 65) #3E3F41 1,0: ( 90, 90, 91) #5A5A5B 2,0: (104,105,106) #68696A 0,1: ( 52, 51, 52) #343334 1,1: ( 60, 60, 59) #3C3C3B 2,1: ( 64, 64, 64) #404040 0,2: ( 49, 49, 50) #313132 1,2: ( 60, 60, 60) #3C3C3C 2,2: ( 65, 65, 65) #414141 

Te lo dejo a ti para que pases esa información a tu arduino.

ffmpeg es genial, pero tendrá que acordarse de cambiar el bit de captura de pantalla (aquí en mi ejemplo -f x11grab ) con lo que use el sistema de Windows. Aquí hay un enlace SO que entra un poco más en detalle.

Si realmente insiste en hacer algo multiplataforma, entonces recomendaría sumergirse en openCV con enlaces python y usar el dispositivo framebuffer como entrada de video, reduciendo el resultado a 1×1 píxeles y usando el promedio de color resultante para impulsar su pwm a través de algunos Tipo de transmisión UDP.