WebカメラのYUY2やNV12、MJPEGとは何なのか
Webカメラは解像度やフレームレートなどの性能面で選ぶ人が多いと思う。その際、解像度が高くても、Webカメラのコーデックをきちんと見ておかないと、PCに負荷がかかったりすることもある。コーデックとは一体何なのだろうか。
コーデックにより、画質は異なる
この「技術仕様」はLogicoolのStreamcamの仕様となっている。最大の解像度は1920x1080で、フレームレートは60fpsで出すことができるという。
「サポートされるフレームレート」をよく見ると、コーデックによってフレームレートに差があることがわかる。MJPEGでは最大60fps、YUY2やNV12では30fpsとなっている。
まずYUY2とは4:2:2クロマサブサンプリングでサンプルされた無圧縮の形式であり、NV12は4:2:0クロマサブサンプリングの形式である。
と書いても、多くの人にはあまりピンとこないだろうから、クロマサブサンプリングから説明する。
お絵描きをする人やCSSを書いた人ならわかるが、コンピューターの世界ではRed Green Blue = RGBで赤緑青の割合によって色をつけることが多い。しかし映像や画像では、輝度(Y)と、そこから青(Cb)と赤(Cr)の差分を取った色表現(=YCbCr色空間)を使うことが多い。これはモノクロのアナログテレビの時代、元々輝度(Y)だけが伝送されていたが、後々カラー化をしたいときに色差を送ればカラー化できそうだ!として編み出された手法だ。この方法により、カラーテレビ番組を実現しながら、古いモノクロテレビでも(もちろんモノクロだが)そのまま番組を見れる、前方互換性を保ちつつカラー化できた。
そして、このYCbCr色空間を利用してデータ削減を行う方法も編み出された。
クロマサブサンプリング
人の目は色情報より輝度情報の方に敏感だといわれている。この特徴を使ってデータ量を削減するのがクロマサブサンプリングであり、いくつか方法がある。Wikipediaの図を使って説明する。
まず一番右の4:4:4から説明する。これは1ピクセルごとに輝度情報、1ピクセルごとに色情報が入っている、いわゆる普通の画像といえる。
4:2:2は、輝度情報は1ピクセルごとに、色情報は水平方向は2ピクセルに1つの割合、垂直方向は全ピクセルで色情報を埋め込む。
4:2:0は、輝度情報は1ピクセルごとに、色情報は2ピクセルに1つの割合で色情報を埋め込むものだ。つまり、色情報は全ピクセルに対して半分しかないのだ。
これは情報を削減する手法として優れていて、実写の風景などを映像や写真として撮っても違和感がないが、テキストや線画など、ピクセルごとに急激に色が変わる場合などは違和感が出ることが多い。例えば、以下のように、色滲みが出る場合がある。
NV12とYUY2など
冒頭のWebカメラでは、NV12というコーデックにも対応している。NV12は4:2:0クロマサブサンプリング形式の無圧縮ストリームであって、色の表現としてはあまり優れない一方、無圧縮であることはメリットである。
YUY2は4:2:2の無圧縮ストリームで、NV12よりは色の表現に優れ、また無圧縮であるため、RGBを除いては最も画質が良いと思われる。
これら2つは無圧縮である(色情報を省いているとは言える)ことでサイズは大きくなるため、30fpsまでしか対応しないと思われる。無圧縮であることはメリットもあり、もちろん画質面で有利なことと、コンピューターはWebカメラから受け取ったデータをデコードせずにそのまま使えるため、処理が軽いことが挙げられる。
MJPEG
MJPEGはJPEG画像をパラパラ漫画のようにつなげたようなもので、1フレームを切り取ってみればJPEG画像と同じである。すなわちJPEGの圧縮方式が使われており、データサイズとしては軽くなる。それにより60fpsでの伝送を可能にしていると思われる。
JPEGによる圧縮は標準的にはYCbCr色空間においてなされ、4:4:4、4:2:2、4:2:0どれも仕様としてはありうる。またRGB色空間でも使えるため、色の表現についてはどうなっているかを知ることはこの資料からは難しいので、どのクロマサブサンプリングが使われてどのような画質になるかはわからない。例えば4:4:4やRGBで処理されていた場合は、前述のコーデックより色の表現が良くなる場合も考えられる。
しかし一般的に言えば、色空間の変換を行い、その後にJPEGの仕様に基づき圧縮が行われる。この部分で幾らかの画質のロスがある。
JPEG圧縮された画像はそのままでは処理できないため、一旦コンピュータで無圧縮のビットマップ画像にデコードされる。ここでCPUを使い、NV12やYUY2と比べるとここでマシンパワーを使う。
H.264
場合によってはH.264が利用できるWebカメラも存在する。メリットは高いフレームレートや解像度が選べる場合があること。
デメリットはMJPEGで述べたようなデコード時の負荷があること、そしてH.264はフレーム間での圧縮をおこなっている可能性が否定できないので、素早い動きなどでブロックノイズが生じる場合がある。また、同じ理由で画像をキャプチャしてからコンピュータで表示するまでのラグ(レイテンシ)がどうしても生じてしまう問題がある。
そのほかのコーデック
I420やI444、YVYU、UYVYなど、他の名前で呼ばれるものもあるが、これらは以下のような対応になる。
RGB: RGBA, BGRA, BGRX
4:4:4: I444, AYUV
4:2:2: YUY2(YUYV), YVYU, UYVY
4:2:0: I420, YV12(YUV420), NV12
これらは正確にいうならばコーデックというよりは、YCbCrをどうメモリで表現するかというフォーマットであり、圧縮自体はされていない。できるだけRGBか4:4:4の高画質なフォーマットを使いたい。
USBカメラの画質の設定を極める
OBSなどでは、ソースのプロパティにおいて入力フォーマットを選ぶことができる。
ではどう選んだらいいのだろうか?
入力フォーマットを選ぶ
まずはあまりにも低スペックだったり、ゲームなど他プログラムに対する影響を最小限まで抑えたい場合は無圧縮フォーマット、つまりRGBか4:4:4のI444、RGBA/BGRA/BGRX、あるいは4:2:2のYVYU、YUY2、UYVYなどの色情報が間引きが少ないものを選ぶことになるだろう。一方でこれらのフォーマットでは60fpsなどでキャプチャできない可能性も高い。
もしMJPEGやH.264でしか求めるフレームレートや画質が選べなかった場合は、それを選ぶ。例えば最初に挙げたWebカメラは、1080pでの60fpsはMJPEGでしか行えない。
しかし、前述したようにこれらはエンコードとデコードを行う無駄さがあるため、工学的に優れているかというと微妙である。そもそもカメラからPCまでを接続するためのバスやUSBの帯域が限られているために圧縮をしているのであり、本来であれば画質の劣化を引き起こす圧縮はない方がいいのである。
テレビ局などの映像制作の現場ではSDIなどの非圧縮で映像を送れるような帯域の広いケーブルを使用しているように、本来であれば制作の過程において圧縮(エンコード)を行う回数は減らした方がいい。
しかし何事にも妥協は必要で、何を求めるかによって、何かを切り捨てるという選択を賢く行うというのが最も適切である。
色空間を選ぶ
Rec.601やRec.709 (sRGBとも) が選べる場合もある。その場合、必ずRec.709を選ぼう。Rec.601の表現範囲は狭く、以下のように緑の表現が非常に苦手で、くすんで見えるのが明確にわかる。
この画像は実際にカラーバーの画像をOBSで表示、詳細設定の色空間を変更し、ローカルに4:2:0 H.264で録画したものである。
おまけ: OBSで色周りをよくする
色空間は709にすること。カラーフォーマットはエンコーダーの設定によって変わってくるだろうが、多くの場合エンコーダーでRGBを処理することは少ないので、I444かI420かNV12となる。
私はカラーフォーマット設定を色々変えて、YouTubeではなくローカル録画(Apple H.264 VTハードウェアエンコーダ; 出力は4:2:0)したファイルをチェックしてみたが、I444が最もアーティファクトが少ないように見えた。緑と紫のバー(“e”と“c”の間)の縦のラインと黄色と青緑(“Rec”の前)を見ればわかるが、にじみが最も少ないように思える。ただ、これはエンコーダのクロマサブサンプリングの設定にもよると思うので、適切な設定は変わると思う。