Publi

Cómo aplicar filtros de GIMP a un vídeo

photo-1464602083226-de2c1675e946

Estoy subiendo vídeos a mi canal personal de Youtube. Aunque sólo tengo algunos pequeños tutoriales, postales de navidad y cosas así. He decidido subir algunos vídeos y cortos antiguos. Aunque están grabados con una cámara analógica y en cinta magnética, lo que significa que el vídeo tiene mucha pérdida y poca calidad. En un intento por darle algo más de definición, o al menos que el visionado sea algo más agradable, pensé en un filtro de Gimp (Desenfocado Gaussiano Selectivo), y estaría muy bien poder aplicarlo a todos los fotogramas.

En principio, ya que GIMP es un programa para edición de imágenes, no puedo pasarle un vídeo completo, tendré que pasarle fotogramas sueltos para que él los trate Lo que no quería yo era perder mucho tiempo, aunque si tengo que dejar el ordenador varias noches encendido no me importa. Por otro lado, tampoco me gustaría necesitar gran cantidad de disco, como experimento, convertí un vídeo de 3 minutos a imágenes fijas y ocupó más de 2Gb, no quiero saber lo que podría pasar con un vídeo de 1h de más resolución, por lo que tendremos que gestionar el uso de disco.

Por otro lado, y como dije antes, la velocidad es lo de menos, se puede tirar varios días si es necesario. No he utilizado técnicas multi-hilo, para procesar los fotogramas, y supongo que si necesito hacerlo con muchos vídeos, tarde o temprano tendré que hacer que se puedan ejecutar varias instancias de GIMP para procesar varios fotogramas a la vez, aunque también estaría bien evitar la carga del programa una y otra vez.

Para empezar, debemos tener unas nociones de Scheme, el lenguaje utilizado por las extensiones Script-fu de Gimp. Para empezar te recomiento este post.
En el script que vamos a hacer ahora, nos centraremos en abrir la imagen, obtener un drawable (algo así como un lienzo a partir de la imagen) y salvar dicho lienzo en un archivo. Para estas operaciones he optado por utilizar el formato PNG, aunque podríamos haber utilizado lossless jpeg, tiff, o cualquier otro formato que aplique compresión de imagen sin pérdidas. Es importante esto, porque la compresión de vídeo normalmente también tiene pérdida y siempre que extraemos y volvemos a grabar se producen, por lo tanto no queremos que en la aplicación del efecto ocurran más pérdidas por otro lado.

Script para GIMP

El script que guardaremos en .gimp-2.x/scripts/ se llamara gaussblursel.scm (donde 2.x es vuestra versión de GIMP), y contendrá lo siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(define (gaussblursel infile outfile radius max-delta)
    (let*
        (
            (image (car (file-png-load 1 infile infile)))
            (drawable (car (gimp-image-active-drawable image)))
        )
    (plug-in-sel-gauss 1 image drawable radius max-delta)

    (file-png-save 1 image drawable outfile outfile
          1 9 0 0 0 0 0)   
            ; 1 Adam7 interlacing?
            ;   0 deflate compression factor (0-9)
            ;     0 Write bKGD chunk?
            ;       0 Write gAMMA chunk?
            ;         0 Write oFFs chunk?
            ;           0 Write tIME chunk?    ?? backwards in DB Browser
            ;             0 Write pHYS chunk?  ?? backwards in DB Browser
    )
)

Aquí abrimos, procesamos el archivo y lo salvamos, utilizamos plug-in-sel-gauss que es la función que nos proporciona el desenfoque gaussiano selectivo y es el script que ejecutaremos para cada fotograma de vídeo.

Shell script

