#はじめに
自分が論文を読んでいて、急に「ヒストグラム平坦化」というものが登場した。初めてのものであったので、今回は自分の備忘録も兼ねて、まとめておく。
#ヒストグラム平坦化とは
画像のヒストグラムを描くと、画像全体の明暗に関する状態が得られる。
この画像を明るくしたり暗くしたり、コントラストを高めたり低くしたりした4つの画像を用意した。
これらについて、ヒストグラムを描くと次のようになる。
ここから考察し、次のような性質がある。
[1]画像が「暗い」場合 → ヒストグラムは「左側」に偏る
[2]画像が「明るい」場合 → ヒストグラムは「右側」に偏る
[3]画像の「コントラストが高い」場合 → ヒストグラムの中央部が平坦になる
[4]画像の「コントラストが低い」場合 → ヒストグラムは「中央」に偏る
つまり、コントラストが高い、もっともメリハリのついた画像が欲しければ、ヒストグラムが全体的に平均化(平坦化)されるように画素値を変換してあげればよい。また、ニューラルネットワークに入れて学習させる画像に対してヒストグラム平坦化を施すと、精度が上昇する場合がある。
ヒストグラム平坦化を数式で表すと次のようになる。
【Def.】ヒストグラム平坦化
$I(x,y)$:画像中の座標$(x,y)$での入力画像の画素値
$H(x,y)$:画素値の度数$H(x,y)$
$I_{max}$:入力画像の画素値の最大値
$S$:入力画像の画素数の総和
に対して、以下の式を用いると出力画像の画素値$\hat{I}$が求められる。
$$\hat{I}=\dfrac{I_{max}}{S}\sum_{i=0}^{I(x,y)}H(x,y)$$
#実際につかってみた
ここでは、アメリカ国立衛生研究所(NIH)が公開しているオープンデータ「ChestX-ray14」の中にある胸部レントゲン写真を使ってみよう。
レントゲン写真を解析したいとき、患部がどこにあるかハッキリ診る必要がある。レントゲン中には骨や臓器、患部が白い影として表示される。骨や臓器は(個人差が激しいんだけどだいたい)同じ場所にあるので、健康な人だと写っていない白い影が写っていると、その領域に疾病の可能性がある、と判断される。
そういった背景から、白と黒のコントラストが強くついている方が疾病がハッキリ見やすい。このとき、今回のヒストグラム平坦化が使えるのである。
import cv2
import numpy as np
#画像の読み込み
img = cv2.imread('x-ray.png',1)
#画像をRGBからグレースケールに変更
gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
#ヒストグラム平坦化
hist_img = cv2.equalizeHist(gray_img)
#処理後の画像を保存
cv2.imwrite('x-ray_hist.png', hist_img)
ここでは、OpenCVを使ってヒストグラム平坦化をした。OpenCVにおいて、ヒストグラム平坦化を行う関数は*equalizeHist( image )*である。
ここで気をつけるポイントとしては、*equalizeHist( image )に入れる画像imageは、1チャンネルであるということである。RGBのものは入れることができないので、これを使う前にimageをグレースケールなどの1チャンネルに変換する必要がある。今回はcv2.cvtColor(img, cv2.COLOR_RGB2GRAY)*を使い、RGBからグレースケールへと変換を施している。
さて、この作業を経て得られる画像は次である。
先ほどと比べて、画像右下部分のモヤがハッキリと写っているように見える。モヤがハッキリと見えるということは、そこに潜む疾病もわかりやすくなる、ということである。(こうした画像をCNNに入れて学習をさせ、レントゲン写真の自動診断をする、という研究が最近始まったという事実もある。ちなみに僕はそっちの人。)
#おわりに
ヒストグラム平坦化をすると、画像のコントラストがついて、ハッキリ見えるようになる。単純ながらも大事そうで、活用分野が非常に広そう。