LoginSignup
42

More than 5 years have passed since last update.

画像解析 opencv python入門

Last updated at Posted at 2016-09-17

macに以下をインストール

brew update
brew install -v cmake
brew tap homebrew/science
brew install opencv
export PYTHONPATH="/usr/local/lib/python2.7/site-packages/:$PYTHONPATH"

画像を取り込み表示する

適当にメッシの画像を撮ってきて「messi.jpeg」で保存
messi5.jpeg

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import numpy as np
import cv2


# 元の画像を読み込む
img = cv2.imread('messi.jpeg',cv2.IMREAD_UNCHANGED)
# ウィンドウに表示
cv2.imshow("result", img)
# 書き出し
cv2.imwrite('img.jpg', img)
# 終了処理
cv2.waitKey(0)
cv2.destroyAllWindows()

終わらなかったら、control + z で強制終了

グレースケールにする

gray_img = cv2.imread('messi.jpeg', cv2.IMREAD_GRAYSCALE)
cv2.imshow("result", gray_img)

gray_messi.png

輪郭だけにする

canny_img = cv2.Canny(gray_img, 50, 110)
cv2.imshow("result", canny_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

canny_messi.png
```

輪郭の強さを変える

cv2.Canny()はキャニー法という方法で処理をする関数で、2つの閾値を設定します。数値を上げると書かれる輪郭は少なくなります。
詳しくはこちら http://postd.cc/image-processing-101/

canny_img = cv2.Canny(gray_img, 200, 400)

canny_img.jpg

ボールを検出する

対象となる物体が線や円などの標準的な形態であれば、ハフ変換というのを使って検出できます

circles = cv2.HoughCircles(canny_img, cv2.cv.CV_HOUGH_GRADIENT,
          dp=2, minDist=50, param1=20, param2=30,
          minRadius=5, maxRadius=20 )
print circles
import matplotlib.pyplot as plt
plt.imshow(canny_img)
plt.show()

パラメータ

dp ・・・ 処理するときに元画像の解像度を落として検出する場合は増やす。例えば、1だとそのままの画質で処理して、2だと1/2に縮小して処理するらしい。
minDist ・・・ 検出される円と円の最小距離
param1 ・・・ 「Cannyのエッジ検出器で用いる二つのしきい値の高い方」らしい。低いほどいろんなエッジを検出する
param2 ・・・ 中心検出計算時のしきい値。低いほど円じゃないものも検出する
minRadius ・・・ 最小半径
maxRadius ・・・ 最大半径

すると、5つ候補が出てきた [x,y,半径]

[[[ 125.           51.           16.27882004]
  [ 193.          161.            5.83095169]
  [ 131.          155.            8.24621105]
  [  71.           73.           18.02775574]
  [ 161.           91.           17.80449295]]]

円を元画像にプロット

cups_circles = np.copy(img)

if circles is not None and len(circles) > 0:
    circles = circles[0]
    for (x, y, r) in circles:
        x, y, r = int(x), int(y), int(r)
        cv2.circle(cups_circles, (x, y), r, (255, 255, 0), 4)
    plt.imshow(cv2.cvtColor(cups_circles, cv2.COLOR_BGR2RGB))
    plt.show()

print('number of circles detected: %d' % len(circles[0]))

figure_1.png

ほう、、、あってるけど、なんか変なのもカウントされている

パラメータなどを調整すると顔とボールだけにできた
(グレースケールをやめたらいい感じになった)
figure_1.png

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
import cv2
import matplotlib.pyplot as plt

img = cv2.imread('messi5.jpeg',cv2.IMREAD_UNCHANGED)
canny_img = cv2.Canny(img, 230, 500)


# find hough circles
circles = cv2.HoughCircles(canny_img, cv2.cv.CV_HOUGH_GRADIENT,
          dp=2, minDist=100, param1=25, param2=30,
          minRadius=5, maxRadius=20 )
print circles

cups_circles = np.copy(img)

# if circles are detected, draw them
if circles is not None and len(circles) > 0:
    # note: cv2.HoughCircles returns circles nested in an array.
    # the OpenCV documentation does not explain this return value format
    circles = circles[0]
    for (x, y, r) in circles:
        x, y, r = int(x), int(y), int(r)
        cv2.circle(cups_circles, (x, y), r, (255, 255, 0), 4)
    plt.imshow(cv2.cvtColor(cups_circles, cv2.COLOR_BGR2RGB))
    plt.show()

cv2.waitKey(0)
cv2.destroyAllWindows()

ほう。色のフィスタをかけるともっと綺麗みたい
http://stackoverflow.com/questions/22870948/how-can-i-pythonically-us-opencv-to-find-a-a-basketball-in-an-image
http://www.pyimagesearch.com/2015/09/14/ball-tracking-with-opencv/

もしアプリ化をするなら参考になりそう
http://www.melt.kyutech.ac.jp/2015/onoue.pdf#search='opencv+ball+%E7%B2%BE%E5%BA%A6'

なんと、ラズパイで、追っかけカメラが作れるのか!
https://www.youtube.com/watch?v=58xxn6d_bUg

次は、動画チュートリアルをやってみる
http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_gui/py_video_display/py_video_display.html

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
42