⚠️ これは 非公式の翻訳サイトです。ImageMagick Studio LLC とは無関係です。正確な情報は 原文(https://usage.imagemagick.org/video/index.html) を参照してください。

ImageMagick 使用例 -- 動画の取り扱い

ImageMagick 使用例 前書きと索引
動画から GIF へ、最適化のまとめ
動画フレームのインターレース解除

ImageMagick はデジタル動画の取り扱いに特に向いているわけではありませんが、特に Linux 環境ではこの目的によく使われています。ここでは、実写(およびレイトレーシングによる)動画シーケンスの取り扱いに特有のテクニックや例を探っていきます。


動画から GIF へ、最適化のまとめ

IM を使ってムービー GIF を作成しているソフトウェア開発者の Benoit Rouleau 氏が、私との議論の中で、IM の動画変換テクニックを相互に探るのを手伝うために、飛行機が上を飛び去る AVI 動画をくれました。しかし AVI 自体は非常に小さいものの、非圧縮の動画は [IM Text] バイトという巨大なサイズで、[IM Text] フレームにわたって [IM Text] 色を含んでいます。しかし IM はこの動画を GIF アニメーションに変換するのにまったく苦労しません。ただし、おそらく未対応の 'AVI chunk' エラーがいくつか出ることに注意してください。これは "[-quiet](https://imagemagick.org/command-line-options/#quiet)" 制御設定 を使うことで無視できます。 |

  magick -quiet -delay 1 plane.avi plane.gif

[IM Output]
これは ImageMagick のデフォルトの 色の量子化とディザリング 手法を使い、この動画を非常に妥当な品質で変換しました。元の動画が非常に少ない色しか使っていないため、色の問題はほとんど起きていません。これは常にそうとは限りません。特に GIF にはフレームあたり 256 色という制限があるためです。しかしアニメーションファイルは [IM Text] バイトのサイズで、色削減と GIF のピクセルデータ圧縮のおかげで元の 1/5 のサイズになっているとはいえ、まだかなり大きいものです。さらに、できあがったアニメーションをよく調べると、画像中の [IM Text] フレームのうち、[IM Text] フレームが独自の ローカルカラーテーブル を追加されていることがわかります。つまり、GIF アニメーション内の各フレームがそれぞれ独自のカラーインデックステーブルを必要としたのです。すなわち、(GIF フォーマットの制限により)各フレームは 256 色未満であるものの、アニメーション全体では合計 [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 アニメーションを生成するより良い方法は、アニメーションに対して '最良の' グローバルカラーテーブルを生成するのではなく、単に汎用的な色の範囲を与えることです。元の動画にどんな色が含まれていてもうまく機能するものを使います。こうするもう一つの理由は、色選択に深刻な悪影響を与えたり、各フレームにローカルカラーテーブルを使う羽目になったりすることなく、動画を長くできるからです。各フレームは、アニメーション内の他のフレームが何であるかとは完全に独立して、同じカラーマップにディザされます。 ここでは '332' カラーマップ を使います。これは透明色が不要な場合に非常に良い標準カラーマップと一般に見なされています。私はこのカラーマップ(あるいは 219 色の 'ウェブセーフ' カラーマップ)がさまざまな動画フォーマットでよく使われるのをしばしば見てきました。 |

  magick -quiet -delay 1 plane.avi -remap colormap_332.png plane_ugc.gif

[IM Output]
このアニメーションは [IM Text] のローカルカラーテーブルを持ち、その結果アニメーションはより小さく [IM Text] バイトのサイズになります。しかし問題は、一定の色の領域でしばしば明白で煩わしい 'ノイズ' が見えることです。このノイズは、これまでの全ての動画アニメーションにも存在していました。より汎用的で、それゆえより広く分散したカラーマッピングを使ったことで、今になって初めて見えるようになっただけです。このノイズは実際には、画像を再生成する際の削減された色集合へのディザリングによって引き起こされます。しかしこれはフレームごとに変化する擬似ランダムな色のパターンを生成し、結果として画像に背景ノイズのような見え方をもたらします。なぜこれが起こるかの詳細については E ディザの問題点 を参照してください。 'ディザノイズ' を除去するために、単に色のディザリングをオフにすることもできます… |

  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]
上記ではまた、全ての画像がまったく同じグローバルカラーマップ(秩序ディザがすでに最大 256 色に削減済み)を使うようにするために "[+remap](https://imagemagick.org/command-line-options/#remap)" 演算子を使いました。色数はすでに最適なので、"[+remap](https://imagemagick.org/command-line-options/#remap)" 演算子はディザも色削減も行いません。できあがるディザパターンはランダムではなく、あるフレームから次のフレームへ大きく変化しません。こうして 'ディザノイズ' がアニメーションから除去され、フレームからフレームへと固定された色のパターンになります。このパターンはまた非常に反復的で、はるかに良い圧縮を可能にします。そして最後に、カラーマップが固定されているため、どんな動画を使ってもそれなりにうまく機能するはずです。

より高品質な秩序ディザ動画

しかしこの特定の動画は、主にさまざまな青の濃淡という、わずかな範囲の色しか使っていないため、汎用の一様なカラーマップが提供する色の多くを実際には使っていません。実際、最後の動画アニメーションでは [IM Text] 色しか使われていませんでした! これは極めて少なく、それゆえかなり目立ちます。しかしこれはまた、この特定のアニメーションが秩序ディザ操作で多数の '色レベル' を使うことで恩恵を受けられ、全体的な品質を向上できることを意味します。ただしまず、GIF ファイルフォーマットとグローバルカラーマップの再マッピングの両方が課す 256 色の制限に達する前に、アニメーションがいくつの色レベルを扱えるかを判断する必要があります。しかし厄介なのは、これらを限られた GIF フォーマットにアニメーションを保存する に判断しなければならないことです。そして以下が私の使うコマンドです…

    magick -quiet plane.avi -ordered-dither o8x8,23 -append -format %k info:

[IM Text]

基本的には、必要な 256 色の制限にちょうど収まる数値が得られるまで、使う色レベルの数を増やしたり減らしたりしました。 そうして見つけた '色レベル' の選択を plane アニメーションに適用できます。 |

  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 フォーラムに連絡してください。あなたの意見、テクニック、議論を聞いたり、あなたが抱える特定の動画/アニメーションの問題を見たりできれば、とても嬉しく思います。 そうした議論の一つが アニメ GIF で量子化のための「正しいレベル」を見つける です。

Giflossy 圧縮 LZW 最適化

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

  gifsicle -O3 --lossy=80 --colors 256 plane.gif -o plane_giflossy.gif

これは [IM Text] バイトという、まったく驚くべきサイズになります。秩序ディザを使って達成したものほど高品質ではありませんが、サイズは半分未満です。 [IM Output]
上記の結果に勇気づけられて、私は GifLossy を、得られた最良の秩序ディザ結果に適用し、さらに小さくできるか試してみることにしました。 |

  gifsicle -O3 --lossy=80 plane_od2.gif -o plane_od2_giflossy.gif

そして実際に [IM Text] バイトという、さらに小さなサイズが得られました。残念ながら、私たちが以前あれほど苦労して達成した高品質な秩序ディザの結果を、基本的に失ってしまいました。これは残念です。 [IM Output]


動画フレームのインターレース解除

すべての画像がデジタルカメラから来るわけではありません。CCD でない動画カメラからのデジタル動画フィードから画像を抽出するのは非常によくあることです。これらの画像はテレビに直接表示するためにインターレースされており、その結果、1 行おきに画像の異なるフレームになっています(インターレース)。物が動いていない 2 つのフレームでは、インターレースは通常それほど目立ちません。おそらく画像にわずかなエッジのぼやけを生じるくらいです。しかし速く動く物体が関わると、できあがるインターレース画像は、2 つのフレームが合成されているために非常に違和感のあるものになります。 Wolfgang Hugemann Auto@Hugemann.de(ドイツ)氏はこの問題を抱えており、彼自身が撮影した 衝突試験 のスナップショットを私に送ってくれました。ただしデモのためには、これから切り出した小さい画像を使います。テクニックはフルサイズの画像でも機能します。 |

    magick video_frame.png  -crop 100x100+200+470 +repage  interlaced.png

[IM Output]
| Wolfgang Hugemann 氏は元の動画フレームに TIFF フォーマットを使いましたが、私は IM Examples で使うためにこれを PNG に変換しました。処理を終えるまでこれらの画像に JPEG を使う誘惑に駆られないでください。この処理に必要な低レベルの品質を破壊してしまうからです。
---|---
ご覧のとおり、インターレースは 2 つの別々のフレームを示しています。これはインターレースされた PAL デジタル動画シーケンス(毎秒約 50 ハーフフレーム)から来ているためです。そう、車は非常に速く動いており、カメラは高速シャッターを使っていて、非常に高品質な動画画像を生み出しています。できあがった画像は 2 つの織り合わされたハーフフレームで、ハーフフレーム間の 1/50 秒という間の時間に、車のサイドミラーがかなりの距離を移動しています。 ここでは、インターレースされたハーフフレームの一方(1 行おき)を単に白で置き換えます。これは 'BoB' フィルタとして知られる標準的なインターレース解除手法です。これは Wolfgang 氏が IM Examples のために寄稿してくれました。 |

  magick interlaced.png  -fx "floor(j/2)==j/2 ? u : 1"  deinterlace_1.png

[IM Output]
さて FX 演算子 は遅いので、代替手段は '縞模様の画像' を作成することです。そのような画像は、特殊な "pattern:Horizontal2" 組み込み画像から生成できます。 その画像は次に、'[Screen](compose.html#screen)' 合成手法を使って元の画像に重ねて白い線を重ねたり、あるいは '[Multiply](compose.html#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]
ピクセル化テクニック を使って画像を縮小・拡大し、1 行おきに 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](https://imagemagick.org/command-line-options/#roll)" する必要があったでしょう。