【Python】OpenCVのMeanShiftとCamShiftによる物体の発見・追跡

Pythonの応用
スポンサーリンク

初心者の独学でのプログラミング学習はとてもツライ…

プログラミングをマスターしたい!

今のIT業界はプログラミングエンジニアが不足していると言われています。
高収入の職業とも言われる分野もありますし、AI、機械学習、ディープラーニング、IOTといった注目される分野が目白押しです。

でも、いざ初心者がプログラミングをマスターしようとすると…

  • 本を読んだりネットの記事で自力で勉強しているけど限界を感じる
  • プログラミングスクールに定期的に通うのは面倒だ
  • 地方に住んでると家の近くにプログラミングスクールなんてない
  • どのプログラミング言語を学べばいいのか悩む
  • 実際の就職や転職にプログラミングが活かせるのか心配だ

など、プログラミングを自分で勉強しようとすると悩みが尽きません。

プログラミングに詳しい友人に教えてもらおうと思っても、そんな友人なんて滅多にいません。いたとしても細かく教えてくれるほど時間に余裕がある人はいないでしょう。

そんな独学でプログラミングをマスターするのに限界を感じてる方に、オンラインプログラミングスクールをがおすすめです。

おすすめのオンラインスクールはこちら

OpenCVを使ったPythonでの画像処理について、Lucas-Kanade法密なオプティカルフローでの物体の追跡(Object Tracking)について触れてきました。

ここでは画像中にある物体を発見・追跡するためのMeanShift、CamShiftアルゴリズムについて見ていこうと思います。

MeanShiftアルゴリズムは、画像中に点の分布などがあるときに、そこへ小さなウィンドウを移動させて画素の分布密度や画素数が最大になる領域にウィンドウを合わせていく処理になります。

CamShiftアルゴリズムは、MeanShiftアルゴリズムで追跡するウインドウが常に同じサイズなので、追跡対象の見え方によってウィンドウのサイズを調節する処理になります。

ここでは、webカメラで撮影された顔を検出して、その移動を追跡する操作をやっていきます。

スポンサーリンク

OpenCVでのMeanShiftアルゴリズム

では、OpenCvのMeanShiftアルゴリズムを使ってwebカメラでの物体追跡(顔の追跡)をやってきましょう。

OpenCVとNumPyのライブラリーをインポートして、内臓webカメラに接続して映像を読み込みます。CascadeClassifier()を使って顔の検出器を読み込んでおきます。

Haar Cascadesによる顔の検出はすでにあつかったのでこちらを参照してください。

【Python】OpenCVのHaar Cascadesによる顔検出
OpenCVを使ったPythonでの画像処理について、Haar Cascadesという分類器を使って画像からの顔の検出を扱っていきます。顔の検出と顔認識とは違うことに注意しましょう。ここでは画像からの顔検出とwebカメラの顔検出を行います。

while文を使って、キャプチャーを実行して行きます。

while文を使って、キャプチャーを実行し、read()で読み込みます。retはデータの読み込みの可否のture/falseの取得、frameは映像のパラメータの取得です。

先にCascadeClassifier()で顔の検出器を読み込んでいるので、detectMultiScale()を使って顔検出を行います。

顔検出の最初のパラメータの位置と幅と高さをface_x,face_y,w,hにタプルで渡して、追跡で移動させるウインドウを作ります。

このウインドウは全体画像とは異なるサイズの画像の合成となるので、トラッキングの為の関心領域ROI(Region of Interest)を設定します。フレームの中にオフセットの位置を指定しています。このROIについては画像の合成のところですでに扱った内容です。

【Python】OpenCVで画像を合成する - addWeighted, bitwise演算, ROI
Pythonに画像処理ライブラリのOpenCVを使って、2つの画像を合成したり重ねたりする方法を見ていきたいと思います。addWeighted()での合成や、関心領域(ROI)とbitwise演算を使った合成の方法を見ていきます。

これをHSVカラーマッピングで使用するようにcv2.cvtColor()で変換します。

物体が動くと、その動きはヒストグラムを逆投影した画像中に反映して映されるので、各フレームでターゲットを逆投影するためのヒストグラムをcalcHist()を使って見つけます。

calcHist()についてはこちらで扱いました。

