LoginSignup
5
1

More than 1 year has passed since last update.

OpenCVでJPEG画像が汚く保存される問題の対策が、4.7.0から入ります

Last updated at Posted at 2022-12-24

この記事はOpenCV Advent Calendar 2022の17日目の記事(代打ち)です。
他の記事は目次にまとめられています。

TL;DR

  • JPEG圧縮するときにはサンプリングに気を付けよう!
  • OpenCV 4.7.0から、JPEGのサブサンプリング指定ができるようになりますよ!

自己紹介

はい、どこにでもいる普通の画像処理エンジニアでした。

今回は今年contributeしたJPEGのサンプリング指定パッチについて簡単に説明します。

「OpenCVでJPEG形式で画像を保存したら、なんか色が変だなあ?」というときにご利用ください。

どういう問題だったのか?

切っ掛けとなったissueはこちらである。

紫色の細線の色がおかしい、というissue。

JPEGのサブサンプリングの振り返り

  • JPEGのサブサンプリング指定は、デフォルトが420形式である。
  • 420形式だと、Y chが4x2に対して、CrCbが2x1しか含まれない
  • CrCbプレーンの情報が大幅に欠落する。

もうちょっと詳しく、ただしざっくり概念をまとめていくとこうなる。まず、オリジナルのRGB画像を、4x2単位に分割する

RGB00 RGB10 RGB20 RGB30
RGB01 RGB11 RGB21 RGB31

↓ RGBからYCrCb色空間に変換する

YCbCr00 YCbCr10 YCbCr20 YCbCr30
YCbCr01 YCbCr11 YCbCr21 YCbCr31

この、Y,Cr,Cb Planeごとに分離する。Yが「輝度」、Cr,Cbが「赤っぽさ」「青っぽさ」である。

Y00 Y10 Y20 Y30
Y01 Y11 Y21 Y30

Cb00 Cb10 Cb20 Cb30
Cb01 Cb11 Cb21 Cb31

Cr00 Cr10 Cr20 Cr30
Cr01 Cr11 Cr21 Cr31

人間の眼には、Yが重要、ということで、情報量削減のためCbプレーンとCrプレーンで、情報を間引く=平均を取る。

CbA = (Cb00 + Cb10 + Cb01 + Cb11) / 4 \\
CbB = (Cb20 + Cb30 + Cb21 + Cb31) / 4 \\
CrA = (Cr00 + Cr10 + Cr01 + Cr11) / 4 \\
CrB = (Cr20 + Cr30 + Cr21 + Cr31) / 4 
CbA CbB
CrA CrB

CbA/CbB, CrA/CrBの色情報があれば、YCbCr -> RGB変換の時には「平均」を利用して、大体 同じ画像を復元できる事になる。これで情報量削減するのが「サブサンプリング」のざっくり説明となる。

CbA (CbA) CbB (CbB)
(CbA) (CbA) (CbB) (CbB)
CrA (CrA) CrB (CrB)
(CrA) (CrA) (CrB) (CrB)

どんな問題が起きるのか?

困ったことに、紫色(RGB(255,0,255)) の細線を描画しようとすると、青・赤の成分が周囲に滲んでしまう。その結果、元々よりもくすんだ色となり、かつ、色が無かったところにも色がのってしまう。下がサンプル画像ですが、いやもう、縮小画像の時点で「なんか色へーん」ってわかりますよね?

image.png

拡大もしてみましょう。例えば、左がSubsampling = 420(JPEGデフォルト)、右がSubsampling = 444(サンプリング指定なし)である。これくらい違う。だめだこりゃ!

image.png

OpenCV 4.7.0からJPEGのSubsampling指定ができるようになります。

「じゃあ、JPEG形式で保存すると、画像が汚くなっちゃうの・・・」と心配された方、ご安心下さい!! OpenCV 4.7.0からは、サブサンプリング指定もできますよ!
 
https://docs.opencv.org/4.x/d8/d6a/group__imgcodecs__flags.html#ga292d81be8d76901bff7988d18d2b42ac

image.png

 https://docs.opencv.org/4.x/d8/d6a/group__imgcodecs__flags.html#ga4b97ca569a53587801257896d79656e1

image.png

「どれだけ色成分を犠牲にして、ファイルサイズを小さくするのか」を指定し放題になりました!

これで、OpenCVの後ろに何かのライブラリを繋いだりするときも、色変換によるくすみなんかを回避できるようになりますね!!

まとめ

  • JPEG圧縮するときにはサンプリングに気を付けよう!
  • OpenCV 4.7.0から、JPEGのサブサンプリング指定ができるようになりますよ!

それではみなさん、楽しいクリスマスイブをお過ごしくださいませ、メリークリスマス!!

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1