openCV
前回、openCVでの画像の二極化の方法を紹介しました。
今回は読み込んだ画像のデータ形式を確認して、ヒストグラムを表示させてみます。
今回も使う画像はこちらの蓮の花(lotus.jpg)を使っていきます。
それでは始めていきましょう。
グレースケール画像のデータ形式とヒストグラム表示
まずはデータ形式がより簡単なグレースケールのデータ形式を確認して、ヒストグラム表示をしてみましょう。
とりあえずデータを読み込んで、そのままprint関数でデータを表示してみます。
import cv2
img = cv2.imread("lotus.jpg", cv2.IMREAD_GRAYSCALE)
print(img)
実行結果
[[ 8 8 8 ... 24 24 23]
[ 8 8 8 ... 25 24 24]
[ 8 8 8 ... 25 25 25]
...
[ 8 9 9 ... 1 1 1]
[ 8 8 8 ... 1 1 1]
[ 8 8 8 ... 1 1 1]]
グレースケールの場合は二次元配列となっていることがわかりました。
この二次元配列で特定のピクセルのX、Yの場所、数値がピクセルの強度となっています。
ついでにデータの型も確認しておきましょう。
import cv2
img = cv2.imread("lotus.jpg", cv2.IMREAD_GRAYSCALE)
print(type(img))
実行結果
<class 'numpy.ndarray'>
numpyの配列(ndarray型)であることがわかりました。
ということはnumpyでいじってあげればデータを変えることができると考えられます。
その点に関してはまた別途試してみましょう。
ここからヒストグラムのデータを取得するには「cv2.calcHist([画像],[チャンネル数],マスク画像,[bin数],[画素値1,画素値2])」です。
チャンネル数は一つのピクセルに幾つの画素強度があるかということです。
グレースケールの場合は白黒の強度を1つの数字で表しているので1チャンネル、カラー画像の場合は「RGB」、つまり赤、緑、青の3種類の色の強度をそれぞれ一つずつの数字で表しているので3チャンネルです。
ただしopenCVの場合はRGBの順では無く「BGR(青、緑、赤)」の順で並んでいることに注意しましょう。
マスク画像はヒストグラムを取得したくない部分を黒塗りにした画像を用意すると、その部分以外のところのヒストグラムを取得してくれます。
bin数は何段階の強度に分けるかということですが、色は0から255までの256段階で表されることが多いので通常「256」としておきます。
画素値1、画素値2は取得する画素値の範囲です。
先ほど色は0から255の256段階で表されるとお話ししましたが、このうちのどの範囲を取得するか指定できるというわけです。
特段理由がない限りは「0, 256」(range関数と同じで最後の数字は入らないため)とします。
ということでこんな感じです。
import cv2
img = cv2.imread("lotus.jpg", cv2.IMREAD_GRAYSCALE)
hist = cv2.calcHist([img],[0],None,[256],[0,256])
print(hist)
実行結果
[[2.5849e+04]
[4.5799e+04]
[5.0401e+04]
(中略)
[2.8000e+01]
[6.0000e+00]
[3.0000e+00]]
これでヒストグラム用のデータの取得ができました。
あとはmatplotlibを使って表示していきます。
import cv2
import matplotlib.pyplot as plt
img = cv2.imread("lotus.jpg", cv2.IMREAD_GRAYSCALE)
hist = cv2.calcHist([img],[0],None,[256],[0,256])
plt.plot(hist)
plt.show()
実行結果
カラー画像のデータ形式とヒストグラム表示
次にカラー画像のデータ形式の確認とヒストグラム表示を行います。
まずデータ形式です。
import cv2
img = cv2.imread("lotus.jpg")
print(img)
実行結果
[[[ 6 11 2]
[ 6 11 2]
[ 6 11 2]
...
[ 6 40 0]
[ 6 40 0]
[ 5 39 0]]
[[ 6 11 2]
[ 6 11 2]
[ 6 11 2]
...
[ 7 41 1]
[ 6 40 0]
[ 6 40 0]]
[[ 6 10 4]
[ 6 10 4]
[ 6 11 2]
...
[ 7 41 1]
[ 7 41 1]
[ 7 41 1]]
(中略)
[[ 3 13 0]
[ 4 14 1]
[ 4 14 1]
...
[ 1 1 1]
[ 1 0 2]
[ 1 0 2]]
[[ 3 13 0]
[ 3 13 0]
[ 3 13 0]
...
[ 1 1 1]
[ 1 0 2]
[ 1 0 2]]
[[ 4 13 0]
[ 4 13 0]
[ 4 13 0]
...
[ 1 1 1]
[ 1 0 2]
[ 1 0 2]]]
こちらはX、Yの他にカラーであるBGRの情報が含まれるため、三次元配列になっています。
ヒストグラムのデータを取得するには「cv2.calcHist([画像],[チャンネル数],マスク画像,[bin数],[画素値1,画素値2])」で、カラーの場合は3チャンネル「0」、「1」、「2」がそれぞれ「B(青)」、「G(緑)」「R(赤)」の強度です。
ということでカラー画像のヒストグラムを表示するにはこんな感じになります。
import cv2
img = cv2.imread("lotus.jpg")
hist_b = cv2.calcHist([img],[0],None,[256],[0,256])
hist_g = cv2.calcHist([img],[1],None,[256],[0,256])
hist_r = cv2.calcHist([img],[2],None,[256],[0,256])
plt.plot(hist_b, color="blue")
plt.plot(hist_g, color="green")
plt.plot(hist_r, color="red")
plt.show()
実行結果
あまりカラー画像のヒストグラムを表示するにはいい画像ではなかったようですが、とりあえずヒストグラムが表示できました。
次回はopenCVで文字や図形(線、矢印、四角形、丸、マーカー)を表示する方法を紹介します。
ではでは今回はこんな感じで。
コメント