コンピュータビジョンと移動ロボット。 パート1-V-REP、Python、OpenCV





無人のレーシングカーの発売に関する出版物を読んだとき、そのようなことをするのは面白いと思いました。 もちろん、レーシングカーではなく、少なくともカメラを通して空間に向けられた移動ロボット-パターン認識。



ハックスペースでは、ロボットの作成はそれほど大きな問題ではありません。 しかし、誰もが必ずしも実際のハードウェアを試す機会があるわけではなく、仮想環境で問題を解決しようとするのは興味深いことでした。その後、ハードウェアを復活させます。



そのため、仮想シミュレーションから実際の移動ロボットでの実装まで、ロボットを宇宙に向ける最も単純なタスクを解決することについて、一連の記事のアイデアが生まれました。



パート1 仮想環境をセットアップし、PythonおよびOpenCVと統合して、仮想世界の画像を認識します。

パート2 仮想移動ロボットの作成、自律移動アルゴリズム(オブジェクト検索)

パート3 実際のロボットを作成し、そこにロジックを転送します。



この結果を達成したい-仮想ロボットを制御するpythonスクリプトが、実際のロボットを制御するpythonスクリプトと可能な限り同一になるように。



ロボットの頭脳はRaspberryPi2マイコンになります-pythonとOpenCVは問題なく動作します。 したがって、V-REP仮想ロボットシステムをPythonとOpenCVでドッキングする必要があります。 それはそれについてであり、最初の部分があります-この出版物。



ビデオ、何が起こった(緑のオブジェクトを検索)


上のウィンドウには3D仮想世界のビデオカメラからの直接画像があり、下のウィンドウには画像を受け取ってOpenCVに渡し、見つかったオブジェクトの周りにマーカーを描画するpythonスクリプトの結果があります。



移動ロボットのアーキテクチャを描きましょう。



移動ロボットのアーキテクチャ

実際のロボットは次のようになります(別のカメラを追加します)





建築的に:





ご覧のように、ロボットの「頭脳」は画像を受け取り、OpenCVを介して認識し、制御コマンドをホイールに送信します。 また、カメラ画像を3D画像に置き換え、仮想世界の3Dロボットの仮想車輪を制御して車輪を制御することで、論理を立てる立場になります。



仮想スタンドのこのようなアーキテクチャを取得します。





今日の最初の部分では、OpenCVを使用してパターン認識を実行し、見つかったオブジェクトの周囲にマーカーを表示する外部PythonスクリプトとV-REPをリンクする問題を解決する必要があります。



次のアーキテクチャが判明します。





V-REPをインストールする


無料のV-REPロボットモデリングシステムについて-ロシア語の出版物がいくつかありました。



したがって、インストールと最初のステップ-あなたはそれらを見ることができます。



シーン


V-REPがインストールされ動作していると考えています。 シーンを作成する必要があります。



シーンにカメラがあり、さまざまな3Dオブジェクトがある領域を確認します。この画像は、外部Pythonスクリプトにブロードキャストする必要があります。外部Pythonスクリプトは、OpenCVを呼び出してマーカーを認識および生成し、この画像をV-REPに返して制御する必要があります。



幸いなことに、V-REPに付属する例には同様の例が含まれていましたが、ROSを使用していました(現在のタスクには必要ありません)





このデモに基づいて、次のシーンが登場しました。



シーンscene.tttここからダウンロードできます



Python API


Pythonがインストールされていると信じています(2.7.6でテスト済み)



V-REPが起動すると、Python APIバンドルを提供するプラグインが自動的にロードされます。 Pythonスクリプトを介してAPIを使用するには、フォルダーに3つのファイルが必要です。



V-REPディレクトリからコピーできます(programming / remoteApiBindings / python / python、programming / remoteApiBindings / lib / lib /)。 その後、V-REPモジュールをインポートできます。

import vrep
      
      





APIに接続する最も単純なスクリプトは次のようになります。

 import vrep vrep.simxFinish(-1) # just in case, close all opened connections clientID = vrep.simxStart('127.0.0.1', 19997, True, True, 5000, 5) if clientID!=-1: print 'Connected to remote API server' while (vrep.simxGetConnectionId(clientID) != -1): print "some work" else: print "Failed to connect to remote API Server" vrep.simxFinish(clientID)
      
      







シーンにはv0とv1の2つのオブジェクトがあります。これは視覚センサーです。最初から画像を読み取り、2番目から結果を記録する必要があります。 したがって、Pythonスクリプトのコンテキストでこれらのオブジェクトを取得する必要があります。これはAPIコマンドvrep.simxGetObjectHandleを使用して行われます



  res, v0 = vrep.simxGetObjectHandle(clientID, 'v0', vrep.simx_opmode_oneshot_wait) res, v1 = vrep.simxGetObjectHandle(clientID, 'v1', vrep.simx_opmode_oneshot_wait)
      
      





