ImageMagick の例 --
ビデオ処理

目次
ImageMagick の例:序文と目次
ビデオから GIF へ、最適化の概要
ビデオフレームのインターレース解除
ImageMagick はデジタルビデオ処理に特に適しているわけではありませんが、特に Linux 環境ではこの目的でよく使用されます。ここでは、現実の(そしてレイトレーシングされた)ビデオシーケンスの処理に特化したテクニックと例を探求します。

ビデオから GIF へ、最適化の概要

IM を使用してムービー GIF を作成するソフトウェア開発者である Benoit Rouleau 氏との議論の中で、彼から 飛行機が飛んでいる AVI ビデオを提供していただき、IM ビデオ変換技術を相互に調査するのに役立てました。ただし、AVI 自体はかなり小さいものの、非圧縮ビデオは巨大な [IM Text] バイトのサイズであり、[IM Text] 色、[IM Text] フレームで構成されています。
しかし、IM はこのビデオを GIF アニメーションに変換するのに実際には問題ありません。ただし、「-quiet制御設定を使用することで無視できる、サポートされていない「AVI chunk」エラーが発生する可能性があることに注意してください。

  magick -quiet -delay 1 plane.avi plane.gif
[IM Output]
これは ImageMagick のデフォルトの カラー量子化とディザリングメソッドを使用して、非常に妥当なビデオ変換を生成しました。ビデオはごく少数の色を使用しているため、カラーの問題はほとんどありません。これは常に当てはまるわけではなく、特に GIF にはフレームごとに 256 色の制限があるためです。ただし、アニメーションファイルは [IM Text] バイトのサイズであり、色の削減と GIF ピクセルデータ圧縮により、わずか 1/5 のサイズですが、それでもかなり大きいです。また、結果のアニメーションをさらに調べると、画像の [IM Text] フレームのうち、[IM Text] フレームが独自の ローカルカラーテーブルを追加したことがわかります。つまり、GIF アニメーションのすべてのフレームには、独自のカラーインデックステーブルが必要でした。つまり、各フレームには 256 色未満の色(GIF 形式の制限による)がありますが、アニメーション全体では合計 [IM Text] 色を使用しています。残念ながら、GIF 形式はカラーテーブルを圧縮しないため、これらの余分なカラーテーブルは最大で次のスペースを使用する可能性があります。 256 色 * 1 色あたり 3 バイト * 106 フレーム。または 81,408 バイトのファイルスペース。1G バイトのビデオではそれほど多くはありませんが、特にビデオをさらに最適化する際にはかなりの量のスペースになります。これに加えて、アニメーションは GIF フレームの最適化があまりうまくありません。背景が動いている(カメラが上向きにパンしているため)だけでなく、IM が エラー訂正ディザ(ヒルベルト曲線ディザ)を使用したため、フレームごとに異なる疑似ランダムな色のパターンが生成されるためです。後の例では、この「ディザノイズ」がはるかに目立つようになります。

共通グローバルカラーテーブル

ここでは、ビデオのすべてのフレームに対して、単一のグローバルカラーテーブルを生成します。

  magick -quiet -delay 1 plane.avi  +remap   plane_cgc.gif
これにより、当然ながら [IM Text] のローカルカラーテーブルと、[IM Text] バイトのファイルサイズになります。
[IM Output]
ご覧のとおり、結果のアニメーションには余分なローカルカラーテーブルはありません。代わりに IM は、アニメーションのすべてのフレームに基づいて「最適な」色の [IM Text] の単一のグローバルカラーテーブルを生成しました。残念ながら、これにより、以前ほどピクセルデータがうまく圧縮されなくなり、より強力なディザリングが必要になりました。その結果、以前とほぼ同じサイズの、少し見劣りするアニメーションになります。この特定の色数が限られたビデオでは、問題なく使用する色数をさらに 64 色に減らし、さらに小さなアニメーションファイルサイズを生成することもできました。ただし、これは使用するビデオシーケンスに大きく依存しており、見栄えがあまり良くない可能性があります。特に多くの色と複数のシーンを使用するビデオを扱う場合、独自ビデオの結果が良くなる場合もあれば、悪くなる場合もあります。