Ahora, crearemos un shell script que extraiga fotogramas del vídeo, los procese (con el script de GIMP), y los vuelva a meter en el vídeo. Para ello, extraeremos del vídeo intervalos de un segundo (suelen ser unos 25/30 fotogramas), lo que ocupa poco espacio en disco duro. Una vez ha extraído los fotogramas, llama varias veces a gimp en modo no-interactivo (desde consola, sin necesidad de abrir ventanas), procesa todos los fotogramas con el script anterior, los salva y los va metiendo todos en un vídeo llamado resultado.mp4; eso sí, para que no haya problema con el audio, cogeremos la misma pista de audio del vídeo original y la implantaremos en el vídeo destino.
Este script, para calcular la duración del archivo de vídeo y los fotogramas por segundo del mismo utiliza el script videoinfo.
Allá va la primera versión del script.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash

VIDEO="$1"
SECS=$(videoinfo seconds "$VIDEO")
FPS=$(videoinfo fps "$VIDEO")
TEMPNAME=$(tempfile)
rm "$TEMPNAME"

for ((i=0;i<$SECS;i++)); do
    echo "SEGUNDO: $i de $SECS" >&2
    avconv -i "$VIDEO" -an -q:v 1 -ss $i -t 1  -f image2 $TEMPNAME%05d.png
    for img in $TEMPNAME*.png; do
    gimp -i -b "(gaussblursel "$img" "$img" 8 40)" -b '(gimp-quit 0)'
    cat $img
    rm $img
    done
done | avconv -r $FPS -f image2pipe -c:v png -i pipe:0 -i "$VIDEO" -c:v h264 -c:a mp3 -map 0:v:0 -map 1:a:0 resultado.mp4

Al final del post, optimizaremos un poco y sólo un poco el script, para no cargar tantas veces gimp, aunque se cargará el programa al menos una vez por segundo.

Análisis del script

