WebPとJPEGの圧縮はどこが違うか

WebPGoogleが開発した静止画ファイルフォーマットです。 圧縮形式としては大きく2種類あって非可逆圧縮のLossy WebPと可逆圧縮のLossless WebPです。 用途で考えるとLossyはJPEG相当、LosslessはPNG相当と言えます。 どちらにしても拡張子は.webpが使われるので紛らわしいですが、使われている圧縮アルゴリズムはまったく別物になっています。

ここでは公式サイトにあるLossy WebPとJPEGの比較サンプルの画像を観察して、どこが違うのか見てみた結果を紹介します。 この公式サンプルは5つのPNG画像をそれぞれJPEGとWebPに変換したものですが、WebPのファイルサイズがちょうどJPEGの3割減になるように圧縮オプションが調整されています。 つまり「同じ画質でファイルサイズが3割減」というデモではなく、単純に3割減にした場合の画質比較デモなので、その点はちょっと注意が必要です。 おそらく「3割減にしたけど画質は変わらないでしょう?」と言いたいのだと思います。

JPEGもLossy WebPも内部的にはYCbCr色空間を用いて圧縮しているので、YCbCrヒストグラムを比べてみました。

f:id:tshino:20190501045745p:plain
YCbCrヒストグラムの比較

図は左から、ソースPNGJPEG、WebP。ヒストグラムは上からY、Cb、Crの順です。 JPEGのCbとCrが細かい「くし形」のヒストグラムになっているのはJPEG圧縮でよく見られる特徴で、量子化の影響だと思われます。 WebPの方はY成分にやや幅の広いくし形というか周期的な凹みがあるのを発見しました。これは他の画像サンプルについても同様でした。

この周期的な凹みは何なのか?

どうやらLossy WebPでは256段階の輝度の階調を保つことは出来ず、飛び飛びにしか表せないという制約があるようです。 次の図は、このことを確かめるために0から255までの階調を均等に含むようなグレイスケール画像を最高画質で作り、その輝度ヒストグラムを表示したものです。Lossy WebPではこのように滑らかな階調を表現することには限界があるようです。

f:id:tshino:20190501050051p:plain
グレイスケールの輝度ヒストグラム比較

次に画像のどの部分が実際に違うのか、桜の画像を拡大して目視で比較しました。

f:id:tshino:20190501050206p:plain
桜の画像の拡大

青空の部分では、ソースPNGにあった細かい濃淡がWebPではきれいさっぱりなくなっています。 それが良いのか良くないのかは場合に依るでしょうが、ファイルサイズの削減には効いている部分だと思います。 また、JPEGでは木のまわりの空の部分にJPEG特有の「モスキートノイズ」が現れていますが、WebPではそれがほとんど見られないことも分かります。 どんな圧縮アルゴリズムでこうなっているのかは(詳しく調べていないので)分かりませんが、モスキートノイズが出にくい特性があるようです。

次の図は湖の画像を拡大して、YCbCr色空間の各チャンネルをグレイスケールで表示してみたものです。

f:id:tshino:20190501050346p:plain
湖の画像の拡大
f:id:tshino:20190501050436p:plain
YCbCrのチャンネル画像の比較

チャンネル別の図は上から元のカラー画像、Y成分、Cb成分、Cr成分です。 普通にカラー画像で見ても圧縮によるブロックノイズが目立つ部分ですが、チャンネルに分けてみるとさらに凄いことになっているのが分かります。 CbやCrが大きなモザイク状になっていて、かなり圧縮率に寄与していそうです。

まとめ

Lossy WebPとJPEGの画像のどこがどう違うのか、公式サンプルを観察して気づいた点を紹介しました。 ただ、この公式サンプルはかなり高圧縮率(JPEGのquality値は80)、言い換えると低画質の場合の比較になっているため、それほど圧縮せずに高画質の写真を表示するような場合にはまた異なる傾向になると思われます。

個人的には、モスキートノイズが少ない点でWebPもなかなか良いかなと思いました。ただ、圧縮率によってはかなりアグレッシブにブロックノイズが出るので、注意が要るようです。

なお比較に使ったツールは、私の開発しているCompareというウェブアプリです。 便利ですよ(これが言いたかった)。