【Python・OpenCV】画像のヒストグラムを作成するには(cv2.calcHist)

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

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

【Python・OpenCV】画像のヒストグラムを作成するには(cv2.calcHist)

2023-07-18

はじめに

画像を解析において画像のコントラスト調整、画像の二値化(閾値処理)、画像のセグメンテーション(領域分割)、色調補正など、さまざまな画像処理操作においてヒストグラムの解析が行われます。
今回はヒストグラムを作成する方法について紹介します。

画像のヒストグラムとは

画像のヒストグラムとは、画像中のピクセル値の分布を表すグラフです。ヒストグラムは、画像処理やコンピュータビジョンの分野で頻繁に使用される重要なツールです。

画像はピクセルと呼ばれる小さな画素単位で構成されています。各ピクセルには、色情報(RGB画像の場合)または明度情報(グレースケール画像の場合)が含まれています。ヒストグラムは、画像内の各ピクセルの値を数値的に表し、その値の分布をグラフ化します。

ヒストグラムは一般的に、横軸にピクセル値の範囲を、縦軸にピクセルの数や出現頻度を表します。ヒストグラムを通じて、画像内のピクセル値の範囲や分布を視覚的に把握することができます。

ヒストグラムは、画像処理のさまざまなタスクに役立ちます。例えば、画像のコントラスト調整、画像の二値化(閾値処理)、画像のセグメンテーション(領域分割)、色調補正など、さまざまな画像処理操作においてヒストグラムの解析が行われます。

ヒストグラムを作成することで、画像の特徴や構造を理解し、適切な処理や解析を行うための手がかりを得ることができます。で

本記事では下の画像を使用させて頂きました。

RGBのカラー画像のヒストグラム計算の入力画像として、この画像を使用しています。

引用元
https://burst.shopify.com/photos/camping-kettle-and-coffee-cup?c=coffee

明るい画像のヒストグラム計算は、この画像をグレースケールに変換して使用しています。

引用元
https://pixabay.com/photos/cherry-blossoms-landscape-spring-2218781/

暗い画像のヒストグラム計算は、この画像をグレースケールに変換して使用しています。

引用元
https://www.pakutaso.com/20220846243post-42479.html

下の図はRGBのカラー画像を各チャンネルごとにヒストグラムを作成して描画したものです。
左側に入力画像、右側に赤、緑、青の各チャンネルのヒストグラムをmatplotlibを使って表示しました。
入力画像はこちらです。

参考記事
参考記事

cv2.calcHist関数

OpenCVではcv2.calcHist関数を使ってヒストグラム計算をすることができます。

cv2.calcHist関数の基本的な構文

cv2.calcHist(入力画像, channels, mask, histSize, ranges[, hist[, accumulate]])

引数

名称説明
入力画像(必須)入力画像データ。対応するデータ型はuint8、unit16またはfloat32です。
channels(必須)計算をするチャンネルのインデックス
mask(必須)画像の特定の領域を指定するマスク。画像の全データを計算する場合は'None'を指定。
histSize(必須)ヒストグラムのビンの数
ranges(必須)ヒストグラム計算の対象となる画素値の範囲
hist(オプション)ヒストグラムが均一かどうかのフラグ(デフォルト:True)
accumulate(オプション)累積フラグ。設定されている場合、ヒストグラムは割り当てられたときに最初にクリアされません。(デフォルト:False)

ポイント

フルスケールの輝度値をヒストグラム計算する場合は、histSizeが”[256]”、rangesが[0,256]を設定します。

戻り値

戻り値はヒストグラムのデータです。

使い方

明るい画像暗い画像をそれぞれヒストグラム計算した結果を示します。

ポイント

ヒストグラムの横軸は明るさを表しています。0が最も暗く、255が最も明るい状態です。
縦軸はそれぞれの画素の明るさが画像の中に存在する個数を表しています。

明るい画像は明るさの明るい方にピークがあり、暗い画像は明るさの暗い方にピークがあることがわかります。この様にヒストグラムにより、画像の特徴を捉えることができます。

サンプルコードを下に示します。

import cv2
import matplotlib.pyplot as plt

# 画像を読み込み
image = cv2.imread("image.jpg")

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

# Matplotlibで表示するためにRGBの並びに変更する
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# ヒストグラムの可視化
plt.rcParams["figure.figsize"] = [12,3.8]                        # 表示領域のアスペクト比を設定
plt.subplots_adjust(left=0.05, right=0.95, bottom=0.15, top=0.9) # 余白を設定
plt.subplot(121)                                                 # 1行2列の1番目の領域にプロットを設定
plt.imshow(rgb_image)                                            # 画像を表示
plt.axis("off")                                                  # 軸目盛、軸ラベルを消す
plt.subplot(122)                                                 # 1行2列の2番目の領域にプロットを設定
plt.plot(b_histogram, color='blue', label='blue')                # 青チャンネルのヒストグラムのグラフを表示
plt.plot(g_histogram, color='green', label='green')              # 緑チャンネルのヒストグラムのグラフを表示
plt.plot(r_histogram, color='red', label='red')                  # 赤チャンネルのヒストグラムのグラフを表示
plt.legend(loc=0)                                                # 凡例
plt.xlabel('Brightness')                                         # x軸ラベル(明度)
plt.ylabel('Count')                                              # y軸ラベル(画素の数)
plt.show()                                                       # ウィンドウにプロットを表示

このサンプルコードは「画像のヒストグラムとは」で示した結果を出力するものです。RGBのカラー画像のそれぞれの色チャンネルのヒストグラムを表示します。
表示にはmatplotlibを使用しています。

注意

入力画像の引数を[ ]で囲うことを忘れないでください。[ ]で囲わなくても結果が出力されますが、正しいものではない様です。

次のサンプルコードはカラー画像をグレースケールに変換して、ヒストグラムを計算する例です。
5行目の画像読み込み時に、cv2.imread関数の第2引数でcv2.IMREAD_GRAYSCALEを指定してグレースケールで読み込んでいます。
グレースケール画像のため画像のチャンネルは1つだけなので、ゼロ番目のチャンネルとなります。このため、cv2.calcHist関数の引数channelsは[0]となります。

import cv2
import matplotlib.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,3.8]                        # 表示領域のアスペクト比を設定
plt.subplots_adjust(left=0.05, right=0.95, bottom=0.15, top=0.9) # 余白を設定
plt.subplot(121)                                                 # 1行2列の1番目の領域にプロットを設定
plt.imshow(image, cmap='gray')                                   # 画像をグレースケールで表示
plt.axis("off")                                                  # 軸目盛、軸ラベルを消す
plt.subplot(122)                                                 # 1行2列の2番目の領域にプロットを設定
plt.plot(histogram)                                              # ヒストグラムのグラフを表示
plt.xlabel('Brightness')                                         # x軸ラベル(明度)
plt.ylabel('Count')                                              # y軸ラベル(画素の数)
plt.show()                                                       # ウィンドウにプロットを表示

おわりに

OpenCVを使用してヒストグラムを作成する手順を解説しました。
ヒストグラムは画像処理の基礎的な手法の一つであり、さまざまな応用があります。
今後、ヒストグラム計算を応用した、画像処理について紹介したいと思います。

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

■OpenCVの参考書としてどうぞ!■

参考記事

参考リンク

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