2017-05-22 17 views
3
  • のOpenCV => 3.2
  • オペレーティングシステム/プラットフォーム=> Windowsの64ビット
  • コンパイラ=> Visual Studioの2015

と連携現在、車両の検出と追跡、車両周囲の立方体の推定と最適化を含むプロジェクトに取り組んでいます。そのためには、車両の検出と追跡を行い、車両の境界ボックスのエッジのイメージポイントの3次元ワールド座標を見つけて、直方体のエッジとプロジェクトのワールド座標を推定する必要がありますそれを表示するために画像に戻します。トランス2D画像は、3Dの世界に座標私はz = 0の

私はコンピュータビジョンとOpenCVの新人ですが、私の知るところでは、画像上に4点が必要で、4点のワールド座標を知り、OpenCVでsolvePNPを使用して回転と平行移動を取得する必要がありますベクトル(私はすでにカメラ行列と歪み係数を持っています)。次に、ロドリゲスを使用して回転ベクトルを回転行列に変換し、それを平行移動ベクトルと連結して外因性行列を得、次にカメラ行列を乗算して投影行列を得る必要があります。私のz座標はゼロであるので、2D画像ポイントを3Dワールドポイントに変換するためのホモグラフィ行列を与える投影行列から3番目の列を離す必要があります。今、私は、ホモグラフィ行列の逆数を見て、3D世界点と2D画像点の間のホモグラフィを私に与えます。その後、イメージ点[x、y、1] tに逆ホモグラフィ行列を掛けて[wX、wY、w] tを得、ベクトル全体をスカラwで除算して[X、Y、1]私に世界の座標のXとYの値を与えます。

私のコードは次のようになります。

#include "opencv2/opencv.hpp" 
#include <stdio.h> 
#include <iostream> 
#include <sstream> 
#include <math.h> 
#include <conio.h> 

using namespace cv; 
using namespace std; 

Mat cameraMatrix, distCoeffs, rotationVector, rotationMatrix, 
translationVector,extrinsicMatrix, projectionMatrix, homographyMatrix, 
inverseHomographyMatrix; 


Point point; 
vector<Point2d> image_points; 
vector<Point3d> world_points; 

