LoginSignup
31
28

More than 5 years have passed since last update.

泳いでいる鯉を認識してみる

Last updated at Posted at 2017-09-29

今回は、これまでと趣向を変えて物体認識について取り扱ってみます。

動画の中から任意の個体を認識させて、それを追跡する検証をPythonベースのプログラムで行ってみます。

泳いでいる鯉の認識

今回扱う映像は、泳いでいる鯉の映像です。
Goldfish.gif
(※GIF動画にしたので画像が少々荒いです。)

画面を横切っていく、少し体の大きな赤色の鯉を認識させてみます。
goldfish_tartget.jpg

機械学習ライブラリ「dlib」

これまでのブログでは、scikit-learnを使ってきましたが、今回はdlibという機械学習のライブラリを使ってみます。
オープンソースのC++ベースのライブラリで、Pythonからも使用することができます。

dlibをインストールする場合は、ライブラリのビルドをC++ライブラリのboostを用いて行うので、それも合わせてインストールする必要があります。

ちなみに、Macの場合のインストールコマンドは以下の通り。

brew install boost
brew install boost-python --with-python3
pip install dlib

サンプリング画像と矩形データの作成

動画から対象の鯉が写っているコマをいくつかキャプチャして、学習データを作成していきます。

今回は動画プレイヤーでコマを進めながら20ファイル分、サンプリングしてみます。
sampling.png

サンプリングした画像から、鯉が表示されている矩形をデータ化します。

dlibに矩形データを作成する、imglabというGUIツールが用意されていますので、それを使います。
矩形データはxml形式のファイルで生成されます。
今回は、training.xmlというファイルにしましょう。

サンプリング画像を内包するディレクトリで、以下のコマンドを
実行します。
サンプル画像はPNGファイルで、「IMG_01.png」のような連番で
用意しておきます。

~/dlib/tools/imglab/build/imglab training.xml
~/dlib/tools/imglab/build/imglab -c training.xml IMG_*.png

以下のような、GUIのウィンドウが表示されます。
各画像ファイルに対して、Shiftキーを押しながらドラッグすると、
赤い矩形範囲がマーキングできます。

imglab.png

全てのサンプリング画像に対して、鯉の部分を矩形でマーキングしたあとに
「File」メニューから「Save」コマンドで保存します。

サンプリング画像と同階層に生成された「training.xml」ファイルには
以下のように、画像ファイルと矩形のbox情報(top,left,width,height)が
記録されていることが確認できます。

xml_shot.png

学習データの作成

先ほどの矩形データのxmlファイルで、学習データを作成していきます。

dlibのsimple_object_detectorを用いて認識を行うため、
それ用の学習データを用意します。

pythonで以下のコードで「detector.svm」という学習データを
作成しています。

import dlib

#学習用のオプション変数の生成.
options = dlib.simple_object_detector_training_options()

#認識はSVMアルゴリズムを使っている。それのコストパラメータを設定.
options.C = 3

#学習処理を行うときの実行スレッドの数.
options.num_threads = 8

#左右反転のイメージは生成しない(鯉が一方向に進むだけなので)
options.add_left_right_image_flips = False

#学習処理の経過を出力する(ターミナルで確認可能)
options.be_verbose = True

#矩形のXMLデータから学習データを作成.
dlib.train_simple_object_detector("training.xml", "detector.svm", options)

#学習データから認識オブジェクトの作成.
detector = dlib.simple_object_detector("detector.svm")

認識アルゴリズムはサポートベクターマシン(SVM)を用いています。
options.CはSVMのコストパラメータと呼ばれるもので、値が大きいほど誤認識に対して厳しく判定するようになります。

動画の鯉を認識させてみる

上記で生成した鯉の認識オブジェクトを用いて、実際に動画中の鯉を認識させてみます。

動画の読み込みはOpenCVを用いて行います。
動画はmp4形式のファイルで扱っています。

OpenCVのVideoCaptureに動画ファイルを指定してやれば、簡単に動画のフレームを読み込み、解析処理を行うことができます。

以下のプログラムでは、VideoCaptureで読み込んだフレーム画像に対して、dlibの認識オブジェクト(detector)を通して、鯉の判定矩形を取得しています。

それをフレームに青枠で書き込んで、再生ウィンドウに出力しています。

import cv2

#鯉の動画(input.mp4)をキャプチャーする.
cap = cv2.VideoCapture("input.mp4")

while(cap.isOpened()):
    #キャプチャーで動画のフレームを読み込む.
    ret, frame = cap.read()

    #フレームが出来なかった場合(動画が終了した場合など)はループを抜ける.
    if ret == False:
        break

    # 読み込んだフレームを鯉の矩形認識処理に通す.
    dets = detector(frame)

    # 返された矩形の数分、フレームに青色で矩形を書き込む.
    for det in dets:
        cv2.rectangle(frame, (det.left(), det.top()), (det.right(), det.bottom()), (255, 0, 0), 3)

    # 出力ウィンドウにフレームを表示する.    
    cv2.imshow("frame", frame)

    if cv2.waitKey(1) == 27: # ESCキーで終了
        break   

#キャプチャーの解放.        
cap.release()
#出力ウィンドウの破棄.
cv2.destroyAllWindows()

実行すると以下のような映像が出力されます。

detect_frame.gif

サンプリング画像は、鯉が全体で写っている画像で学習させているので、
見切れているときは、青枠は表示されませんね。

ただ、20ファイル程度のサンプリングデータで、動画中の対象物体の認識も
そこそこ出来ているようです。

今回はここまで。


参照動画URL:
https://pixabay.com/videos/id-3613/

31
28
0

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
31
28