Google製JPEGエンコーダー「Guetzli」

  • 68
    いいね
  • 15
    コメント

Guetzli

https://github.com/google/guetzli

Guetzli [guɛtsli] とはスイスドイツ語でクッキーの意味。1

Google が2016年10月22日に GitHub で Initial Release を公開 2 した JPEG エンコーダー。2017年1月13日に GIGAZINE で紹介される。3
2017年3月15日に 1.0 がリリース 4 され、Google Research Blog でアナウンスされた 5 ため、同17日頃より国内メディアで紹介され始めた。

使ってみた感想

Mozilla の JPEG エンコーダー mozjpeg と画像処理を比較した結果、200倍の処理時間がかかった上に圧縮率が拮抗してて(しかも負けてる)、見た目も大差ないので、正直使えないかもしれない。ナニコレ。

指摘を受けた後の補足

個人的な感想に変更はないが、Guetzli のメリットとしては、同じく Google 製の butteraugli による品質評価でスコアが優位であり、butteraugli のスコアを同一にした場合に、画像サイズがより小さくなるらしい。GIGAZINE の1月の記事にちゃんと書いてあった…。
ただ、よっぽど大きい画像とかじゃないと正直違い分からないと思うよ。quality 84 より下に設定できないし。

どういった画像が人間が評価したときに違いが出やすいかが明示されて、200倍の時間をかける必要性があることに対してであれば、あるいは使いどころもあるかもしれない。

より詳しい情報

この記事を書いている人間は画像処理についてまったく知見のない完全な素人です。
そして画像処理に詳しい人たちにヘイトの溜まる書き方だったようでかなり反感を買いましたが、おかげで詳しい記事を書いてくれたようです。
少なくともこの記事より技術的に正しい、あるいは詳しい内容かと思うので、技術的に気になる方はそちらを参照してください。

インストール

curl -L https://github.com/google/guetzli/releases/download/v1.0/guetzli_linux_x86-64 -o guetzli
chmod a+x guetzli && mv $_ /usr/local/bin

CentOS 7.3.1611 (minimal) で動作確認。
コンパイル手順では libpng (extras) と gflags (epel) のインストールが記載されているが、バイナリ版には含まれているのかインストールしなくても動作した。(インストールしてもエンコードサイズは変わらなかった)

使い方

※リリース早々に1.0.1にバージョンアップして挙げ句パラメーター変わってるらしいのでご注意ください。

基本

guetzli bees.png bees_compressed.jpg

品質指定

guetzli -quality 90 bees.png bees_90.jpg

詳細表示

guetzli -verbose bees.png bees_compressed.jpg
Original Out[ 148444] BA[100.00%] D[0.4312] Score[148444.0000] (*)
Iter  1: f111111 quantization matrix:
  1  1  1  1  1  1  1  1     1  1  1  1  1  1  1  1     1  1  1  1  1  1  1  1
  1  1  1  1  1  1  1  1     1  1  1  1  1  1  1  1     1  1  1  1  1  1  1  1
  1  1  1  1  1  1  1  1     1  1  1  1  1  1  1  1     1  1  1  1  1  1  1  1
  1  1  1  1  1  1  1  1     1  1  1  1  1  1  1  1     1  1  1  1  1  1  1  1
  1  1  1  1  1  1  1  1     1  1  1  1  1  1  1  1     1  1  1  1  1  1  1  1
  1  1  1  1  1  1  1  1     1  1  1  1  1  1  1  1     1  1  1  1  1  1  1  1
  1  1  1  1  1  1  1  1     1  1  1  1  1  1  1  1     1  1  1  1  1  1  1  1
  1  1  1  1  1  1  1  1     1  1  1  1  1  1  1  1     1  1  1  1  1  1  1  1
Iter  1: f111111 GQ[ 0.00] Out[ 148314] BA[100.00%] D[0.4312] Score[148314.0000] (*)
(snip)
Iter  9: f111111 quantization matrix:
  3  3  3  3  3  3  5  5     3  3  3  3  3  3  5  5     3  3  3  3  3  3  5  5
  3  3  3  3  3  5  5  5     3  3  3  3  3  5  5  5     3  3  3  3  3  5  5  5
  3  3  3  3  5  5  5  5     3  3  3  3  5  5  5  5     3  3  3  3  5  5  5  5
  3  3  5  5  5  5  5  5     3  3  5  5  5  5  5  5     3  3  5  5  5  5  5  5
  3  5  5  5  5  5  5  5     3  5  5  5  5  5  5  5     3  5  5  5  5  5  5  5
  5  5  5  5  5  5  5  5     5  5  5  5  5  5  5  5     5  5  5  5  5  5  5  5
  5  5  5  5  5  5  5  5     5  5  5  5  5  5  5  5     5  5  5  5  5  5  5  5
  5  5  5  5  5  5  5  5     5  5  5  5  5  5  5  5     5  5  5  5  5  5  5  5
Iter  9: f111111 GQ[29.82] Out[  58432] BA[100.00%] D[0.9286] Score[58432.0000]