APIを介して使用可能なすべての関数は、内部スクリプト(Lua)を介しても使用できます。唯一の違いは、simxではなく名前がsimであることです。つまり、この場合、Luaの関数呼び出しは「simGetObjectHandle」になります。



ビジョンセンサーから画像と記録を取得するには、 vrep.simxGetVisionSensorImagevrep.simxSetVisionSensorImageの 2つの関数があります。



また、Pythonコードでは、次のようになります(v0とv1は対応するオブジェクトです)。

  #     v0 err, resolution, image = vrep.simxGetVisionSensorImage(clientID, v0, 0, vrep.simx_opmode_buffer) #     v1 vrep.simxSetVisionSensorImage(clientID, v1, image, 0, vrep.simx_opmode_oneshot)
      
      





外部ソースからデータを受信するビジョンセンサーの唯一のことは、パラメーターに適切なフラグを設定することです。





イメージリレー


したがって、V-REP APIを介してビデオセンサーから画像を取得して中継するPythonスクリプトを作成できます。

simple_image_retranslate.py
 # simple_image_retranslate.py import vrep import time vrep.simxFinish(-1) clientID = vrep.simxStart('127.0.0.1', 19997, True, True, 5000, 5) if clientID!=-1: print 'Connected to remote API server' # get vision sensor objects res, v0 = vrep.simxGetObjectHandle(clientID, 'v0', vrep.simx_opmode_oneshot_wait) res, v1 = vrep.simxGetObjectHandle(clientID, 'v1', vrep.simx_opmode_oneshot_wait) err, resolution, image = vrep.simxGetVisionSensorImage(clientID, v0, 0, vrep.simx_opmode_streaming) time.sleep(1) while (vrep.simxGetConnectionId(clientID) != -1): err, resolution, image = vrep.simxGetVisionSensorImage(clientID, v0, 0, vrep.simx_opmode_buffer) if err == vrep.simx_return_ok: vrep.simxSetVisionSensorImage(clientID, v1, image, 0, vrep.simx_opmode_oneshot) elif err == vrep.simx_return_novalue_flag: print "no image yet" else: print err else: print "Failed to connect to remote API Server" vrep.simxFinish(clientID)
      
      





確認するには、シーンを開始し([再生]ボタンを押して)、その後、コマンドラインでファイルsimple_image_retranslate.pyを実行する必要があります。



結果は次のとおりです(v1-pythonスクリプトからの画像を表示します):





OK、基本的なワークピースがあります。パターン認識(コンピュータービジョン)を接続する必要があります。



コンピュータビジョン、OpenCV


彼が開発したオープンコンピュータビジョンシステム、 OpenCVについては誰もが聞いたと思います

ゲイリー・ブラドスキー


Gary BradskiはInnoprom 2014のハックスペースブースを訪問しました


まず、OpenCVをインストールする必要があります。LinuxMint(Ubuntu)にopencv2をインストールするのは非常に簡単です。

sudo apt-get install libopencv-dev python-opencv







その後、Pythonコードでライブラリを接続することが可能になりました。

 import cv2
      
      





ここで、最も単純な認識機能を実装する必要があります。 基本は、 この例を使用することで、写真の緑色のボールを検索します。



def track_green_object(image)関数が登場し、緑色のオブジェクトが見つかった場合はその座標を返します。



また、見つかったオブジェクトの周囲にマーカーでマークする必要があります。これには、基本的なOpenCV関数を使用して長方形を描画します: cv2.rectangle



コードスニペットは次のとおりです。

  1. 画像を取得(v0から)
  2. オブジェクト(緑色)を見つける
  3. マーカーを追加します(黄色の長方形)
  4. 画像を返します(v1)


次のようになります。

  # get image from vision sensor 'v0' err, resolution, image = vrep.simxGetVisionSensorImage(clientID, v0, 0, vrep.simx_opmode_buffer) if err == vrep.simx_return_ok: image_byte_array = array.array('b', image) image_buffer = I.frombuffer("RGB", (resolution[0],resolution[1]), image_byte_array, "raw", "RGB", 0, 1) img2 = numpy.asarray(image_buffer) # try to find something green ret = track_green_object(img2) # overlay rectangle marker if something is found by OpenCV if ret: cv2.rectangle(img2,(ret[0]-15,ret[1]-15), (ret[0]+15,ret[1]+15), (0xff,0xf4,0x0d), 1) # return image to sensor 'v1' img2 = img2.ravel() vrep.simxSetVisionSensorImage(clientID, v1, img2, 0, vrep.simx_opmode_oneshot)
      
      







結果



ここですべてを一緒に実行する必要があります。シーンを開始し、スクリプトを実行して、何が起こるかを確認します。





プロジェクトのソースコードはgithubにあります。



次のパートでは、V-REPでロボットを作成し、緑色のボールを検索するようにプログラムします。



All Articles