はじめに
Pythonを使って星を数えてみよう
↑のnoteで使用したコードについて説明していきます。
下のコードは「(練習)いちごの検出、カウント」で使用したものです。
Python 3.7.1
OpenCV 3.4.2
numpy 1.15.4
matplotlib 3.0.2
import cv2
import numpy as np
import matplotlib.pyplot as plt
imageGRAY = cv2.imread("strawberry.jpg", cv2.IMREAD_GRAYSCALE)
imageBGR = cv2.imread("strawberry.jpg", cv2.IMREAD_COLOR)
blur = cv2.GaussianBlur(imageGRAY, (59, 59), 0)
ret1, th1 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
image, contours, _ = cv2.findContours(th1.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
frame = cv2.drawContours(imageBGR, contours, -1, (0,0,0), 10)
cv2.imwrite("/Users/ユーザー名/保存先/保存したい画像の名前", frame)
count = []
for i in contours :
x = 0
y = 0
for n in i :
x += n[0][0]
y += n[0][1]
count.append([x/len(i), y/len(i)])
count = np.array(count)
print("結果 : " + str(len(count)) + "個")
1.画像を読み込む
#グレースケール化して画像を読み込む
imageGRAY = cv2.imread("strawberry.jpg", cv2.IMREAD_GRAYSCALE)
#カラー画像を読み込む
imageBGR = cv2.imread("strawberry.jpg", cv2.IMREAD_COLOR)
cv2.imread関数を使って画像を読み込みます
cv2.imread()では画像はBlue,Green,Redの順で読み込まれますが、
matplotlibはRed,Green,Blueの順で画像を解釈するので注意してください。
※cv2.cvtColor(画像, cv2.COLOR_BGR2RGB)でBGR→RGBに変換できます
2.画像をぼかす(前処理)
blur = cv2.GaussianBlur(imageGRAY, (59, 59), 0)
cv2.GaussianBlur関数を使って画像をぼかします。
今回行った星を検出するような際にはこの処理は行いません。
3.閾値処理で2値化(前処理)
ret1, th1 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
cv2.threshold関数を使って画像を閾値処理して2値化します。
この関数は2つの出力を返します。1つ目(ret1)が閾値で、2つ目(th1)が2値化された画像になります。
また閾値処理の方法として「cv2.THRESH_BINARY_INV」と「cv2.THRESH_OTSU」の2種類を使用しました。
4.物体の輪郭を検出する
image, contours, _ = cv2.findContours(th1.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cv2.findContours関数を使って輪郭を検出します。
(注:入力画像はNumPy配列しか受け取らないのでnp.uint8型に変換)
返り値であるcontoursには抽出された輪郭のリストが返されます。
5.検出した輪郭を写真に描画
frame = cv2.drawContours(imageBGR, contours, -1, (0,0,0), 10)
cv2.imwrite("/Users/ユーザー名/保存先/保存したい画像の名前", frame)
cv2.drawContours関数を使って写真に抽出した輪郭を描画します。
全輪郭を描画したい場合は第3引数に−1を指定します。
6.各輪郭の重心を求めて座標としてリスト(count)に追加
count = []
for i in contours :
x = 0
y = 0
for n in i :
x += n[0][0]
y += n[0][1]
count.append([x/len(i), y/len(i)])
count = np.array(count)
append()を使ってリストの末尾に座標を追加していきます。
7.個数を表示
print("結果 : " + str(len(count)) + "個")
(補足)matplotlibでグレースケール化した画像を表示
plt.imshow(imageGRAY,'gray') #matplotlibは疑似カラーに自動で表示するため灰色を指定
plt.colorbar() #カラーバーを表示
plt.xticks([]) #[]でグラフのX軸を非表示
plt.yticks([]) #[]でグラフのY軸を非表示
plt.show() #画像を表示