int main() 
{ 
FileStorage fs1("intrinsics.yml", FileStorage::READ); 

fs1["camera_matrix"] >> cameraMatrix; 
cout << "Camera Matrix: " << cameraMatrix << endl << endl; 

fs1["distortion_coefficients"] >> distCoeffs; 
cout << "Distortion Coefficients: " << distCoeffs << endl << endl; 



image_points.push_back(Point2d(275, 204)); 
image_points.push_back(Point2d(331, 204)); 
image_points.push_back(Point2d(331, 308)); 
image_points.push_back(Point2d(275, 308)); 

cout << "Image Points: " << image_points << endl << endl; 

world_points.push_back(Point3d(0.0, 0.0, 0.0)); 
world_points.push_back(Point3d(1.775, 0.0, 0.0)); 
world_points.push_back(Point3d(1.775, 4.620, 0.0)); 
world_points.push_back(Point3d(0.0, 4.620, 0.0)); 

cout << "World Points: " << world_points << endl << endl; 

solvePnP(world_points, image_points, cameraMatrix, distCoeffs, rotationVector, translationVector); 
cout << "Rotation Vector: " << endl << rotationVector << endl << endl; 
cout << "Translation Vector: " << endl << translationVector << endl << endl; 

Rodrigues(rotationVector, rotationMatrix); 
cout << "Rotation Matrix: " << endl << rotationMatrix << endl << endl; 

hconcat(rotationMatrix, translationVector, extrinsicMatrix); 
cout << "Extrinsic Matrix: " << endl << extrinsicMatrix << endl << endl; 

projectionMatrix = cameraMatrix * extrinsicMatrix; 
cout << "Projection Matrix: " << endl << projectionMatrix << endl << endl; 

double p11 = projectionMatrix.at<double>(0, 0), 
    p12 = projectionMatrix.at<double>(0, 1), 
    p14 = projectionMatrix.at<double>(0, 3), 
    p21 = projectionMatrix.at<double>(1, 0), 
    p22 = projectionMatrix.at<double>(1, 1), 
    p24 = projectionMatrix.at<double>(1, 3), 
    p31 = projectionMatrix.at<double>(2, 0), 
    p32 = projectionMatrix.at<double>(2, 1), 
    p34 = projectionMatrix.at<double>(2, 3); 


homographyMatrix = (Mat_<double>(3, 3) << p11, p12, p14, p21, p22, p24, p31, p32, p34); 
cout << "Homography Matrix: " << endl << homographyMatrix << endl << endl; 

inverseHomographyMatrix = homographyMatrix.inv(); 
cout << "Inverse Homography Matrix: " << endl << inverseHomographyMatrix << endl << endl; 

Mat point2D = (Mat_<double>(3, 1) << image_points[0].x, image_points[0].y, 1); 
cout << "First Image Point" << point2D << endl << endl; 

Mat point3Dw = inverseHomographyMatrix*point2D; 
cout << "Point 3D-W : " << point3Dw << endl << endl; 

double w = point3Dw.at<double>(2, 0); 
cout << "W: " << w << endl << endl; 

Mat matPoint3D; 
divide(w, point3Dw, matPoint3D); 

cout << "Point 3D: " << matPoint3D << endl << endl; 

_getch(); 
return 0; 

私は4つの既知の世界ポイントの画像座標を持って、簡略化のためにそれをハードコーディングされています。 image_pointsには4点の画像座標が含まれ、world_pointsには4点のワールド座標が含まれています。私は、ワールド軸の原点(0、0、0)として第1ワールドポイントを考慮し、他の4つのポイントの座標を計算する既知の距離を使用しています。逆ホモグラフィ行列を計算した後、ワールド座標(0、0、0)に関連する[image_points [0] .x、image_points [0] .y、1] tを乗算しました。次に、結果を第3の成分wで除算して[X、Y、1]を得る。しかし、XとYの値をプリントアウトした後、それぞれ0,0ではないことが分かります。何が間違っているの?

私のコードの出力は次のようである:

Camera Matrix: [517.0036881709533, 0, 320; 
0, 517.0036881709533, 212; 
0, 0, 1] 

Distortion Coefficients: [0.1128663679798094; 
-1.487790079922432; 
0; 
0; 
2.300571896761067] 

Image Points: [275, 204; 
331, 204; 
331, 308; 
275, 308] 

World Points: [0, 0, 0; 
1.775, 0, 0; 
1.775, 4.62, 0; 
0, 4.62, 0] 

Rotation Vector: 
[0.661476468596541; 
-0.02794460022559267; 
0.01206996342819649] 

Translation Vector: 
[-1.394495345140898; 
-0.2454153722672731; 
15.47126945512652] 

Rotation Matrix: 
[0.9995533907649279, -0.02011656447351923, -0.02209848058392758; 
0.002297501163799448, 0.7890323093017149, -0.6143474069013439; 
0.02979497438726573, 0.6140222623910194, 0.7887261380159] 

Extrinsic Matrix: 
[0.9995533907649279, -0.02011656447351923, -0.02209848058392758, 
-1.394495345140898; 
0.002297501163799448, 0.7890323093017149, -0.6143474069013439, 
-0.2454153722672731; 
0.02979497438726573, 0.6140222623910194, 0.7887261380159, 
15.47126945512652] 

Projection Matrix: 
[526.3071813531748, 186.086785938988, 240.9673682002232, 4229.846989065414; 
7.504351145361707, 538.1053336219271, -150.4099339268854, 3153.028471890794; 
0.02979497438726573, 0.6140222623910194, 0.7887261380159, 15.47126945512652] 

Homography Matrix: 
[526.3071813531748, 186.086785938988, 4229.846989065414; 
7.504351145361707, 538.1053336219271, 3153.028471890794; 
0.02979497438726573, 0.6140222623910194, 15.47126945512652] 

Inverse Homography Matrix: 
[0.001930136511648154, -8.512427241879318e-05, -0.5103513244724983; 
-6.693679705844383e-06, 0.00242178892313387, -0.4917279870709287 
-3.451449134581896e-06, -9.595179260534558e-05, 0.08513443835773901] 

First Image Point[275; 
204; 
1] 

Point 3D-W : [0.003070864657310213; 
0.0004761913292736786; 
0.06461112415423849] 

W: 0.0646111 
Point 3D: [21.04004290792539; 
135.683117651025; 
1] 
+0

3D点が平面上にあることがわかっている場合は、光線と平面の交差点を使用してカメラフレーム内の3D点を計算できます。次に、カメラポーズを使用して、カメラフレーム内の3Dポイントをオブジェクトフレームに変換します。 – Catree

答えて

1

あなたの推論が健全であるが、あなたは...最後の部門でいくつかのミスを作っているか、私は何かが足りないのですか? Wの分割前

あなたの結果は次のとおりです。

Point 3D-W : 
[0.003070864657310213; 
0.0004761913292736786; 
0.06461112415423849] 

今、私たちは、あなたの質問で説明したように、W(配列の3番目の要素)によって、すべての座標を分割することによって、これを正規化する必要があります。そう:[0,0]にいまいましい近い

Point 3D-W Normalized = 
[0.047528420183179314; 
0.007370113668614144; 
1.0] 

:その結果

Point 3D-W Normalized = 
[0.003070864657310213/0.06461112415423849; 
0.0004761913292736786/0.06461112415423849; 
0.06461112415423849/0.06461112415423849] 

関連する問題