Yuki’s blog

自身の成果物や好きなことを発信していきたいと思います。情報系のジャンルが多いです。

ヒストグラム均等化法【実装】

     

こんばんは。

今回は前回の記事で説明したヒストグラム均等化の理論を実際に実装してみたいと思います。前回の記事はこちら↓
yuki9892.hatenablog.com

ヒストグラム均等化法のプログラム

 pythonで実装します。画像の読み込み、画像からヒストグラムの算出はopencvで行っています。今回、使用した画像はおなじみの画像です。

f:id:Yuki9892:20191222230312p:plain
lenna image

import numpy as np
import cv2
import matplotlib.pyplot as plt
#画像読み込み
input_img = cv2.imread('../images/lenna.jpg', 0)
#create_histogram
img_hist = cv2.calcHist([input_img], channels = [0], mask = None, histSize = [256], ranges = [0, 256])

plt.plot(img_hist), plt.title('img_histgram')
print(input_img.shape)

#ヒストグラムの正規化
number_pix = input_img.shape[0] * input_img.shape[1]
normalize_hist = np.zeros(img_hist.shape, dtype = float)
print(normalize_hist.shape)
for i in range(img_hist.shape[0]):
    normalize_hist[i][0] = img_hist[i][0] / number_pix

#グラフの塗りつぶし
hist_list = []
for i in range(normalize_hist.shape[0]):
    hist_list.append(normalize_hist[i][0])
plt.plot(np.arange(256), hist_list), plt.title('normalize_hist')
plt.fill_between(np.arange(256), hist_list, color = 'lightblue')
 
#ヒストグラム変換関数
def transform_function(normalize_hist):
    transform_hist = np.zeros(normalize_hist.shape, dtype = float)
    for i in range(normalize_hist.shape[0]):
        for j in range(i):
            transform_hist[i][0] += (normalize_hist.shape[0] - 1) * normalize_hist[j][0]
    
    #計算結果を少数地を丸める
    for i in range(normalize_hist.shape[0]):
        transform_hist[i][0] = round(transform_hist[i][0])
        
    return transform_hist

#変換関数を求め表示
t_function = transform_function(normalize_hist)
plt.plot(t_function), plt.title('transform_function')
print(t_function)

#新しいヒストグラムの作成
equalize_hist = np.zeros(t_function.shape, dtype = float)
for i in range(t_function.shape[0]):
    number = int(t_function[i][0])
    equalize_hist[number][0] = normalize_hist[i][0] 
    
#グラフの塗りつぶし
my_list = []
for i in range(t_function.shape[0]):
    my_list.append(equalize_hist[i][0])

plt.subplot(111)
plt.plot(np.arange(256), my_list, linewidth = 0.5), plt.title('hist_equalization')
plt.fill_between(np.arange(256), my_list, color = 'lightblue')

実装結果

f:id:Yuki9892:20191222230452p:plain
input_image_histogram
f:id:Yuki9892:20191222230955p:plain
transform_function
f:id:Yuki9892:20191222230611p:plain
histogram_equalization
 上2つの図を見て分かるように、輝度値の分布が広がってることが分かると思います。対応しないx軸もあるのでヒストグラム均等化後には値が0のビンがたくさん有ります。ちなみに、画像がどんな感じになるかというと以下のようになります!
f:id:Yuki9892:20191222232844p:plain
ヒストグラム均等化画像(左)との比較
 随分、コントラストが強調され明るい画像になっていますね!!このヒストグラム均等化法の応用でヒストグラムマッチングというものあるのでまたの機会に記事にしたいと思います。