Edited at

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

More than 1 year has passed since last update.

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

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


泳いでいる鯉の認識

今回扱う映像は、泳いでいる鯉の映像です。



(※GIF動画にしたので画像が少々荒いです。)

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


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

これまでのブログでは、scikit-learnを使ってきましたが、今回はdlibという機械学習のライブラリを使ってみます。

オープンソースのC++ベースのライブラリで、Pythonからも使用することができます。

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

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

brew install boost

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


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

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

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

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

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キーを押しながらドラッグすると、

赤い矩形範囲がマーキングできます。

全てのサンプリング画像に対して、鯉の部分を矩形でマーキングしたあとに

「File」メニューから「Save」コマンドで保存します。

サンプリング画像と同階層に生成された「training.xml」ファイルには

以下のように、画像ファイルと矩形のbox情報(top,left,width,height)が

記録されていることが確認できます。


学習データの作成

先ほどの矩形データの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()

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

サンプリング画像は、鯉が全体で写っている画像で学習させているので、

見切れているときは、青枠は表示されませんね。

ただ、20ファイル程度のサンプリングデータで、動画中の対象物体の認識も

そこそこ出来ているようです。

今回はここまで。


参照動画URL:

https://pixabay.com/videos/id-3613/