jpg画像シーケンスをffmpegでビデオに可逆的にエンコードする方法は?


21

私は大量のjpgをロスレスでビデオに変換したい(または、少なくとも、エンコード時間がそれほど長くない限り、ロスレスに非常に近い)。

単純に、個々のjpgフレームを(再圧縮せずに)そのまま保存できるコーデックが必要であり、おそらくいくつかのフレームを前のフレームからのデルタの情報だけで置き換えることでいくつかの素晴らしい圧縮を実現できると思います。私の場合、互いに同一の、またはそれらの間にわずかな違いがある多くのフレームのシーケンスがあります。

これを実現できるffmpegのコーデックと適切な設定はありますか?




1
sequence-of-jpegsは長い間コーデックです。h.264を使用しないデジタルカメラは常にMJPEGを記録し、ビデオキャプチャカードはそれを使用していたと思います。
ピーターコーデス

回答:


24

画像を多重化するだけ

単にJPG画像を多重化してビデオを作成できます。

ffmpeg -framerate 30 -i input%03d.jpg -codec copy output.mkv

省略する-framerateと、デフォルトの-framerate 25が入力に適用されることに注意してください。

ロスレス最適化

あなたは使用することができjpegtran、各フレームにロスレス最適化を実行することが重要なファイルサイズの削減を提供します。

mkdir outputdir
for f in *.jpg; do jpegtran -optimize -copy none -perfect -v "$f" > "outputdir/$f"; done

ffmpeg上記のように、muxを使用します。

実際にロスレスであることを確認する

framehashミュクサーは結果が真に可逆であることを保証するために、各フレームの一意のハッシュを比較するために使用することができます。

$ ffmpeg -i input%03d.jpg -f framehash -
stream_index, packet_dts, packet_pts, packet_duration, packet_size, hash
0,          0,          0,        1,   460800, 29bcc2db3726c7dfec1826c5740f603f
0,          1,          1,        1,   460800, b5fdc23d93cbd043dc2b9290dc8378f0
0,          2,          2,        1,   460800, ee0709942f24b458fd2380d134dcb59d
...

$ ffmpeg -i output.mkv -map 0:v -f framehash -
stream_index, packet_dts, packet_pts, packet_duration, packet_size, hash
0,          0,          0,        1,   460800, 29bcc2db3726c7dfec1826c5740f603f
0,          1,          1,        1,   460800, b5fdc23d93cbd043dc2b9290dc8378f0
0,          2,          2,        1,   460800, ee0709942f24b458fd2380d134dcb59d
...

上記の例では、入力と出力に関連付けられた各フレームは同じハッシュを共有し、フレームが同一であり、出力がロスレスであることを保証します。

こちらもご覧ください


framemd5単にハッシュをリストするだけでなく、2つのコマンドが何を達成するのかを明確にしてください。このように同一のフレームが識別された場合、どのようにして追加の圧縮を取得しますか?
GJ。

1
ハッシュは、フレームが個々の画像と同じであることを示すためにのみ含まれているため、「個々のjpgフレームをそのまま(再圧縮なし)」保存するという要件を満たします。
-llogan

VFR MJPEG.mkvで終わるために、重複フレームをドロップするためのテストされていないアイデアで私自身の答えを投稿しました。VFRは、MJPEGで一時的な冗長性を利用する唯一の方法です。:P
ピーターコーデス

SSIMを使用すると、忠実度をより迅速に比較できます。
ギャン

11

これにより、フレームが他のフレームからの情報を使用するロスレスH.264ビデオが出力されます

ffmpeg -f image2 -r 30 -i %09d.jpg -vcodec libx264 -profile:v high444 -refs 16 -crf 0 -preset ultrafast a.mp4

オプションの説明:

  • -f image2 -ffmpegに画像のグループを選択するよう指示します
  • -r 30 -ffmpegに1秒あたり30フレーム(または画像)でエンコードするように指示します(これを目的のフレームレートに変更します)
  • -i %09d.jpg-ffmpegに画像000000000.jpgから999999999.jpgを入力として使用するように指示します。9in %09d.jpgを、画像シーケンスの名前が持つゼロの数に変更します。たとえば、ファイル名がimg0001.jpgの場合、これはimg%04d.jpgとして表されます。
  • -vcodec libx264 -ffmpegにH.264準拠ファイルへの出力を指示します
  • -profile:v high444 -libx264に高4:4:4予測ロスレスプロファイルを使用するように指示し、ロスレスエンコーディングを許可します
  • -refs 16 -libx264に16個の画像をバッファに保存するように指示し、ビデオ内の他の画像から参照できるようにします
  • -crf 0 -ロスレスエンコードを実行するようlibx264に指示します
  • -preset ultrafast -出力ファイルサイズよりもエンコード速度を優先するようにlibx264に指示します
  • a.mp4-a.mp4というMP4ファイルに出力を保存するようにffmpegに指示します。これを使用するファイル名と形式に変更します

3
いくつかのメモ:-f image2ここでは不要です。画像ファイルデマルチプレクサは、使用する必要があります-framerate代わりに-r。libx264は-profile、ロスレスに適したものを自動的に選択し、-presetに対処し-refsます。
llogan

