Movendo Cortar no Vídeo

8

Eu tenho um vídeo em HD de um palestrante dando uma palestra. Eu gostaria de redimensionar o vídeo cortando cada quadro, mas o retângulo de corte precisa estar centralizado na cabeça do falante enquanto ele se move pelo palco.

I pode gerar um arquivo que contém X do retângulo de corte, Y, largura e altura para cada quadro do vídeo.

Qual é a melhor maneira de aplicar esse corte em movimento ao vídeo?

Deveria funcionar se eu ..

  1. Use ffmpeg para extrair cada quadro em uma pasta
  2. Use outro programa para cortar cada arquivo de imagem
  3. Use ffmpeg para reconstruir o vídeo usando os arquivos de imagem cortados

Existe uma maneira melhor de fazer isso?

David
fonte
O ImageMagick pode fazer o corte se você tiver uma descrição numérica do quadro de corte. Eu sugiro: exportar como sequência de imagens usando ffmpeg, processo em lote usando ImageMagick e remux como um filme em ffmpeg. Você precisará de algum tipo de script de shell para colar tudo, provavelmente. Se você postar um exemplo do arquivo com as informações de corte, posso descobrir os detalhes para você.
Stib
Posso perguntar como você gera esse arquivo? Estou trabalhando exatamente no mesmo problema. Eu tenho uma prova de conceito usando o filtro de subtração ffmpeg tblend e, em seguida, o filtro de detecção de culturas. Querendo saber se você tem uma maneira melhor.
Janes

Respostas:

2

Semelhante à resposta de sobreposição de Gyan, uma versão um pouco mais simples pode usar um -filter_script básico com os filtros "swaprect" e "crop". Mova o destino de corte para 0,0 e, em seguida, corte a área de destino em 0,0. O destino deve ser trocado para 0,0, caso contrário, o outro ret é trocado. Isso funcionou com a versão 3.4.6-0ubuntu0.18.04.1 do ffmpeg

Verifique se os números dos quadros são relativos ao deslocamento passado com "-ss".

Um exemplo de segmentação de culturas de 1280 x 720 a partir de uma fonte de 4096 x 2160. A fonte é 24fps e as informações de rastreamento são 8fps.

script de filtro de colheita:

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
fonte
1

Eu já mudei para avconv, então peço desculpas se a resposta pode ser um pouco diferente no ffmpeg clássico, mas acredito que não deve haver muita diferença.

Você pode ter um corte em movimento se puder criar algum tipo de fórmula entre o número do quadro e a posição do corte; mas não há ferramentas analíticas disponíveis para fazer isso. Isso significa que, se o alto-falante se mover de maneira previsível, teoricamente você poderá fazer isso sem um aplicativo externo.

Vamos supor, por exemplo, que o alto-falante esteja se movendo da parte superior esquerda para a parte inferior direita da imagem. Você pode fazer algo como:

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

Aqui estou movendo 1 pixel por quadro, o que é muito improvável como alguém se moveria.

Lembre-se de que existem muitas funções matemáticas que são fornecidas pela interface de filtro do avconv (e eu tenho certeza que o ffmpeg é semelhante).

Então, vamos imaginar que você deseja mover 1 pixel por quadro, mas apenas de 200 para 350 quadros. Você pode então fazer

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

Para os quadros <200, max(n,200)geraria 200, depois retiramos 200 para torná-lo 0 e, em seguida min, retornamos a primeira parte até 350 quadros, onde esse resultado se tornaria mais de 150 e a constante começará a ser retornada.

Embora escrever essa fórmula à mão seja bastante tedioso, talvez seja útil em alguns casos também.

Dito tudo isso, se eu tivesse a opção de ter acesso ao software capaz de trabalhar com imagens quadro a quadro, eu seguiria esse caminho.

v010dya
fonte
1

Como você tem " um arquivo que contém os X, Y, Largura e Altura do retângulo de corte para cada quadro ", você pode usar a opção filter_script para fazer isso no FFmpeg. O filtro de corte não suporta a edição da linha do tempo, mas o filtro de sobreposição. Portanto, se você criar uma tela em branco com a mesma resolução do seu vídeo e sobrepor o vídeo com coordenadas, de modo que a região desejada seja sobreposta na área visível, o objetivo será alcançado.

A sintaxe básica é

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

onde file.txtfica assim:

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]

A tela We Hdeve ser igual às dimensões de corte (fixas / estáticas) e da mesma FPS. Em seguida, cada quadro do vídeo é sobreposto em ( - X, - Y) para que o canto superior esquerdo da região desejada esteja em (0,0) da tela. Cada sobreposição ocorre para um quadro. Por uma questão de eficiência, se você tiver intervalos em que a região de colheita é estática, use o avaliador entre

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

Você também pode avaliar usando o carimbo tde data e hora em vez do índice de quadros.

Gyan
fonte
Tentei implementar esta solução para ver como ela funciona, só queria uma versão bruta no início para teste, para não ter implementado entre elas, apenas adicionei a posição de cada quadro, para os primeiros 3000 quadros. Minha memória ffmpeg está agora em 36GB e indo com 1 quadro por minuto :( Eu acho que essa não é a melhor solução para cada quadro haha
Eek
Atualmente, estou fora da cidade, mas procure usar o filtro de apara para isolar um quadro e enviar para o Png. Então, n comandos para n quadros. Então concat as imagens para um vídeo
Gyan