2021年9月5日日曜日

【OpenCV】ヒストグラム平坦化による画像コントラストの向上

 全体的に明るい画像や全体的に暗い画像などは、画素の輝度分布が高い値または低い値に偏っているため画素間の輝度差が小さい、つまりコントラストが低くなる。偏った画素値の分布をヒストグラム平坦化処理により広げることで画像のコントラストを高めることができる。


OpenCVを使うには次のようにインポートが必要。
import cv2


1. equalizeHistによるヒストグラム平坦化

 全体的に明るい画像はピクセルの輝度分布が高い値に偏っている。逆に全体的に暗い画像はピクセルの輝度分布が低い値に偏っている。この分布をequalizeHistにより広げることで画像のコントラストを高くすることができる。はじめに画像の色空間をBGR色空間からHSV色空間に変換しV値(明度・Value)に対してequalizeHistを適用することでヒストグラムが平坦化される。


例に用いる画像'shelf.jpg'は以下を使用(フリー写真素材ぱくたそより)



import cv2 
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('shelf.jpg')
# BGR->HSV変換
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) 

# V値のヒストグラム表示
hist = cv2.calcHist([hsv], [2], None, [256], [0,256]) 
plt.plot(hist, color = "b")
plt.show()

# V値のヒストグラム平坦化
hsv[:, :, 2] = cv2.equalizeHist(hsv[:, :, 2])

# 平坦化後のV値のヒストグラム表示
hist = cv2.calcHist([hsv], [2], None, [256], [0,256]) 
plt.plot(hist, color = 'g')
plt.show()

# HSV->BGR変換
bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) 

# 画像の保存 
cv2.imwrite('shelf_eq.jpg', bgr) 

実行結果
画像のコントラストが向上し暗くてよく見えなかった部分が見えるようになる。



変換前画像のV値のヒストグラム



変換後画像のV値のヒストグラム




暗いほうに集中していたV値がヒストグラム平坦化処理により広げられたことがわかる。



2. CLAHEによる適用的ヒストグラム平坦化

 equalizeHistは画面全体のコントラストを考慮した処理のため、明るい部分と暗い部分が混在している画像ではヒストグラム平坦化がうまくいかない場合がある。CLAHE (Contrast Limited Adaptive Histogram Equalization)を用いると画面を分割し(デフォルトは8x8)それぞれの分割画面内でヒストグラム平坦化処理が行われる。


例に用いる画像'hida.jpg'は以下を使用(フリー写真素材ぱくたそより)



import cv2 
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('hida.jpg')
# BGR->HSV変換
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) 

# V値のヒストグラム表示
hist = cv2.calcHist([hsv], [2], None, [256], [0,256]) 
plt.plot(hist, color = "b")
plt.show()

# CLAHEパラメータの設定
clahe = cv2.createCLAHE(clipLimit=4.0,tileGridSize=(8,8))

# V値のヒストグラム平坦化
hsv[:,:,2] = clahe.apply(hsv[:,:,2]) 

# 平坦化後のV値のヒストグラム表示
hist = cv2.calcHist([hsv], [2], None, [256], [0,256]) 
plt.plot(hist, color = 'g')
plt.show()

# HSV->BGR変換
bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) 

# 画像の保存 
cv2.imwrite('hida_clahe.jpg', bgr) 

実行結果
適用的コントラスト補正により手前の山の様子がわかるようになる。





変換前画像のV値のヒストグラム



変換後画像のV値のヒストグラム



同じ画像をequalizeHistで処理した場合。
上に比べて空、山それぞれのコントラストが弱い。





3. リファレンス

OpenCV > OpenCV-Python Tutorials > Histograms - 2: Histogram Equalization
OpenCV > Histograms > equalizeHist()
OpenCV > Histograms > createCLAHE()

使用したバージョン:Python 3.8.8 / OpenCV 4.0.1

0 件のコメント:

コメントを投稿