Crop im Video verschieben

8

Ich habe ein HD-Video von einem Sprecher, der einen Vortrag hält. Ich möchte die Größe des Videos ändern, indem ich jedes Bild beschneide, aber das beschnittene Rechteck muss auf dem Kopf des Sprechers zentriert sein, wenn er sich auf der Bühne bewegt.

Ich kann eine Datei erstellen, die das X, Y, die Breite und die Höhe des zugeschnittenen Rechtecks ​​für jedes Bild im Video enthält.

Was ist der beste Weg, um diese bewegte Ernte auf das Video anzuwenden?

Es sollte funktionieren, wenn ich ..

  1. Verwenden Sie ffmpeg, um jeden Frame in einen Ordner zu extrahieren
  2. Verwenden Sie ein anderes Programm, um jede Bilddatei zuzuschneiden
  3. Verwenden Sie ffmpeg, um das Video mithilfe der zugeschnittenen Bilddateien neu zu erstellen

Gibt es einen besseren Weg, dies zu tun?

David
quelle
ImageMagick kann das Zuschneiden durchführen, wenn Sie eine numerische Beschreibung des Zuschneiderahmens haben. Ich würde vorschlagen: Exportieren als Bildsequenz mit ffmpeg, Batch-Prozess mit ImageMagick und Remux als Film in ffmpeg. Sie benötigen wahrscheinlich eine Art Shell-Scripting, um alles zusammenzukleben. Wenn Sie ein Beispiel für die Datei mit den Ernteinformationen veröffentlichen, kann ich die Details für Sie herausarbeiten.
Stib
Darf ich fragen, wie Sie diese Datei generieren? Ich arbeite an genau dem gleichen Thema. Ich habe einen Proof of Concept mit dem ffmpeg tblend-Subtraktionsfilter und dann dem Cropdetect-Filter. Ich frage mich, ob Sie einen besseren Weg haben.
Jannes

Antworten:

2

Ähnlich wie bei Gyans Overlay-Antwort kann eine etwas einfachere Version ein einfaches -filter_script mit den Filtern "Swaprect" und "Crop" verwenden. Bewegen Sie das Zuschneideziel auf 0,0 und beschneiden Sie den Zielbereich auf 0,0. Das Ziel muss auf 0,0 getauscht werden, da sich sonst das andere getauschte Rechteck überlappen kann. Dies funktionierte mit ffmpeg Version 3.4.6-0ubuntu0.18.04.1

Stellen Sie sicher, dass die Frame-Nummern relativ zum mit "-ss" übergebenen Offset sind.

Ein Beispiel für 1280 x 720 Pflanzen aus einer 4096 x 2160-Quelle. Die Quelle ist 24fps und die Tracking-Informationen sind 8fps.

Crop-Filter-Skript:

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

Ich habe bereits zu geändert avconv, also entschuldige ich mich, wenn die Antwort im klassischen ffmpeg etwas anders sein mag, aber ich glaube, dass es keinen großen Unterschied geben sollte.

Sie können einen sich bewegenden Ausschnitt haben, wenn Sie eine Formel zwischen der Rahmennummer und der Position des Ausschnitts erstellen können. Dafür stehen jedoch keine Analysetools zur Verfügung. Das heißt, wenn sich der Lautsprecher vorhersehbar bewegt, können Sie dies theoretisch ohne eine externe Anwendung tun.

Nehmen wir zum Beispiel an, dass sich der Lautsprecher im Bild von oben links nach unten rechts bewegt. Sie könnten etwas in der Art von:

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

Hier bewege ich 1 Pixel pro Frame, was sehr unwahrscheinlich ist, wie sich jemand bewegen würde.

Denken Sie daran, dass die Filterschnittstelle von avconv eine Menge mathematischer Funktionen bietet (und ich bin sicher, dass ffmpeg ähnlich ist).

Stellen Sie sich also vor, Sie möchten 1 Pixel pro Bild verschieben, jedoch nur von 200 auf 350 Bilder. Sie können dann tun

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

Für die Frames <200 max(n,200)würde 200 generiert, dann nehmen wir 200 weg, um 0 zu machen, und geben dann minden ersten Teil bis zu 350 Frames zurück, wobei dieses Ergebnis mehr als 150 werden würde und die Konstante beginnt, zurückgegeben zu werden.

Obwohl das Schreiben einer solchen Formel von Hand ziemlich mühsam wäre, kann es in einigen Fällen auch hilfreich sein.

Wenn ich jedoch die Möglichkeit hätte, auf die Software zuzugreifen, mit der Bilder Frame für Frame bearbeitet werden können, würde ich diesen Weg gehen.

v010dya
quelle
1

Vorausgesetzt, Sie haben " eine Datei, die X, Y, Breite und Höhe des zugeschnittenen Rechtecks ​​für jeden Frame enthält ", können Sie die Option filter_script verwenden, um dies in FFmpeg zu tun. Der Zuschneidefilter unterstützt keine Timeline-Bearbeitung, der Overlay-Filter jedoch. Wenn Sie also eine leere Leinwand mit der gleichen Auflösung wie Ihr Video erstellen und das Video dann mit Koordinaten überlagern, sodass Ihre beabsichtigte Region im sichtbaren Bereich überlagert ist, ist das Ziel erreicht.

Grundlegende Syntax ist

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

wo file.txtsieht das so aus:

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]

Die Leinwand Wund Hsollte den (festen / statischen) Ernteabmessungen entsprechen und gleich sein FPS. Dann wird jedes Bild des Videos mit ( - X, - Y) überlagert , sodass sich die obere linke Ecke des gewünschten Bereichs bei (0,0) der Leinwand befindet. Jede Überlagerung erfolgt für einen Frame. Wenn Sie aus Effizienzgründen Intervalle haben, in denen der Erntegut statisch ist, sollten Sie den Zwischenauswerter verwenden, z

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

Sie können auch einen Zeitstempel tanstelle eines Frame-Index verwenden.

Gyan
quelle
Ich habe versucht, diese Lösung zu implementieren, um zu sehen, wie es funktioniert. Ich wollte zu Beginn nur eine Brute-Version zum Testen, also habe ich sie nicht implementiert. Ich habe nur die Position für jeden Frame für die ersten 3000 Frames hinzugefügt. Mein ffmpeg-Speicher ist jetzt bei 36 GB und läuft mit 1 Bild pro Minute :( Ich denke, dies ist nicht die beste Lösung für pro Bild haha
Eek
Ich bin derzeit nicht in der Stadt, aber ich möchte einen Trimmfilter verwenden, um einen Frame zu isolieren und an Png auszugeben. Also n Befehle für n Frames. Dann konzentrieren Sie die Bilder auf ein Video
Gyan