普遍的なグローバルカラーテーブル

「より小さな」GIF アニメーションを生成するためのより良い方法は、アニメーションに最適なグローバルカラーテーブルを生成するのではなく、一般的な普遍的な色の範囲を提供するだけです。元のビデオにどのような色が存在する場合でもうまく機能するはずの色を使用します。これを行うもう 1 つの理由は、カラー選択に深刻な悪影響を与えることなく、またはフレームごとにローカルカラーテーブルに頼ることなく、ビデオを長くすることができるためです。各フレームは、アニメーション内の他のフレームとは完全に独立して、同じカラーマップにディザリングされます。
ここでは、透明度が必要ない場合に非常に優れた標準カラーマップと見なされている 「332」カラーマップを使用します。さまざまなビデオ形式でこのカラーマップ(または 219 色の 「ウェブセーフ」カラーマップ)がよく使用されているのを見てきました。

  magick -quiet -delay 1 plane.avi -remap colormap_332.png plane_ugc.gif
[IM Output]
このアニメーションには、[IM Text] ローカルカラーテーブルがあり、その結果、アニメーションは小さくなり、[IM Text] バイトのサイズになります。ただし、問題は、一定の色領域で目立つ迷惑な「ノイズ」がよく見えることです。このノイズは、以前のすべてのビデオアニメーションにも存在していました。これは、より普遍的であるため、より広く分散したカラーマッピングを使用している場合にのみ表示されます。ノイズは、画像を再生成するときに、減色されたカラーセットをディザリングすることによって実際に発生します。ただし、これにより、フレームごとに変化する擬似ランダムな色のパターンが生成され、画像にバックグラウンドノイズが表示されます。この理由の詳細については、E-Dithers の問題を参照してください。
「ディザノイズ」を削除するために、カラーディザリングをオフにするだけで済みます...

  magick -quiet -delay 1 plane.avi \
          +dither -remap colormap_332.png plane_ugc_nd.gif
これにより、[IM Text] ローカルカラーテーブルがあり、サイズが [IM Text] バイトになります。
[IM Output]
結果のアニメーションは、元のサイズ 1/60 と非常に小さくなっています。これは、一般的に、ソリッドカラーの広い範囲が非常に優れたピクセル圧縮を生み出すためです。しかし、ディザノイズは修正され、ファイルサイズは非常に小さくなりますが、代わりにカラーバンディングが発生し、これは一般的に非常に悪いトレードオフと見なされています。

順序ディザリングビデオ

真の解決策は、フレームごとに異なるパターンを生成しない異なるカラーディザリング技術を使用することです。
たとえば、ここでは、同じ普遍的な 「332」カラーマップをディザリングするために、ポスタライズされたカラーレベルを使用した順序ディザリングを使用しました。

  magick -quiet -delay 1 plane.avi \
          -ordered-dither o8x8,8,8,4 +remap plane_od.gif
これにより、[IM Text] ローカルカラーテーブルがあり、サイズが [IM Text] バイトになります。
[IM Output]
上記では、すべての画像がまったく同じグローバルカラーマップを使用するようにするために、「+remap」演算子も使用しました(順序ディザリングは既に最大 256 色に減らしました)。色の数がすでに最適であるため、「+remap」演算子は、ディザリングや減色を行いません。結果のディザパターンはランダムではなく、フレームごとに大きく変化しません。したがって、「ディザノイズ」がアニメーションから削除され、フレームごとに固定されたカラーパターンになります。このパターンも非常に反復的であるため、はるかに優れた圧縮が可能になります。そして最後に、カラーマップが固定されているため、どのビデオを使用しても合理的にうまく機能するはずです。

より高品質の順序ディザリングビデオ

ただし、この特定のビデオは、主にさまざまな色合いの青の色を使用して、限られた色の範囲のみを使用するため、一般的な均一なカラーマップで提供される多くの色を実際には使用しません。実際、前回のビデオアニメーションでは、わずか [IM Text] 色しか使用されていませんでした。これは非常に低いため、かなり目立ちます。しかし、これはまた、この特定のアニメーションが、順序ディザリング操作で多数の「カラーレベル」を使用することからメリットを得て、全体的な品質を向上させることができることも意味します。ただし、最初に、GIF ファイル形式とグローバルカラーマップの再マッピングの両方によって課せられる 256 色の制限に達する前に、アニメーションが処理できるカラーレベルの数を判断する必要があります。ただし、難しい部分は、アニメーションを制限された GIF 形式に保存する前に、これらを決定する必要があることです。そして、これが私が使用するコマンドです...

    magick -quiet plane.avi -ordered-dither o8x8,23 -append -format %k info:
