画像処理におけるヒストグラム
はじめに
今回は画像処理をするとき(2値化などで)に使うヒストグラムというものについてまとめる
ヒストグラムとは
ヒストグラムとは画像処理以外の分野で使われることもあるが
画像処理の分野では、各濃度値に対してその濃度値を持った画素数を求めたもので、濃度ヒストグラム
または単純にヒストグラムという。
ヒストグラムは主に横軸が濃度値、縦軸に画素数をとったグラフで表現される
ヒストグラムはその画像がどのような濃度値を持った画素から成り立っているかの情報をまとめたもので
画像処理において処理が容易なのもあり非常に有用な手段といえる
ヒストグラムの性質
ヒストグラムにはいくつかの性質がある
まずはヒストグラムは各画素の濃度値だけをとりあげているので、その画素の場所には関係しないグラフとなる
なのでその濃度値を持った画素がどれくらいあるかはわかってもその画素がどこにあるかまではわからない
つまり画像の持つ空間的特徴は考慮されずその情報はヒストグラム上では失われる
次に、ヒストグラムは同一の画像に対しては一意に、つまり一通りに定まるが
異なる画像であってもそれと同一のヒストグラムを持つことも可能性としてないわけではない
最後にヒストグラムは画像の各画素の濃度値を集めたのもなので
画像を分割してヒストグラムを求めた場合、それらの和が全体のヒストグラムと一致する
ヒストグラムの計算法
大きさMxN画素の濃度レベルがNGLの画像imgのヒストグラムを求め
配列hstに格納する方法でC言語ライクな擬似コードでしめす
また配列hstの初期値は各要素とも0であるとする
int i,j; int img[N][M]; int hst[NGL]; for(i = 0; i < N; i++){ for(j = 0; j < M; j++){ hst[img[i][j]]++; } }
濃度レベルが256で8bitだとすると
ヒストグラムは0〜255までの範囲となる
実用例
ヒストグラムの具体的な使い方は後述することにして
今回はpythonとOpenCVを使ってヒストグラムを表示するものを紹介する
例によりこのLenna.pngの画像を使う
結果
#coding:utf-8 import cv2 import pylab as plt img = cv2.imread("lenna256.png") hist = cv2.calcHist([img],[0],None,[256],[0,256]) plt.plot(hist) plt.xlim([0,256]) plt.show()
今回はカラーのままでやったがグレースケールにするとまた少し違って見える
ヒストグラム計算を自作してみる
ヒストグラムを求めること自体は結構簡単なので画像の入出力だけにOpenCVを使い
それ以外を自作するなんていうことも可能
#coding:utf-8 import numpy as np import cv2 img = cv2.imread("lenna256.png") #画像をグレースケールに変換 gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY) #ヒストグラムを作成 histgram = [0]*256 for i in range(0,len(gray)): for j in range(0,len(gray[0])): histgram[gray[i][j]] += 1