【Python】OpenCVを使ったヒストグラム - calcHist(), equalizeHist()
OpenCVを使ったPythonでの画像処理についてヒストグラムを扱います。ヒストグラムを求めるにはcalcHist()を使います。画像のコントラストを調整するのにヒストグラム平坦化があり、equalizeHist()を使います。

これを、関数cv2.normalize()を使って最小0、最大255の範囲でヒストグラム配列値を正規化してコントラストを低減しています。

term_criteは繰り返し処理の終了条件です。Lucas-Kanade法を扱った時にも触れました。この条件が満たされた時にアルゴリズムの繰り返し計算が終了します。cv2.TERM_CRITERIA_EPSは指定された精度(epsilon)、 cv2.TERM_CRITERIA_COUNTは指定された繰り返しの最大回数(count)です。ここではこれらのどちらかの条件が満たされた時に繰り返し計算の終了を指定しています。ここでは回数を10、精度を1にしています。

各種設定が決まったので、if文を使って画像の読み込みが成立している時の処理を行って行きます。コードの終わりの方でelse文を指定してretがfalseならbreak処理します。

まずHSV形式でストリームのフレームを変換します。

cv2.calcBackProject()を使い、先に作成したroi_histに基づいた逆投影を計算します。パラメータはcalcHist()とほぼ同じ使い方です。

矩形の新しい座標を取得するためにcv2.meanShift()を適用します。

取得した新しい座標から、cv2.rectangle()を使ったframe内に赤い矩形を描いていきます。

これをimshow()で描画します。

if cv2.waitKey(30) & 0xff == 27: で[esc]キーが押された時にbreak処理します。

while文はここまでです。

最後に、cap.release()でデバイスを解放し、cv2.destroyAllWindows()で全て終了させます。

コードは以上です。

このコードのwhile文の中の冒頭のface_rectからif文の手前のterm_criteまでの部分は、取り出して外に出し、face_cascadeの下に配置してもいいと思います。私の環境ではカメラの起動に時間がかかって、顔を認知できずに初期の追跡ウインドウが設定できなかったので、こういうコードにしてみました。

このPythonスクリプトを実行すると、webカメラが起動し、検出された顔が赤い四角で囲まれます。ただし、最初に検出した顔で四角の追跡サイズを決めているので、カメラに近ずいたり遠ざかった場合に問題が生じます。ここを調整するのが、次のCamShiftアルゴリズムです。

スポンサーリンク

OpenCVでのCamShiftアルゴリズム

CamShiftアルゴリズムは、MeanShiftアルゴリズムで追跡するウインドウが常に同じサイズなので、追跡対象の見え方によってウィンドウのサイズを調節する処理になります。

上のコードを下記のように書き換えてます。全体の流れは同じで一部分を変更しているだけです。

コメントアウトで3段の#で挟まれている部分がMeanShiftのコードと違う部分です。この部分のみについて触れていきます。

cv2.MeanShift()の代わりにcv2.CamShift()で処理して矩形の新しい座標を取得します。

cv2.boxPoints()で矩形データを4点座標に変換し、np.int0で整数にキャストしています。

これをcv2.polylines()を使って多角形として描いています。polylines()については線や図を描く処理ですでに扱いました。

【Python】OpenCVで線や図を描く - rectangle, circle, line, putText, polylines
PythonにOpenCVをインポートして画像に線や図を描画する方法学びます。ここでは矩形のrectangle()、円のcircle()、直線のline()、テキストのputText()、 多角形のpolylines()を扱います。

上との違いはこの部分のみです。

このPythonスクリプトを実行するとMeanShiftで行ったものとは違って、顔を傾けたり、カメラに近づいたり遠ざかったりすると、顔を検出した赤い枠が顔を傾けた方向に合わせてひし形になったり、近寄ると大きくなったり、遠ざかると小さくなって顔をトラッキングすることができます。ただ、ちょっとズレが微妙なトラッキングかもしれません。

スポンサーリンク

カメラの起動時間を考慮したコードの修正

ここまでの処理において、カメラの起動時間の関係について、先ほど次のようなことを述べました。

このコードのwhile文の中の冒頭のface_rectからif文の手前のterm_criteまでの部分は、取り出して外に出し、face_cascadeの下に配置してもいいと思います。私の環境ではカメラの起動に時間がかかって、顔を認知できずに初期の追跡ウインドウが設定できなかったので、こういうコードにしてみました。

このカメラの起動時間を考慮して、ここで触れた部分をwhile文の外に出したコードを用意してみました。

