色恒常性仮説に基づいた画像色補正ライブラリcolorcrrect


# はじめに

Gunosyの粟飯原([@shunsukeaihara](https://twitter.com/shunsukeaihara))です。社内でのポジションはピエール瀧です。Gunosy Advent Calender2014では三度目の登場です。今回は自作のPython製の画像処理ライブラリ、colorcorrectの紹介をします。


# colorcorrect

colorcorrectは、色恒常性仮説に基づき、ホワイトバランスのズレや、画像の褪色・変色を自動で補正するライブラリです。古い画像の色の復元のような事もできますが、画像認識などの前処理としてこのライブラリで色の補正を入れることで画像認識の精度を向上させることが可能になります。CVPR2013の論文などで実際に利用されています。[^1]

numpyで実装されていますが、速度が必要な部分はC++で書いたものをnumpy.ctypesでラップして呼び出しています。作成したのがかなり昔の物なので、Pythonの2系にのみ対応しています。

- リポジトリ
  - https://bitbucket.org/aihara/colorcorrect 


# デモページ

ライブラリをインストールせずに、いかのページで動作を確認することが出来ます。

- http://colorcorrect.argmax.jp/

  ![fe89d5c25aee79eab3caa6d01d135305.png](https://qiita-image-store.s3.amazonaws.com/0/43606/ac6e2c43-f821-b4b5-8394-6739f9624ea9.png "fe89d5c25aee79eab3caa6d01d135305.png")

# インストール

PyPIに登録してありますので、easy_installやpipを用いてインストールが可能です。Windows向けバイナリは用意していません。
依存ライブラリはPILとnumpyのみですが、PILは開発が止まっているので、Pillowにリプレイスしたいところです。

```
pip install colorcorrect
```

# 色恒常性仮説

人間は、色付きのガラス等のフィルタを通した場合や、様々な照明条件においても物体の本当の色を正しく認識することが出来ます。また、周辺の色が異なると、同じ色でも違う色に認識してしまう錯視現象もよく知られていると思います。

このような現象のことを色恒常性と言います。もちろん元々の物体の色を事前知識として知っておりそれを元に補正しているということもありますが、人間の視覚認知の機能自体に、実際に目に入った色と認識する色が異なるような処理機構が備わっていると考えられており、その処理機能について様々な仮説が存在しています。

# 実装アルゴリズム

多くの手法は、色恒常性仮説の一つ、灰色仮説(Gray World Assumption)に基づいています。灰色仮説とは、白色光原下において視野内のすべての色、画像の場合は、全ピクセルのRGB値の平均を取ると灰色になるという仮説のこと。つまり、特殊な光源下の画像や、褪色して色が失われてしまった画像のRGB値の平均値は灰色とは乖離しているため、それのズレを補正して上げることで元の色を推定するという手法になります。もちろん、白色光原下においても平均が灰色にならない画像については正しく補正することが出来ないため、それを修正するような複数の手法が提案されていることになります。

colorcorrectには、以下の9アルゴリズムを実装しています。アルゴリズムの詳細は参考文献を参照してください。

- gray world[^2]
- max white[^2]
- stretch[^2]
- retinex[^3]
- retinex with adjust(Gray WorldとRetinexの混合手法)[^3]
- standard deviation weighted grey world[^4]
- standard deviation and luminance weighted gray world[^4]
- luminance weighted gray world[^4]
- automatic color equalization[^5]


# 使い方
PILのイメージオブジェクトをfrom_pil関数でcolorcorrectで扱うデータ構造に変換して用います。

```python
import Image
import colorcorrect.algorithm as cca
from colorcorrect.util import from_pil, to_pil
img = Image.open('/path/to/image')
to_pil(cca.stretch(from_pil(img))).show()
```

to_pil関数で、PILのImageオブジェクトに戻すことができます。また、複数のアルゴリズムを、以下のようにチェインして用いることもできます。

```python
cca.stretch(cca.gray_world(from_pil(img))))
```

それぞれのアルゴリズムのimport pathとusageは以下のとおりです。第一引数の画像以外は基本的には指定しなくても大体うまく行きます。

- gray world
  - path: colorcorrect.algorithm.gray_world
  - usage: image
- max white[1]
 - path: colorcorrect.algorithm.max_white
 - usage: image
- stretch
  - colorcorrect.algorithm.stretch
  - usage: image
- retinex
  - path: colorcorrect.algorithm.retinex
  - usage: image
- retinex with adjust
  - path: colorcorrect.algorithm.retinex_with_adjust
  - usage: image
- standard deviation weighted grey world
  - path: colorcorrect.algorithm.standard_deviation_weighted_grey_world
  - usage: image,subblock width(default:20), subblock height(default:20)
- standard deviation and luminance weighted gray world
  - colorcorrect.algorithm.standard_deviation_and_luminance_weighted_gray_world
  - usage: image,subblock width(default:20), subblock height(default:20)
- luminance weighted gray world
  - path: colorcorrect.algorithm.luminance_weighted_gray_world
  - usage: image,subblock width(default:20), subblock height(default:20)
- automatic color equalization
  - path: colorcorrect.algorithm.automatic_color_equalization
  - usage: image,slope(default:10),limit(default:1000), samples(default:500)

automatic color equalizationは、フルに計算すると非常に重いため、ランダムサンプリングをして計算量を下げるという適当なあんちょこをしています。samplesのパラメータを増やすと、サンプル数が多くなり精度が上がりますが線形に遅くなります。


# 出力結果

wikimedia commonsの以下の画像(Nitzan Danzig, 1982)を用いて色補正結果の比較してみます。
- http://commons.wikimedia.org/wiki/File:Yamit_evacuation_2.jpg?uselang=ja

|original|gray world|max white|stretch|gray world + stretch|retinex|
|---|---|---|---|---|---|
|![694d353971d899641fc72584452122ef.png](https://qiita-image-store.s3.amazonaws.com/0/43606/b48dc37f-94d1-5302-6351-7621c6e6d358.png "694d353971d899641fc72584452122ef.png")|![cab5cdb9898c0404a2b6ab11d6a533d9.png](https://qiita-image-store.s3.amazonaws.com/0/43606/a6bef10b-c810-3a10-4041-4715fc94eb46.png "cab5cdb9898c0404a2b6ab11d6a533d9.png")|![c4300174850cca7879d58464a443da98.png](https://qiita-image-store.s3.amazonaws.com/0/43606/1bd6c068-dab8-ff8f-5a17-a6487fa6f1bf.png "c4300174850cca7879d58464a443da98.png")|![fe0d7ac6966c22d33148c5bd4ff9cf96.png](https://qiita-image-store.s3.amazonaws.com/0/43606/81fdbd13-f318-5e36-8442-6fe72e7478d7.png "fe0d7ac6966c22d33148c5bd4ff9cf96.png")|![3f6019fb9f73561d2e2529993b77bdc9.png](https://qiita-image-store.s3.amazonaws.com/0/43606/beb65f44-9847-d7cc-6369-abc2731e2839.png "3f6019fb9f73561d2e2529993b77bdc9.png")|![c4300174850cca7879d58464a443da98.png](https://qiita-image-store.s3.amazonaws.com/0/43606/f3c8d537-36e5-37d7-d01f-6fc0cc46bb9f.png "c4300174850cca7879d58464a443da98.png")|
||retinex with adjast|standard deviation weighted grey world|standard deviation and luminance weighted gray world|luminance weighted gray world|automatic color equalization|
||![d5886ca3f3c4769e97a39d1c9f9ca414.png](https://qiita-image-store.s3.amazonaws.com/0/43606/731d57b6-33f9-2ff6-a172-60779c9ed1e0.png "d5886ca3f3c4769e97a39d1c9f9ca414.png")|![2895eed38f658a6c8be08ebe9c367090.png](https://qiita-image-store.s3.amazonaws.com/0/43606/68410c10-a2b1-62fa-2ed9-23cf6db6cffe.png "2895eed38f658a6c8be08ebe9c367090.png")|![fa423cf371c912d6e4563183f3461184.png](https://qiita-image-store.s3.amazonaws.com/0/43606/018d8848-0592-441a-8031-1eeb133802b1.png "fa423cf371c912d6e4563183f3461184.png")|![97fc312fe8c2fe01275538a34d409693.png](https://qiita-image-store.s3.amazonaws.com/0/43606/c6e2a8f0-a14a-b256-688f-ef13b49f7437.png "97fc312fe8c2fe01275538a34d409693.png")|![3a72636425dac3e9cea56979801dc83e.png](https://qiita-image-store.s3.amazonaws.com/0/43606/92e123be-58ba-a7af-d870-0ce476a9504b.png "3a72636425dac3e9cea56979801dc83e.png")|

Gary World系はこのような褪色においては青みがかった補正をしてしまうようです。その上でstrechアルゴリズムを適用した場合はかなりきれいな出力になっていますが、理論的な背景は不明です。automatic color equalizationはかなりきれいな補正になっています。このアルゴリズムは、かなり万能に利用できる印象があります。

あくまで色のズレの補正のライブラリなので、件の東亜飯店の退職画像のような完全な褪色画像を補正することは出来ません。


# さいごに

画像からの特徴量の抽出に関して、アルゴリズムや実装に関しては様々なライブラリが公開されており、解説も豊富にありますが、このような画像処理向けの前処理のアルゴリズムに関しては輝度の正規化等を除いてあまり実装がない現状があります。意外とこの手の前処理系のまとまった実装は他に無いため、他にも[pyssp](https://bitbucket.org/aihara/pyssp)という音声認識の前処理用ライブラリも作成しています。手軽に使える物を目指して作成していますので、趣味や研究に活用していただければと思います。


[^1]: R. Benenson, M. Mathias, T. Tuytelaars, L. Van Gool, "Seeking the strongest rigid detector", CVPR, 2013.
[^2]: D. Nikitenko, M. Wirth and K. Trudel, "Applicability Of White-Balancing Algorithms to Restoring Faded Colour Slides: An Empirical Evaluation.", Journal of Multimedia, vol. 3, no. 5, 2008.
[^3]: E.Y. Lam,  "Combining gray world and retinex theory for automatic white balance in digital photography.",in Proc ISCE, 2005.
[^4]: HK. Lam, OC. Au and CW. Wong, "Automatic white balancing using luminance component and standard deviation of RGB components.", in Proc. ICASSP, 2004.
[^5]: A. Rizzi, C. Gatta and D. Marini, "A new algorithm for unsupervised global and local color correction.", Pattern Recognition Letters, vol. 24, no. 11, 2003.