2017-12-05 91 views
1

私は、ビデオストリームのカメラポーズを追跡するためにPythonでOpenCVを使用しようとしています。私はテスト環境として2つの画像間の姿勢を決定するコードのサンプルを持っています。OpenCVとPythonによるカメラ姿勢推定

ここで全体の流れはこれです:画像内

  1. 読むとサイズを変更/グレーに変換します。

  2. 両方の画像からcv2 goodfeaturestotrack機能を抽出します。

  3. cv2 calcOpticalFlowPyrLKを使用して一致するポイントを検索します。
  4. すべてのポイントが0に設定されている場合、p1ポイント(開始イメージ)をzで(x、y、z)に変換します。
  5. 回転と平行移動ベクトルを取得するためにcv2 PnPRansacを解決します。
  6. 角度をラジアンから度に変換します。私は回転と平行移動ベクトルがゼロに非常に近いことを期待していたこのサンプル計算を実行するために、まったく同じ画像を使用していたという事実を考えると
def function(mtx,dist): 

      #feature dictionary 
      feature_params = dict(maxCorners = 1000, 
           qualityLevel = 0.3, 
           minDistance = 7, 
           blockSize = 7) 
      lk_params = dict(winSize = (15,15), 
          maxLevel = 2, 
          criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03)) 


      #image 1 
      image_1=cv2.imread("/Users/user/Desktop/Test_images/Test_image.jpg") 
      image_1=cv2.resize(image_1,(640,480)) 
      gray_1=cv2.cvtColor(image_1,cv2.COLOR_BGR2GRAY) 
      p1=cv2.goodFeaturesToTrack(gray, mask = None, **feature_params) 

      #image read in 
      image_2=cv2.imread("/Users/user/Desktop/Test_images/Test_image.jpg") 
      image_2=cv2.resize(image_2,(640,480)) 
      gray_2 = cv2.cvtColor(image_2,cv2.COLOR_BGR2GRAY) 
      p2, st, err = cv2.calcOpticalFlowPyrLK(gray_1, gray_2, p1, None, **lk_params) 

      #convert the old points to 3d 
      zeros=np.zeros([len(p1),1],dtype=np.float) 
      old_3d=np.dstack((p1, zeros)) 

      #get rotational and translation vector 
      blank,rvecs, tvecs, inliers = cv2.solvePnPRansac(old_3d, p2, mtx, dist) 

      rad=180/math.pi 

      roll=rvecs[0]*rad 
      pitch=rvecs[1]*rad 
      yaw=rvecs[2]*rad 

      print(roll) 
      print(pitch) 
      print(yaw) 
      print(tvecs) 

     function(mtx,dist) 



    rvec (roll, pitch and yaw) 
    [ 0.35305807] 
    [ 2.95965708] 
    [ 0.10954427] 

    tvec (x,y,x ???) 
    [[ -668.42397254] 
    [ -387.32180857] 
    [ 1180.94652875]] 

。しかし、彼らはかなり高いです、以下のサンプル出力を見てください。さらに、既知の翻訳を用いた異なる画像では、ベクトルは非常に間違っている。

手元の質問は私の方法の音ですか?私はこの問題に直面しましたか?ポイントに正しくマッチしましたか?このレベルの騒音は普通ですか、それとも何かできることはありますか?

+0

私には正しいと思われます。オブジェクトフレームで表現された3D点をカメラフレームで表現された3D点に変換することができる回転と平行移動である完全なカメラポーズを推定するには、対応する3D/2D点が必要です。 3Dポイントは、オブジェクトフレームで表現されたポイントでなければなりません。 2D点は、(推定された)カメラ姿勢および固有の+歪みパラメータに従って、現在の画像平面に投影された対応する3D点でなければならない。 – Catree

+0

さて、私はあなたが言っていることに従っていますが、どうすればいいですか?ワークフローはどのように見えますか? OpenCVの機能は何をしますか? – Jake3991

答えて

0

3D構造、つまりあなたがマッチしたポイントの3D座標がわからない場合、PnPは使用できません。

カメラの組み込み関数が分かっている場合は、(平面シーンの場合は)ホモグラフィまたは(一般シーンの場合は)必須マトリックスを推定し、それを分解してスケールを最大にすることができます。このようにして見つけたポーズを絞り込むためにバンドル調整を行うことができます。

これがワンショットプロジェクトの場合、独自のソリューションをコーディングするのではなく、Blenderのようなグラフィックス環境を使う方が速いかもしれません。 matchmoveのチュートリアルを参照してくださいhereまたはhere

関連する問題