[IM Text]
基本的に、必要な 256 色の制限内に収まる数値が得られるまで、使用するカラーレベルの数を増やしたり減らしたりしました。
次に、発見した「カラーレベル」の選択を飛行機のアニメーションに適用できます。

  magick -quiet -delay 1 plane.avi \
          -ordered-dither o8x8,23 +remap plane_od2.gif
これにより、[IM Text] ローカルカラーテーブルがあり、サイズが [IM Text] バイトであり、[IM Text] 色になります。
[IM Output]
ご覧のとおり、非常に高品質で、順序化されたディザリングビデオが生成されました。これは、以前に生成した「最適なカラーマップ」グローバルカラーマップバージョンと同等ですが、サイズは1/3小さく、「ディザノイズ」ははるかに見えにくくなっています。もちろん、品質が非常に高いため、低品質バージョンほど圧縮できないため、ファイルサイズが大きくなります。一方、使用する「カラーレベル」の数という形で、品質とファイルサイズのトレードオフを適切に制御できるようになりました。この手法は、使用する色が多すぎないアニメーションの特殊なケースであることを覚えておいてください。また、フレームを追加してビデオを長くすると、色も増えるため、「カラーレベル」の品質制御を低下させる必要があります。これは、一般的なGIFアニメーションでこれまで見た中で最高のカラー最適化方法です。「ディザノイズ」を排除し、品質を制御でき、フレーム最適化などの他のGIFアニメーション最適化方法を使用する機能も保持しています。

圧縮(透過性)の最適化

このビデオではパンニングカメラを使用しているため、ビデオの背景がフレームごとに変化します。つまり、GIFアニメーションはフレーム最適化をあまりうまく実行できません。
ただし、単純な透過性最適化を使用して、GIFアニメーションの最終的なサイズをさらに削減できます。

  magick plane_od2.gif  -layers OptimizeTransparency +remap plane_opt.gif
結果は、サイズが[IM Text]バイトで、色が[IM Text]色です。
[IM Output]
つまり、透明なカラーインデックスである1つの追加の色が画像に追加され、現在表示されている色を変更しないピクセルはすべて透明にされました。これにより、元の動画に大きな透明領域と、同様のピクセルシーケンスの繰り返しが生成され、最終的なGIF画像でLZW圧縮が改善されます。悪くありません。アニメーションは、GIFへの直接変換の半分になり、それでもかなり高品質です。上記に追加したり、それらをさらに改善する手法について議論したい場合は、私またはIMフォーラムにご連絡ください。皆様の意見、手法、議論について喜んでお聞きします。または、特定の動画/アニメーションの問題について検討します。そのような議論の1つは、アニメーションGIFでの量子化のための「適切なレベル」を見つけるです。

Giflossy圧縮LZW最適化

元のGifsicleプログラムのフォークである新しいツール、GifLossyは、LZWが画像をより多く圧縮できるように各フレームの色を変更します。
たとえば、ここで、元のGIFアニメーションにそれを適用して、色を単一の256色テーブルに減らすように求めました。

  gifsicle -O3 --lossy=80 --colors 256 plane.gif -o plane_giflossy.gif
これにより、[IM Text]バイトという驚くべきサイズになります。順序化されたディザリングを使用して達成したものほど高品質ではありませんが、サイズは1/2未満です。
[IM Output]
上記の結果に勇気づけられて、さらに小さくできるかどうかを確認するために、最高の順序化されたディザリング結果にGifLossyを使用することにしました。

  gifsicle -O3 --lossy=80 plane_od2.gif -o plane_od2_giflossy.gif
そして、[IM Text]バイトというさらに小さなサイズになりました。残念ながら、以前に実現するために非常に努力した高品質の順序化されたディザリング結果を基本的に失いました。これは残念です。
[IM Output]