En principio, una vez extraídos SECS (segundos de duración) y FPS (fotogramas por sengundo), obtenemos un nombre de fichero temporal (para almacenar los fotogramas del segundo con el que trabajaremos cada vez.
En cada segundo que recorramos con el bucle for, extraeremos todos los fotogramas en archivos PNG cuyo nombre finalizará con números consecutivos. Una vez extraído ese segundo, proceso que suele durar poco (si el vídeo tiene los índices bien hechos). Con esta serie de ficheros (tantos como fotogramas por segundo tenga nuestro vídeo) llamaremos al script que hace el desenfoque y con cat, pondremos el contenido del archivo por la salida.
La salida combinada de todos los archivos procesados la cogerá avconv, cuya entrada es la pipe de salida del for, combinará el vídeo con el audio y listo. Podremos elegir los códecs que queramos. En mi caso, preferí hacerlo con h264 para vídeo y mp3 para el audio.

Primeros pasos

El primer paso para un buen resultado, es extraer varios fotogramas de muestra del vídeo y aplicar el efecto que queremos, para elegir los parámetros de radio de desenfoque y delta perfectos para todo el vídeo.
sentada_frame
A primera vista no apreciamos mucho, ya que lo que quería, sobre todo era quitar algo de granulado de los soportes y de las varias compresiones que lleva el vídeo (los vídeos tienen ya un tiempo y en aquellos comprimía los vídeos con gran pérdida, y en ocasiones cuando había que aplicar algún efecto, había que pasar por varios programas comprimiendo y descomprimiendo vídeo, por lo que el resultado siempre estaba algo más deteriorado.

Si ampliamos un área de imagen sí que podremos ver que se ha mejorado:
sentada_frame_g

Revisión del script

Esta es una versión que hice para que GIMP no se ejecutara tantísimas veces y es que la carga y descarga contínea del programa puede hacernos perder muchísimo rendimiento. En mi equipo, la ejecución del script tarda menos de la mitad con esta pequeña modificación:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash

VIDEO="$1"
SECS=$(videoinfo seconds "$VIDEO")
FPS=$(videoinfo fps "$VIDEO")
TEMPNAME=$(tempfile)
rm "$TEMPNAME"

for ((i=0;i<$SECS;i++)); do
    echo "SEGUNDO: $i de $SECS" >&2
    avconv -i "$VIDEO" -an -q:v 1 -ss $i -t 1  -f image2 $TEMPNAME%05d.png
    SEQUENCE=()
    for img in $TEMPNAME*.png; do
    SEQUENCE+=(-b "(gaussblursel "$img" "$img" 2.50 12)")
    done

    gimp -i ${SEQUENCE[@]} -b '(gimp-quit 0)'

    for img in $TEMPNAME*.png; do
    cat $img
    rm $img
    done
done | avconv -r $FPS -f image2pipe -c:v png -i pipe:0 -i "$VIDEO" -c:v h264 -c:a mp3 -map 0:v:0 -map 1:a:0 resultado.mp4

En este caso, lo primero que hacemos es generar los argumentos del comando GIMP que ejecutaremos (será un script por cada fotograma, pero se los pasaremos todos juntos), una vez generado ejecutamos gimp y cuando terminemos, pondremos el contenido de los frames a la salida e iremos borrando archivos.

Listos para ejecutar

Una vez lo tengamos, todo listo, en el script editamos los parámetros del efecto (en la línea de llamada a gimp) y ejecutamos. Tardará un tiempo, pero obtendremos nuestro resultado.
Al final, obtenemos un vídeo que se ve un poco mejor que el original, tampoco se pueden hacer milagros, pero las texturas son un poco más suaves (el vídeo es muy antiguo):

Ideas para el futuro

Como idea, lo que podríamos hacer será generar varias secuencias de archivos y ejecutar varias instancias de gimp con scripts diferentes. Si tienes un equipo con varios núcleos, podrás aprovecharlos todos para procesar fotogramas de vídeo y terminar mucho antes, utilizando herramientas de bash para ejecución en segundo plano, o herramientas propias para ejecutar tareas concurrentemente en shell scripts.

Foto principal: Sergey Turkin

También podría interesarte....

There are 11 comments left Ir a comentario

  1. Pingback: Cómo aplicar filtros de GIMP a un vídeo | PlanetaLibre /

  2. eastpaints /
    Usando Google Chrome Google Chrome 117.0.0.0 en Windows Windows NT

    تعد شركة الشرق للدهانات واحدة من الشركات الرائدة في مجال صناعة وتوزيع الدهانات المختلفة. تتميز شركة دهانات بجودة منتجاتها وفعالية استخدامها، حيث توفر مجموعة واسعة من المنتجات التي تلبي احتياجات العملاء العديدة. تقدم الشركة حلولاً متكاملة للدهان من خلال الخدمات التي تقدمها، سواء كان ذلك للاستخدام الداخلي أو الخارجي. بالإضافة إلى ذلك، تسعى شركة الشرق للدهانات إلى تطوير نفسها باستمرار من خلال الاستثمار في البحث والتطوير وتحسين ابتكاراتها التقنية.
    شركة دهانات

  3. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    The variety and magnitude of these web slots are astounding. Great find. สล็อตเว็บใหญ่

  4. WilliamSEO /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    A debt of gratitude is in order for composing such a decent article, I bumbled onto your blog and read a couple of post. I like your style of composing… 안전한 토토사이트

  5. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    I’d love to hear about any success stories with durable slot options. สล็อตเว็บตรง แตกง่าย

  6. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    I have to look for goals with essential information on given point and offer them to instructor our inclination and the article. เว็บสล็อตทุกค่าย

  7. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    I suggest just great and dependable data, so observe it: 대구맛집

  8. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    Magnificent dispatch! I am to be sure getting well-suited to over this data, is genuinely neighborly my amigo. In like manner awesome blog here among a significant number of the exorbitant data you gain. Hold up the advantageous procedure you are doing here. สล็อตโรม่า

  9. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    This is a marvelous article, Given such an unprecedented measure of information in it, These kind of articles keeps the clients energy for the site, and continue sharing more … positive conditions. ป๊อกเด้งออนไลน์

  10. Fool Me Once Merchandise /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    Thank you for posting such a great article! I found your website perfect for my needs. It contains wonderful and helpful posts. Keep up the good work!. Thank you for this wonderful Article!

  11. jsimitseo /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    Truly value this magnificent post that you have accommodated us.Great site and an incredible subject also I truly get astonished to peruse this. Its better than average. concierge doctor naples

Leave a Reply