X(旧Twitter)を見ていたら、Sirilに実装されているCLAHEが紹介されていました。



SirilのCLAHEは単にOpenCVを呼んでいるだけらしいので、どんなもんかな、とちょっとpythonで書いて触ってみました。

CLAHEは画面を分割して、分割した中でヒストグラムが均等になるように処理をします。画像のエリアごとでのコントラストの差が小さくなるため、比較的範囲の広い低周波の信号が落ちて、周波数高めの信号がのこるのが特徴です。

まずはやってみた結果がこちら。
こちらがオリジナルのM8。
M8s

CLAHEををかけたのがこちら。グラップラー刃牙なM8になりました。
M8_2s


試したソースはこんだけ。超簡単。
import numpy as np
import cv2

img = cv2.imread("M8.TIF")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
v2 = clahe.apply(v)
hsv2 = cv2.merge((h, s, v2))
cl1 = cv2.cvtColor(hsv2, cv2.COLOR_HSV2BGR)
cv2.imwrite('M8_3.TIF',cl1)


最初にRGB画像をHSV(色相、彩度、明度)に変換して、明度だけに対してCLAHEをかけます。

cv2.createCLAHE()がそのメソッド。引数に
・clipLimit
・tileGridSize
の2つを与えることができて
clipLimitは過剰にコントラストをかけないようにするためのリミットです。この値を大きくすると、より派手にコントラストがつきます。

tileGridSizeは、画面を縦横なん分割するか、です。分割数を増やすとより細かい信号が強調されるようになります。

上の画像は clipLimit=2, tileGridSize = (8, 8)でやりました。これを24x24分割にしてみると、確かにより細かいところがはっきりしてきます。
M8_3s

試しに彩度にかけてみると、き、汚い(笑)。
M8_3ss

続いて馬頭星雲にかけてみます。これが
馬頭-DeNoiseAI-standard-2M

こうなります。馬頭から西側に流れるような模様も見えてきています。が、当たり前ですがノイズも強調されるので、元画像の品質が良くないとだめですね。
aaaa

天の川にかけてみました。左がオリジナル。真ん中がそれにCLAHEをかけたもの。右はそれの色をちょっと整えたものです。
aaa0

淡くしか写っていなかった暗黒帯がだいぶはっきりするようになりました。

最初のM8に戻って、今度はclipLimitを変えてみます。
上から1.1, 1.5, 2.0。あまり違わないですが、個人的には一番弱い1.1が自然な感じがします。

M8s1.1
M8s1.5
M8s2.0


何にせよ淡いところの模様が簡単に炙り出せるので、これからちょこちょこ使っていきましょう。