MeanShiftアルゴリズムを使ったコード

先ほどのMeanShiftのコードを書き換えると次のようになります。

cv2.VideoCapture(0)でカメラを起動した時に、time.sleep(1)で一時中断してから、1フレーム目の画像を取り込んで、顔の検出をさせています。カメラの起動が早い環境では、このtime.sleep(1)の部分が無くても処理できるはずです。

CamShiftアルゴリズムを使ったコード

同様にCamshiftのコードを書き換えて見ます。

全く同様の考え方での書き換えです。本来ならimport文は一番上に書くべきですが、わかりやすく、time.sleep()を入れてる位置に書いています。

スポンサーリンク

最後に

OpenCVを使ったPythonでの画像処理について、ここでは画像中にある物体を発見・追跡するためのMeanShift、CamShiftアルゴリズムをみてきました。

MeanShiftアルゴリズムは、画像中に点の分布などがあるときに、そこへ規定のウィンドウを移動させて画素の分布密度や画素数が最大になる領域に合わせていくことでトラッキングの処理を行いました。

CamShiftアルゴリズムは、MeanShiftアルゴリズムで使う追跡ウインドウが常に同じサイズなので、追跡対象の傾きや遠近による見え方の大きさの違いなどで不具合が出るので、ウィンドウのサイズを追跡物体に合わせて調節する処理を行いました。

自宅学習はオンラインプログラミングスクールを活用!

自宅学習にはオンラインプログラミングスクールがおすすめ!

オンラインプログラミングスクールは独学でプログラミングを学習する時のデメリットを解消する仕組みが備わっています。

気になるところは…

学習がオンラインで完結するのはもちろんですが、独学ではできない質問サポートがあるかどうか。わからないことを現役のエンジニアが質問に答えてくれるといいですよね。

受講者個人に担当のメンターがつき、マンツーマンで学習の相談に乗ってくれることも必要で、ITエンジニアの世界についても伺えたりもすると幅が広がります。

オンライン面談だけでなく、チャット機能を使って気軽に質問を投げかけることができることも大切です。

また、オリジナルプロダクトの開発とサポートがコースの中に組み込まれていて、独学ではなかなか難しい実践的なスキルの習得にもつなげたい。

プログラミングをマスターした後の実際の仕事につながる転職サポートでがあると、ITエンジニアの世界に飛び込むのに不安が解消されます。

そんな豊富なメニューが揃っているおすすめのオンラインプログラミングスクールがこちらにあります。

おすすめのオンラインプログラミングスクールはこちら

TechAcademyはおすすめのオンラインプログラミングスクール!

オンラインのプログラミングスクールでは、テックアカデミーの充実度が目を見張ります。

オンラインで受講が完結するので、自宅学習でプログラミングをマスターしたい人にはテックアカデミーがおすすめです。

メンター制度も現役のプロが対応してくれます。大学生などが対応しているスクールに比べて本気度と専門性が違います。メンター制度の無いスクールもありますし、担当では無いメンターが対応するスクールもあったりするので、相談の質が違いますね。

チャットサポートもあるので、それが無いスクールに比べて相談の気軽さの違いがあります。

プロダクト開発のサポートで実践力が養われるだけでなく、どの講座を利用しても転職サポートが受けられるのはありがたい。

用意されているコースも、初心者向けのプログラミングコースから、Python、Java、PHP、iPhoneアプリ、AndroidといったITエンジニアのベースとなる主要な言語だけでなく、AI、データサイエンス、ブロックチェーン、webアプリケーションと行った実践的なコースまで用意しています。

他にも、webデザインやUI/UXデザイン、動画編集、webディレクションやwebマーケティングといったプログラミング以外での役立つコースまであります。

このようなたくさんの選択肢から自分にあったコースを選ぶことがでるのがテックアカデミーです。

コースの期間も短期間でマスターしたり、長期の受講でじっくり取り組むコースを選ぶこともできます。

複数講座のセットコースを利用することで大幅な割引が受けらるので、お得に受講することもできます。

無料体験もありますので、プログラミング学習でオンラインスクールを考えている人はTechAcademyをぜひ利用してみてください。

テックアカデミーの公式サイトはこちら

Pythonの応用OpenCV
スポンサーリンク
CodeGraffitiをフォローする

とにかく進め!Pythonプログラミング入門 〜 コードグラフィティ
タイトルとURLをコピーしました