【Python・OpenCV】ヒストグラム平坦化による画像のコントラストの改善(cv2.equalizeHist)

※当サイトではアフィリエイト広告を利用しています

Python プログラミング 画像処理

【Python・OpenCV】ヒストグラム平坦化による画像のコントラストの改善(cv2.equalizeHist)

2023-07-25

はじめに

前回、画像のヒストグラム計算の記事を投稿しましたが、今回はヒストグラムを応用したコントラストを改善する方法を紹介します。

ヒストグラム平坦化

ヒストグラム平坦化は、画像のコントラストを改善するための手法の一つです。
画像のヒストグラムは、画像内の明るさの分布を表すグラフです。ヒストグラム平坦化は、ヒストグラムの全体的な範囲を均等に広げ、画像のコントラストを向上させます。これにより、暗い画像や明るい画像においても、より明瞭な画像を得ることができます。

下図の左はヒストグラム平坦前の画像のヒストグラム、右はヒストグラム平坦後の画像のヒストグラムです。ヒストグラム平坦前は画素値30付近と220付近にピークを持っており、暗い部分と明るい部分に画素値が集中している中間の明るさの画素が少ないバランスの悪い画像です。

cv2.equalizeHist関数

cv2.equalizeHist関数は、OpenCVライブラリの中でヒストグラム均一化(Histogram Equalization)を行うための関数です。

cv2.equalizeHist(入力画像)

引数

名称説明
入力画像(必須)入力画像データ。対応するデータ型はuint8です。

ポイント

入力はuint8(8ビット)のシングル チャンネル(グレースケール)画像のみ対応しています。

cv2.equalizeHist関数の出力するヒストグラムのビンの合計は255になるように作成されます。

戻り値

戻り値は入力画像と同じサイズのuint8のヒストグラム平坦化が適用されたグレースケール画像データです。

cv2.equalizeHist関数の適応結果を示します。左上に示す入力画像に比べ、左下の適用後の画像は全体的によ自然に明るくなっていることがわかります。右側の列に示すヒストグラムをみると、右上の入力画像のヒストグラムは右下りのCount数ですが、適用後の画像のヒストグラムでは右下りの傾向が緩和され平坦に近くなっていることが確認できます。

入力画像として、この画像を使用しました。

引用元
https://www.shopify.com/stock-photos/photos/narrow-cobbled-streets-in-black-and-white

cv2.equalizeHist関数のサンプルコードを下に示します。

import cv2
from matplotlib import pyplot as plt

# 画像の読み込み
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)

# ヒストグラムの作成(引数の'image'を[ ]で囲うことを忘れないで下さい)
histogram = cv2.calcHist([image], [0], None, [256], [0, 256])

# ヒストグラムの可視化
plt.rcParams["figure.figsize"] = [12,7.5]                         # 表示領域のアスペクト比を設定
plt.subplots_adjust(left=0.01, right=0.95, bottom=0.10, top=0.95) # 余白を設定
plt.subplot(221)                                                  # 2行2列の1番目(左上)の領域にプロットを設定
plt.imshow(image, cmap='gray')                                    # 画像をグレースケールで表示
plt.axis("off")                                                   # 軸目盛、軸ラベルを消す
plt.subplot(222)                                                  # 2行2列の2番目(右上)の領域にプロットを設定
plt.plot(histogram)                                               # ヒストグラムのグラフを表示
plt.xlabel('Brightness')                                          # x軸ラベル(明度)
plt.ylabel('Count')                                               # y軸ラベル(画素の数)

# ヒストグラム平坦化
result = cv2.equalizeHist(image)

# ヒストグラム平坦化後のヒストグラムの作成
histogram = cv2.calcHist([result], [0], None, [256], [0, 256])

# ヒストグラムの可視化
plt.subplot(223)                                                  # 2行2列の3番目(左下)の領域にプロットを設定
plt.imshow(result, cmap='gray')                                   # 画像をグレースケールで表示
plt.axis("off")                                                   # 軸目盛、軸ラベルを消す
plt.subplot(224)                                                  # 2行2列の4番目(右下)の領域にプロットを設定
plt.plot(histogram)                                               # ヒストグラムのグラフを表示
plt.xlabel('Brightness')                                          # x軸ラベル(明度)
plt.ylabel('Count')                                               # y軸ラベル(画素の数)
plt.show()

本サンプルコードでは結果の表示にmatplotlibを使用し、subplot関数により2行2列に結果等を表示しています。

ポイント

matplotlibのimshow関数でシングル チャンネルのグレースケール画像を表示する場合、cmap(colormap)引数に'gray'を指定します。
サンプルコードの14行目、29行目の様に記述してください。
plt.imshow(result, cmap='gray')

cmap(colormap)引数に'gray'を指定しない場合は下図の様な画像になります。

おわりに

OpenCVのcv2.equalizeHist関数を使用したヒストグラム平坦化により、画像のコントラストを向上させることができます。
パラメータ不要で自動的に改善してくれるため、下の記事のコントラスト調整方法より使いやすいです。

最後までご覧いただきありがとうございました。

参考記事

■(広告)OpenCVの参考書としてどうぞ!■

参考リンク

-Python, プログラミング, 画像処理
-