【Python/OpenCV】画像のヒストグラムを求める

この記事では、Python版OpenCVで画像のヒストグラムを求める方法をソースコード付きで解説します。

ヒストグラム

画像処理におけるヒストグラムでは、横軸に画素値(階調値)、縦軸にその画素数を取ります。
つまり、「画像中に画素値が〇〇の画素は何個あるのか」を示します。
【詳細】【画像処理】ヒストグラムの原理・特徴

今回は、Python言語を用いて画像のヒストグラムを求めてみました。
ヒストグラムの計算部分は以下の2種類の方法を実装してみました。

方法①・・・NumPyの「numpy.histogram」を使用
方法②・・・OpenCVの「cv2.calcHist」を使用

書式①

hist, bins = np.histogram(src.ravel(),256,[0,256])
パラメータ名 説明
src 入力画像(1チャンネル)
hist ヒストグラムのデータ(1次元配列)

書式②

hist = cv2.calcHist(src)
パラメータ名 説明
src 入力画像(1チャンネル)
hist ヒストグラムのデータ(2次元配列)

ソースコード(Python3+OpenCV3)

サンプルプログラムのソースコードです。

グレースケール(1ch)

#-*- coding:utf-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt


def main():
    # 入力画像を読み込み
    img = cv2.imread("input.jpg")
    
    # グレースケール変換
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

    # 方法1(NumPyでヒストグラムの算出)
    hist, bins = np.histogram(gray.ravel(),256,[0,256])

    # 方法2(OpenCVでヒストグラムの算出)
    #hist = cv2.calcHist([img],[0],None,[256],[0,256])

    # ヒストグラムの中身表示
    print(hist)

    # グラフの作成
    plt.xlim(0, 255)
    plt.plot(hist)
    plt.xlabel("Pixel value", fontsize=20)
    plt.ylabel("Number of pixels", fontsize=20)
    plt.grid()
    plt.show()


if __name__ == "__main__":
    main()

RGBカラー(3ch)

#-*- coding:utf-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt


def main():
    # 入力画像を読み込み
    img = cv2.imread("input.jpg")
    
    b, g, r = img[:,:,0], img[:,:,1], img[:,:,2]

    # 方法1(NumPyでヒストグラムの算出)
    hist_r, bins = np.histogram(r.ravel(),256,[0,256])
    hist_g, bins = np.histogram(g.ravel(),256,[0,256])
    hist_b, bins = np.histogram(b.ravel(),256,[0,256])

    # 方法2(OpenCVでヒストグラムの算出)
    #hist_r = cv2.calcHist([r],[0],None,[256],[0,256])
    #hist_g = cv2.calcHist([g],[0],None,[256],[0,256])
    #hist_b = cv2.calcHist([b],[0],None,[256],[0,256])

    # グラフの作成
    plt.xlim(0, 255)
    plt.plot(hist_r, "-r", label="Red")
    plt.plot(hist_g, "-g", label="Green")
    plt.plot(hist_b, "-b", label="Blue")
    plt.xlabel("Pixel value", fontsize=20)
    plt.ylabel("Number of pixels", fontsize=20)
    plt.legend()
    plt.grid()
    plt.show()


if __name__ == "__main__":
    main()

※動作には、OpenCVライブラリのインストールが必要です。

実行結果

サンプルプログラムの実行結果です。

■入力画像(右)、1chのヒストグラム(中)、3chのヒストグラム(右)

■出力結果(cv2.calcHistに1ch画像を入力した場合)

[[  113.]
 [   34.]
︙
 [  922.]
 [ 3124.]]

■出力結果(numpy.histgramに1ch画像を入力した場合)

[ 113   34 … 922 3124]

【おすすめ記事】
PythonでOpenCV入門 サンプル集
【Python】画像処理プログラミング入門
【画像処理入門】アルゴリズム&プログラミング

シェア&フォローお願いします!