YUV444 selected quantization matrix:
  3  3  3  3  3  3  5  5     3  3  3  3  3  3  5  5     3  3  3  3  3  3  5  5
  3  3  3  3  3  5  5  5     3  3  3  3  3  5  5  5     3  3  3  3  3  5  5  5
  3  3  3  3  5  5  5  5     3  3  3  3  5  5  5  5     3  3  3  3  5  5  5  5
  3  3  5  5  5  5  5  5     3  3  5  5  5  5  5  5     3  3  5  5  5  5  5  5
  3  5  5  5  5  5  5  5     3  5  5  5  5  5  5  5     3  5  5  5  5  5  5  5
  5  5  5  5  5  5  5  5     5  5  5  5  5  5  5  5     5  5  5  5  5  5  5  5
  5  5  5  5  5  5  5  5     5  5  5  5  5  5  5  5     5  5  5  5  5  5  5  5
  5  5  5  5  5  5  5  5     5  5  5  5  5  5  5  5     5  5  5  5  5  5  5  5
Iter 10: f111111(7) up Coeffs[24885/45016] Blocks[1287/1797/1848] ValThres[0.7288] Out[  46401] EstErr[0.10%] BA[100.00%] D[1.0452] Score[1820309.3844]
Iter 11: f111111(7) up Coeffs[3563/19983] Blocks[861/1781/1848] ValThres[0.0294] Out[  44501] EstErr[0.07%] BA[100.00%] D[1.0487] Score[2088126.7296]
Iter 12: f111111(7) up Coeffs[3543/16420] Blocks[944/1771/1848] ValThres[0.0332] Out[  42585] EstErr[0.08%] BA[100.00%] D[1.0651] Score[4521058.0405]
(snip)
Iter 33: f111111(7) down Coeffs[49/3569] Blocks[27/136/1848] ValThres[0.0173] Out[  37860] EstErr[0.08%] BA[100.00%] D[0.9947] Score[119150.1578]
Iter 34: f111111(7) down Coeffs[47/1717] Blocks[23/73/1848] ValThres[0.0259] Out[  37897] EstErr[0.10%] BA[100.00%] D[0.9796] Score[56045.0362]
Iter 35: f111111(7) down Coeffs[44/285] Blocks[10/21/1848] ValThres[0.0265] Out[  37910] EstErr[0.06%] BA[100.00%] D[0.9717] Score[37910.0000] (*)

バグ?

guetzli -version

とやっても guetzli としか出力されない。

スピードとサイズ

quality 時間 サイズ 圧縮率
84 9.474s 19881 11.2%
90 10.960s 25783 14.5%
95 13.667s 37910 21.4%
100 23.489s 148444 83.7%
未指定 13.530s 37910 21.4%

公式のサンプル画像を元にした数値。オリジナル画像のサイズは 177424 バイト。
-quality は 84 からしか指定できない。
変換サイズから推測して未指定の場合は -quality 95 になるようだ。

その他の JPEG エンコーダー

  • Lepton
  • mozjpeg
  • libjpeg-turbo
  • jpegoptim

mozjpeg との比較

画像

画像処理界隈で有名な Lena の画像 6 で比較。PLAYBOY 1972年11月の切り抜き。

Source: The photo of Lena Söderberg photo and other image processing test images

remastered-lena.jpg

時間

quality Guetzli mozjpeg
(cjpeg)
84 19.498s 0.073s
90 22.506s 0.079s
95 29.476s 0.111s
100 44.614s 0.214s

Guetzli 時間かかりすぎワロタ。

ファイルサイズ

quality Guetzli mozjpeg
(cjpeg)
84 50071
17.7%
49451
17.5%
90 60965
21.6%
60599
21.5%
95 91629
32.5%
80572
28.6%
100 223908
79.3%
173504
61.5%

Guetzli 軒並み負けてて草。

品質

コメントで指摘があるが、品質の比較はファイルサイズでやらないとナンセンスかもしれない。ファイルサイズ揃えるのだるいんでまだ未対応。

AE

quality Guetzli mozjpeg
(cjpeg)
84 248724 246865
90 244907 242166
95 234535 235457
100 120435 179307

ImageMagick の compare で AE で比較。異なるピクセル数。少ない方が品質が高い。オリジナルとの差異が少ない。
quality 90 以下で200倍時間かけてる Guetzli が負けてて草も生えない。

butteraugli

quality Guetzli mozjpeg
(cjpeg)
84 1.944450 2.432503
90 1.473460 1.867565
95 0.971432 1.363530
100 0.211575 0.756934

Google 製の心理視覚を比較するツール butteraugli で比較。同一画像で 0 スコアとなるようだ。
butteraugli 自体の妥当性がどの程度なのかさっぱり分からないが、butteraugli のスコアに最適化されているというだけあって Guetzli の方が数値が良い。

この記事に対する反応

Siv3D というゲームとメディアアートのための C++ ライブラリを開発している未踏スパクリ(2013年度)の人がコメントで butteraugli を紹介してくれた。ありがたい。

品質評価手法の見直しを提案されたので、紹介された butteraugli を使って比較したデータを「品質」の項目に「butteraugli」を追加した。