ビデオフレームのデインターレース

すべての画像がデジタルカメラからのものではありません。非CCDビデオカメラからのデジタルビデオフィードから画像を抽出することは非常に一般的です。これらの画像は、テレビに直接表示するためにインターレースされており、その結果、2番目のすべての線が画像の別のフレームになっています(インターレース)。物事が動いていない2つのフレームの場合、インターレースは通常あまり目立ちません。おそらく、画像のわずかなエッジのぼかしのみを生成します。しかし、動きの速い物体が関与している場合、インターレースされた結果の画像は、2つのフレームがマージされているため、非常に不快になります。
ヴォルフガング・ヒューゲマン <Auto@Hugemann.de>(ドイツ)は、この問題を抱えており、ヴォルフガング自身が撮影したクラッシュテストのスナップショットを送ってくれました。ただし、デモンストレーションのために、この画像から切り抜いた小さい画像を使用します。ただし、これらの手法はフルサイズの画像で機能します。

    magick video_frame.png  -crop 100x100+200+470 +repage  interlaced.png
[IM Output]
ヴォルフガング・ヒューゲマンは元のビデオフレームにTIFF形式を使用しましたが、IM Examplesで使用するためにこれをPNGに変換しました。このプロセスのために必要な低レベルの品質が損なわれるため、処理が完了するまでこれらの画像にJPEGを使用しないでください。
ご覧のとおり、インターレースは2つの別々のフレームを示しています。これは、インターレースされたPALデジタルビデオシーケンス(1秒あたり約50のハーフフレーム)から来ているためです。はい、車は非常に速く移動しており、カメラは高速シャッターを使用しており、非常に高品質のビデオ画像を作成しています。結果の画像は、車のサイドミラーがハーフフレーム間の1/50秒の間隔でかなり移動した、2つの相互に織り込まれたハーフフレームです。
ここでは、インターレースされたハーフフレーム(2番目のすべての線)の1つを白に置き換えるだけです。これは、「BoB」フィルターとして知られる標準的なデインターレース法です。これは、IM Examplesのためにヴォルフガングによって提供されました。

  magick interlaced.png  -fx "floor(j/2)==j/2 ? u : 1"  deinterlace_1.png
[IM Output]
さて、FX演算子は遅いため、別の方法として「ストライプ画像」を作成します。そのような画像は、特別な「pattern:Horizontal2」組み込み画像から生成できます。
その画像は、元の画像と重ね合わせることができ、「Screen」合成法を使用して白い線を重ねたり、「Multiply」または黒い線を重ねます。例:

  magick -size 100x100 pattern:Horizontal2 \
          interlaced.png -compose Multiply -composite  deinterlace_2.png
[IM Output]
パターンを否定すると、インターレースされた画像のもう一方の半分を選択できます。または、「Multiply」を「Screen」に変更すると、白い背景でフレームを抽出できます。
別の方法として、欠落しているフレーム線を前の線を複製するだけで埋めようとしました。

    magick interlaced.png  -fx "u.p{i,j-j%2}"  deinterlace_3.png
[IM Output]
ピクセル化技術を使用して、画像を縮小および拡大して、2番目のすべての線を2倍にすることもできます。

    magick interlaced.png -sample 100%x50% \
                           -sample 100%x200%  deinterlace_4.png
[IM Output]
また、わずかなバリエーションで、両側の線を組み合わせて、サイズ変更の拡大の一部としてハーフフレーム画像を垂直方向に平滑化することもできます。

    magick interlaced.png -sample 100%x50% \
                           -resize 100%x200%  deinterlace_5.png
[IM Output]
結果は、インターレースされたビデオ画像の1つのフレームの特に素晴らしい抽出です。
画像からもう一方のハーフフレームを抽出する場合は、「sampling:offset」(IM v6.8.4-7以降)を調整できます。

    magick interlaced.png -define sample:offset=75 \
            -sample 100%x50%  -resize 100%x200%    deinterlace_6.png
[IM Output]
このバージョンのIMより前は、同じ結果を得るには画像を1ピクセル「-roll」する必要がありました。