Moviendo Cultivo en Video

8

Tengo un video HD de un orador dando una conferencia. Me gustaría cambiar el tamaño del video recortando cada fotograma, pero el rectángulo de recorte debe centrarse en la cabeza del orador mientras se mueve por el escenario.

Yo puedo generar un archivo que contiene X del rectángulo de recorte, y, ancho, y altura para cada fotograma del vídeo.

¿Cuál es la mejor manera de aplicar este recorte en movimiento al video?

Debería funcionar si yo ...

  1. Use ffmpeg para extraer cada cuadro a una carpeta
  2. Use otro programa para recortar cada archivo de imagen
  3. Use ffmpeg para reconstruir el video usando los archivos de imagen recortados

¿Hay una mejor manera de hacer esto?

David
fuente
ImageMagick podría hacer el recorte si tiene una descripción numérica del marco de recorte. Sugeriría: exportar como secuencia de imágenes usando ffmpeg, proceso por lotes usando ImageMagick y remux como una película en ffmpeg. Necesitará algún tipo de script de shell para pegarlo todo probablemente. Si publica un ejemplo del archivo con la información de recorte, puedo resolver los detalles por usted.
stib
¿Puedo preguntar cómo se genera ese archivo? Estoy trabajando exactamente en el mismo problema. Tengo una prueba de concepto usando el filtro de sustracción ffmpeg tblend y luego el filtro cropdetect. Preguntándome si tienes una mejor manera.
Jannes

Respuestas:

2

Similar a la respuesta de superposición de Gyan, una versión un poco más simple puede usar un -filter_script básico con los filtros "swaprect" y "crop". Mueva el objetivo de recorte a 0,0 y luego recorte el área objetivo a 0,0. El objetivo debe intercambiarse a 0,0, de lo contrario, el otro rect intercambiado puede superponerse. Esto funcionó con ffmpeg versión 3.4.6-0ubuntu0.18.04.1

Asegúrese de que los números de fotograma sean relativos al desplazamiento pasado con "-ss".

Un ejemplo dirigido a cultivos de 1280x720 de una fuente de 4096x2160. La fuente es de 24 fps y la información de seguimiento es de 8 fps.

recorte-filtro-script:

swaprect=1280:720:0:0:1568:594:enable='between(n,0,26)',
swaprect=1280:720:0:0:1552:598:enable='between(n,27,29)',
swaprect=1280:720:0:0:1565:583:enable='between(n,30,32)',
swaprect=1280:720:0:0:1603:576:enable='between(n,33,35)',
crop=1280:720:0:0

ffmpeg -ss [start offset] -t [duration] -i input.mov -filter_script:v:0 crop-filter-script -acodec copy out.mov

Jason Gilbert
fuente
1

Ya he cambiado a avconv, así que me disculpo si la respuesta puede ser un poco diferente en el clásico ffmpeg, pero creo que no debería haber mucha diferencia.

Puede tener un recorte en movimiento si puede crear algún tipo de fórmula entre el número de cuadro y la posición del recorte; pero no hay herramientas analíticas disponibles para hacer eso. Esto significa que si el hablante se mueve de una manera predecible, teóricamente podría hacerlo sin una aplicación externa.

Supongamos, por ejemplo, que el altavoz se mueve de arriba a la izquierda a abajo a la derecha en la imagen. Podrías hacer algo en la línea de:

avconv -i input.ogv -vf 'crop=200:100:n:n' -c:v libtheora output.ogv

Aquí me estoy moviendo 1 píxel por cuadro, lo cual es muy poco probable como alguien se movería.

Tenga en cuenta que la interfaz de filtro de avconv proporciona muchas funciones matemáticas (y estoy seguro de que ffmpeg es similar).

Imaginemos que desea mover 1 píxel por fotograma, pero solo de 200 a 350 fotogramas. Entonces puedes hacer

min(max(n,200)-200, 150)

Para los cuadros <200, max(n,200)generaríamos 200, luego quitamos 200 para ponerlo en 0, y luego mindevolveremos la primera parte hasta 350 cuadros, donde ese resultado sería más de 150 y la constante comenzará a ser devuelta.

Aunque escribir tal fórmula a mano sería bastante tedioso, tal vez también sea útil en algunos casos.

Dicho todo esto, si tuviera la opción de tener acceso al software que es capaz de trabajar en imágenes cuadro por cuadro, seguiría esa ruta.

v010dya
fuente
1

Dado que tiene " un archivo que contiene los rectángulos de recorte X, Y, Ancho y Altura para cada cuadro ", puede usar la opción filter_script para hacer esto en FFmpeg. El filtro de recorte no admite la edición de la línea de tiempo, pero el filtro de superposición sí. Por lo tanto, si crea un lienzo en blanco de la misma resolución que su video y luego superpone el video en la parte superior con coordenadas de modo que su región deseada se superponga en el área visible, se logra el objetivo.

La sintaxis básica es

ffmpeg -i in.mp4 -filter_complex_script file.txt -map "[out]" output.mp4

donde se file.txtve así:

nullsrc=WxH:r=FPS[cv];
[cv][0]overlay=-X0:-Y0:shortest=1:enable='eq(n\,0)'[b0];
[b0][0]overlay=-X1:-Y1:shortest=1:enable='eq(n\,1)'[b1];
[b1][0]overlay=-X2:-Y2:shortest=1:enable='eq(n\,2)'[b2];
...
[bm-1][0]overlay=-Xm:-Ym:shortest=1:enable='eq(n\,m)'[out]

El lienzo Wy Hdebe ser igual a las dimensiones de recorte (fijo / estático) y de la misma FPS. Luego, cada fotograma del video se superpone en ( - X, - Y) para que la esquina superior izquierda de la región deseada esté en (0,0) del lienzo. Cada superposición ocurre para un cuadro. En aras de la eficiencia, si tiene intervalos donde la región de cultivo es estática, debe usar el evaluador intermedio, por ejemplo

[bi][0]overlay=-Xi:-Yi:shortest=1:enable='between(n\,1200\,1445)'[bj];

También puede evaluar usando la marca tde tiempo en lugar del índice de fotograma.

Gyan
fuente
Intenté implementar esta solución para ver cómo funciona, solo quería una versión bruta al principio para probar, así que no la he implementado entre, simplemente agregué la posición para cada fotograma, para los primeros 3000 fotogramas. Mi memoria ffmpeg ahora es de 36 GB y va con 1 fotograma por minuto :( Creo que esta no es la mejor solución para cada fotograma jaja
Eek
Actualmente estoy fuera de la ciudad, pero considero usar el filtro de recorte para aislar un cuadro y enviarlo a Png. Entonces, n comandos para n marcos. Luego concat las imágenes a un video
Gyan