ヒストグラム
ヒストグラムを用いることで、解析したい画像の中にどの色(青など)が多いのか調べることができます。
正確に言えば、画素値の分布を描画することで視覚的に分かりやすくします。
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
# 画像の確認
img = cv2.imread('sample.png')
cv2.imshow('img', img)
cv2.waitKey(0) & 0xFF
cv2.destroyAllWindows()
cv2.waitKey(1) & 0xFF
# RGBのヒストグラム
color_list = ['blue', 'green', 'red']
for i, j in enumerate(color_list):
hist = cv2.calcHist([img], [i], None, [256], [0, 256])
plt.plot(hist, color=j)
# グレースケールのヒストグラム
img_gray = cv2.imread('sample.png', 0)
hist2 = cv2.calcHist([img_gray], [0], None, [256], [0, 256])
plt.plot(hist2)
ヒストグラム平坦化
平坦化は均一化や均等化などとも呼ばれたりしますが、全部同じ意味と思っていただいて大丈夫です。
平坦化を行うと、画像のコントラストが強調されて、見たい画像の箇所をはっきりと見ることが可能になります。
注意点としては、カラー画像には使えないので、グレースケール化は必須です。
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
img = cv2.imread('sample.png', 0)
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
plt.plot(hist)
img_eq = cv2.equalizeHist(img)
hist_e = cv2.calcHist([img_eq], [0], None, [256], [0, 256])
plt.plot(hist_e)
# 平坦化とオリジナル画像の比較
cv2.imshow('img', img)
cv2.imshow('eq', img_eq)
cv2.waitKey(0) & 0xFF
cv2.destroyAllWindows()
cv2.waitKey(1) & 0xFF
γ(ガンマ)変換
γ(ガンマ)変換とは画像の明るさの変換方法です。
γが1の場合は直線になり、入力と出力が同じになります。
γが1未満の場合には画像が暗くなり、逆に1を超えると明るくなります。
import cv2
import numpy as np
gamma = 1.5
img = cv2.imread('Lenna_(test_image).png')
gamma_cvt = np.zeros((256, 1), dtype=np.uint8)
for i in range(256):
gamma_cvt[i][0] = 255 * (float(i)/255) ** (1.0 / gamma)
img_gamma = cv2.LUT(img, gamma_cvt)
cv2.imshow('img', img)
cv2.imshow('gamma', img_gamma)
cv2.waitKey(0) & 0xFF
cv2.destroyAllWindows()
cv2.waitKey(1) & 0xFF
補足
トラックバーの作成
import cv2
def onTrackbar(position):
global trackValue
trackValue = position # 表示位置
trackValue = 100
cv2.namedWindow('img')
cv2.createTrackbar('track', 'img', trackValue, 255, onTrackbar)
img = cv2.imread('Lenna_(test_image).png')
cv2.imshow('img', img)
cv2.waitKey(0) & 0xFF
cv2.destroyAllWindows()
cv2.waitKey(1) & 0xFF
マウスイベント
import cv2
import numpy as np
def print_position(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN: # クリックされたら
print(x, y) # 座標表示
img = np.zeros((512, 512), np.uint8)
cv2.namedWindow('img')
cv2.setMouseCallback('img', print_position)
cv2.imshow('img', img)
cv2.waitKey(0) & 0xFF
cv2.destroyAllWindows()
cv2.waitKey(1) & 0xFF
2値化
閾値の取り方は、手動で設定するやり方や、分布を見て自動的に設定してくれるやり方だなどが存在します。
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
img = cv2.imread('Lenna_(test_image).png', 0)
threshold = 100 # 閾値
ret, img_th = cv2.threshold(img, threshold, 255, cv2.THRESH_BINARY)
cv2.imshow('img_th', img_th)
cv2.waitKey(0) & 0xFF
cv2.destroyAllWindows()
cv2.waitKey(1) & 0xFF
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
plt.plot(hist)
ret2, img_o = cv2.threshold(img, 0, 255, cv2.THRESH_OTSU)
cv2.imshow('img_o', img_o)
cv2.waitKey(0) & 0xFF
cv2.destroyAllWindows()
cv2.waitKey(1) & 0xFF
2値化とトラックバーの組み合わせ
import cv2
img = cv2.imread('Lenna_(test_image).png', 0)
def onTrackbar(position):
global threshold
threshold = position
ret, img_th = cv2.threshold(img, threshold, 255, cv2.THRESH_BINARY)
# img_th = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 3, threshold)
cv2.imshow('img', img_th)
cv2.namedWindow('img')
threshold = 100
cv2.createTrackbar('track', 'img', threshold, 255, onTrackbar)
while True:
ret, img_th = cv2.threshold(img, threshold, 255, cv2.THRESH_BINARY)
cv2.imshow('img', img_th)
if cv2.waitKey(10) & 0xFF:
break
cv2.waitKey(0) & 0xFF
cv2.destroyAllWindows()
cv2.waitKey(1) & 0xFF