なお、書いた当人としては特に誤解はしていない(AEによる比較が絶対的に妥当な品質評価基準だとは思っていない)が、多少バズっているので表現を修正した。

画像の品質とファイルサイズについて、butteraugliを用いてlibjpegと結果を比較したところ、同等のスコア(品質)でもファイルサイズを35%減らすことができたそうです。

そもそもの話として、2017年1月13日の GIGAZINE の記事 3 にリンク付きで記載されてた。が、この記事だといずれにしろスルーしてしまう。

お、人に仕事させるのうまいな、見習いたい。と思い、とりあえずリツイートしといたら、よくわからないが切れそうになってコメントしてくれた。尊い。

画像処理の専門家とかでなければ、この辺がごく常識的な理解と評価だろう。

評価方法が「正しくない」という指摘があるので、「品質」の項目で AE を採用した理由を書いておこう。

ぱっとググった範囲では、JPEGエンコーダーの紹介記事で品質の比較を実施している記事は見当たらなかったので、数値による客観的あるいは機械的な比較がしたかった。数字棒。

AE が本当の意味での品質を評価するのに十分であるとは言えないということは最初から理解していたが、品質とはすなわち人間が実際に見て劣化がひどく感じるかどうかであり、Guetzli では quality は 84 までしか下げられず、違いがぱっと見分からない時点でより妥当な評価手法をゼロから探すコストを掛ける意味はない見つけても処理速度を200倍かけるだけのメリットを覆すことはできないと判断した結果である。

AE が評価基準として一番当てにならない、というのについては、単にそれ以外の評価方法についての妥当性について判断する知見を持ち合わせていなかったためである。

思ったよりバズって情報提供とマサカリが飛んできたから、とりあえず butteraugli のインストール手順まとめといたよ。

雑な批判ツイートをもらったでござる。

で、なんで自分で試してコメント欄に画像を貼らないんだこいつは?

煽り返したら仕事してくれたみたい。


画像圧縮の比較で一番簡単な方法は、両者が同じサイズになるようにパラメータ調節したものを見た目で比較すればいい。

2017/03/19 12:46

今回試した小さい画像じゃ数値がそろわなかったから大きい画像探して後で試すわ。「これはひどい」タグはひどい。

そうか、コメント読め、というエントリーだったんだな。そりゃ、そこまで時間かける理由があるんだからなぁ。実際の画像見て比べたいところ。

2017/03/19 13:23

だよね。200倍時間をかけた画像がこちらです。どちらがどちらかは一目瞭然ですよね。

(03/21 14:07追記)面目ない、コメントで指摘があったが、Qiita の編集画面でそのままアップしたためか処理されている様子。後ほど別の場所に上げて直します。

(03/21 15:42追記)Qiita の処理が入らない形で再アップ。ごめんなさいごめんなさい。でもあれか、Qiita の再圧縮が入ってた方がアラが分かりやすくなって逆によかった?
ちなみに Guetzli は quality が 84 までしか下げられないのでそちらに合わせた。mozjpeg は quality を 84.5 にしたらファイルサイズが近くなった。順番は変えてない。
というわけで今度のファイルサイズは Guetzli が quality 84 で 50,071 バイト、 mozjpeg が quality 84.5 で 50,002 バイト。
答えは alt 属性に書いてあるから、まずは alt を見ずにどちらがどちらか当ててみよう。

lena_mozjpeg_0845.jpglena_guetzli_084.jpg

以下はオリジナルの lena.tif を PNG にした奴。
lena.png

考えず見ちゃうとgoogleだめじゃんpgrってなる。コメ欄(違う視点から)も見ろ。人は簡単に勘違いする。という戒めブクマ→Qiitaでコメント返しされてて和んだw

2017/03/19 14:33

おっ、そうだな。/(´∀`)

勉強になる記事。投稿者もどういう観点で比較したかわかるデータをちゃんと載せてて信頼できる。元の主張がしっかりしてるからこそ内容のある議論ができる。/この記事で比較画像乗せるのは蛇足に思う。観点がぶれる

2017/03/19 18:29

こういうまともな人がいると、少し安心する。/なるほど数値で比較してんのに主観の入る画像比較は蛇足と。確かに比較画像を当初マストで掲載しなかったのはそういうのもあったのかも。ただ「目視で比較して品質に差異を感じなかった」という大前提があって、それは読者は記事では確認出来なかったのでやはり載せるのは仕方ないかな的な。

バイナリ落としてエンコ時間とサイズ見てGoogle使えねーと思った自分としては、これらのコメントを引き出した投稿主を褒めることしかできない / おぉ更新されてて勉強になる素晴ら

2017/03/19 19:31

おま俺。/╭( ・ㅂ・)و ̑̑ グッ !

数字棒

2017/03/19 22:45

数字棒。

人間の知覚で劣化が分かりにくくなることを狙ってるのに、画像を見て比較してないのはちょっと……。

2017/03/20 03:16

アップすんの遅くなってごめんね。消しちゃった線画のアニメーションGIF作ったところで力尽きちゃったの。

参照