AfterEffectsでRGBtoYCbCr(1)

March 12, 2012
最近また忙しくなってしまったので、こういう記事も書きにくいのですが...
現在のプロジェクトが4:2:2圧縮のかかったビデオ素材が混在しています。それら圧縮にまつわる前処理をAfterEffects上で行い、一度素材をDPXで書き出した上でNukeで作業してます。そもそも合成素材なのに4:2:2という前時代的な画質のフッテージが混じっちゃうあたりどうしたもんかなという気持ちもありますが、先方もREDが確保できなかったことを詫びていますし、フリーランスの立場なので自分が機材選定からきちんと関わっていない以上仕方ないというところ。折角の機会なので昔書いてドラフトのまま放置していたブログ記事を掘り返して公開することにしました。

そもそも4:2:2って何?という人もいるかと思いますが、ほとんどのビデオはセンサーからの出力をRGBのデータで記録しているのではなくYCbCr(デジタルの場合)あるいはYPbPr(アナログコンポーネントの場合)という信号で記録しています。ひっくるめてYUVと呼ばれたりします。正確にはひっくるめての呼称じゃなくて、策定している機関の違いだったりするんですが、この際細かいことは忘れましょう。最近であればYPbPrは忘れてもいいかと思うので(古いベーカムの素材でもなければ)、ここではYCbCrということにします...この際細かいことは忘れましょう。

「Y」が輝度信号で「Cb」「Cr」が色差信号です(「Cb」, 「Cr」はBチャンネル、Rチャンネルではなくて正確にはシアンとマゼンタです)。輝度に対してRGBを求めるときの色成分を2つの系統にわけて記録していると考えてください。Y成分だけだと白黒でCbCrというステンシルスクリーンで色塗ってます...って感じ。

ビデオ映像は記録時に一定の式に従って色のRGB各要素を変換してまず「Y」を求め、それを元に「Cb」「Cr」を求めています。なんでこんな面倒なことを...と思いますが、これ話しだすと白黒テレビまで遡っちゃうので、この際細かいことは忘れてください。昔ねこまたやさんが書かれた記事があったように記憶してたんだけど発見できず...単に居酒屋で聞いただけだったのかも。

RGBとYUVの違いをわかりやすく説明してくれてるのが

DTVかくし味 - YUVとRGBの比較
http://dtv.sakura.ne.jp/contents1/004.html

あと最近紹介した「カラーコレクションハンドブック-映像の魅力を100%引き出すテクニック-」( 関連記事 / Amazon)に詳しく書かれてます。より正確で詳細なことを知りたい場合にはこちらを参考に。

で、話がやっと戻って4:2:2圧縮の場合は輝度信号は劣化なしの状態なのですが、色差信号に圧縮がかかっています。具体的には水平方向の解像度が1/2になってます。合成やカラコレ/VFX作業を行わない「撮って出し」や送出フォーマットとしては充分な画質のですが、デジタルで合成を行うには笑っちゃうくらい劣化してます。あと勘違いしている人も多いのですが4:2:2圧縮でも中に保持できる色深度は変わりません。10bitであれば10bitの色深度を記録できます。あくまでチャンネル(信号)ごとの画素的な解像度の問題。ただし各チャンネルごと元成分のYCbCrの解像度にズレが生じてますので、キーイングやカラコレなどを作業行うと高コントラストの部分で色差ごとのズレが生じてしまいジャギーが目立ったり望ましくない色のピクセルが生じたりする場合があります。


ここでやっと本記事の本題AfterEffectsでYCbCrを扱うという話。

AfterEffectsでRGB->YCbCr(YUV)という変換をかけるには「Channel Combiner」というエフェクトを使用し「RGB to YUV」を適用します。当然YUV->RGBの逆も同エフェクトで指定できるので「RGB->YUV」の後に「YUV->RGB」をかければ元のRGB画像に戻るはずなんですが...戻らんのですよ、これが。

aechannelcombscreen_0.jpg
画面だけ見ると一見元に戻ってるっぽいのですが数値的に比較してみると、かなり差がでてしまってます。

まず元画像がこれ

aechannelcombscreen_1.jpg 「Channel Combiner」でRGB->YUV変換したのがこれ

aechannelcombscreen_2.jpg 「Channel Combiner」でRGB->YUVした後に再度「Channel Combiner」でYUV->RGB変換し、元画像と「Difference(差)」モードで重ねてExposureを+15したものがこれ

aechannelcombscreen_3.jpg 情報を見てみると数値的に差異が生じてるのがわかります("0"になってない)。

aechannelcombscreen_4.jpg 冒頭で長々書いたように、4:2:2(4:1:1)などの圧縮がかかっているビデオカメラやDSLRムービー(あとうっかりProRes422に変換されてしまった素材も...)の場合、YUVに変換して一部のチャンネル(YUVの場合は信号)を取り出して処理(例えばチャンネルブラーとか...)をかけ、もとのRGBに戻したいということがあります。


AfterEffectsの「Channel Combiner」エフェクトで変換->逆変換で差が出てしまうのは、このエフェクトが32bit floatに対応しておらず内部の整数変換プロセスで誤差が生じているためだと思います(要は係数の精度が低い)。もちろん見た目にはそれほど深刻な問題は生じていないのですが、これらの処理は元素材への前処理として加えることが多いので、画質はできるだけ維持したいというのが本音。ちなみにfloatで計算されるShakeとかNukeではこの問題は生じません。Shakeは8bitでも差が出てこないので多分内部の計算精度が高いんじゃないでしょうか(ちゃんと確認してませんけど_。今回はあくまでAEをターゲットにしたお話なので、ShakeやNukeやFlareやSmoke使えばいいじゃんというのはナシの方向で。

...と、駄目なパターンですけどここから先はまだ原稿書いてないので、ここで続く。


[関連記事]
AfterEffectsでRGBtoYCbCr(2)
GH2 Chroma fix
HS_422Chromafix for Nuke
カラーコレクションハンドブック-映像の魅力を100%引き出すテクニック-