-refs 5MOSTでは、コンテンツに他のいくつかのイメージで区切られた同一のイメージがあることがわかっていない限り、x264が参照を失う可能性があります。より高いultrafast(ロスレスに必要なビットレートで高いCPUコストのため)CAVLCオーバーCABACの〜10%のゲイン以外の可逆モードでは少し違います。真剣に、いくつかの実写720x480p60(インターレース解除出力)では、superfast28GB、slower27GBでした。エンコード時間は重要ではなく、デコード時間は重要な場合は、CABACを避けてください。たぶん-tune fastdecode。中程度のrefカウントは害になりません。
ピーターコーデス

また、CPUを燃やす必要がある場合-preset placeboは、数パーセントの余分な割合を試すこともできます。
DrYak

また、完全性のために、h265にも独自のロスレスモードがあります。-vcodec libx265 -x265-params lossless=1同等のオプションです。(ただし、私の経験では(= Powerpointスライドショープレゼンテーションの記録)、必ずしも優れているわけではなく、h264よりもずっと遅いです) ...のロスレスモード
DrYak

5

avi一連のpng画像としてアニメーションを作成できます(ロスレスなので、変換によって画像png jpeg => png劣化することはありません):

画像が名前付きの場合 img_0001.jpg

ffmpeg -r 25 -start_number 1 -f image2 -i "img_%04d.jpg" -vcodec png video.avi

「25」は、結果のビデオに必要なフレームレートです。-start_number1の場合は不要ですが、最初のビデオ番号が1でない場合に役立ちます。

mjpeg最高品質のコマンドラインでエンコードしたい場合:

ffmpeg -r 25 -start_number 1 -f image2 -i "img_%04d.jpg" -vcodec mjpeg -qscale 1 video.avi

そして、その魅力は、ビデオをシリーズの写真に変換できることです。

ffmpeg -i video.avi "img_series_%04d.png"
ffmpeg -i video.avi "img_series_%04d.jpg"

等...


これは、依頼者のニーズを実際に満たしていません。彼は、画像が変更された場合にのみフレームを損失なく更新できる方法を探しています。これは、同じ画像を複数回使用できることを意味します。また、jpegは本質的にロスレスではありません。最高品質であってもjpeg圧縮を使用していると信じているからです。
AJヘンダーソン

実際には、同じフレームの長いシーケンスでどのように圧縮されるかはわかりませんが、彼はある程度の圧縮を喜んでいたと思います。ffmpegがサポートしているかどうかはわかりませんが、可変フレームレートのプレゼンテーション形式が必要だと思います。
AJヘンダーソン

CorePNGはPフレームも作成できます。通常、jpegは可逆圧縮ではありません。mjpegがPフレームを作成できるとは思いません。質問されたとおりに質問に答えないことに同意しますが、ffmpegでロスレスビデオを作成するための解決策を示します。
オリビエS

4

LordNeckbeardの答えを拡張するには、はい、JPEGデータをMJPEGビデオストリームに多重化します。MJPEGは今日の標準では非常に非効率的なコーデックですが、これは出力画像の正確なシーケンスの最小の表現になります。(時間的冗長性はなく、イントラ予測さえありません。

可変フレームレートのMJPEGビデオを作成して、入力の重複画像を活用できます。

ffmpeg -framerate 30 -i input%03d.jpg -vf mpdecimate -codec copy output.mkv  # doesn't work.

Hrm、これは機能しません。mpdecimateは圧縮データでは機能せず、ffmpegで画像データをデコードしてから再JPEGすることは、損失とCPUコストなしでできないためです。

重複したjpgソースファイルをそのシーケンス番号の空のファイルなどに置き換えたとしたらどうでしょうか。

この質問は最近のものではないので、誰かが方法を尋ねる応答をしない限り、時間をかけてその方法を理解するつもりはありません。しかし、MJPEGはmkvコンテナーに入ることができるため、繰り返されるフレームのjpegデータを複製せずに、複製のシーケンスが完了するまでデコードする出力フレームを持たないファイルを作成することができると確信しています以上。

アイデアは次のとおりです。

ffmpeg -framerate blah -input blah -vf mpdecimate -f mkvtimestamp_v2 mpdecimate.timestamps

次に、mpdecimateがドロップしたいフレームのすべてのjpegを削除(または移動)します(おそらくログオプションがありますか?または-vf showinfo、それを解析し、出力に表示されるフレームのみを移動またはハードリンクして、残しますドロップされたJPEG?)。それをMJPEG.mkvに多重化し、mkvmergeで何かをして、そのフレームのタイムスタンプをからのタイムスタンプに置き換えmpdecimate.timestampsます。

jpegデータをMJPEGに多重化するのではなく、xcodingを使用していた場合、mpdecimateおよび以外のコーデックで最初のコマンドを使用するだけでcopy、Just Work(tm)になるため、これは非常に簡単になります。

これは古い質問だったので、私はこれを試したことはありません。また、mpdecimate出力に基づいてjpegのディレクトリを実際にフィルタリングする方法や、タイムスタンプストリームを実際に使用する方法のギャップを埋めていない理由もあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.