LoginSignup
20

More than 3 years have passed since last update.

Python+OpenCVで画像解析(画像に写っている星を検出)

Posted at

はじめに

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() #画像を表示

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20