2017-05-22 4 views
3
  • OpenCV => 3.2
  • Betriebssystem/Plattform-Koordinaten => Windows 64 Bit
  • Compiler => Visual Studio 2015

Ich bin Derzeit arbeite ich an meinem Projekt, bei dem es darum geht, Fahrzeuge zu erkennen und zu verfolgen und einen Quader um das Fahrzeug zu schätzen und zu optimieren. Dafür habe ich die Erkennung und Verfolgung von Fahrzeugen durchgeführt und muss die 3D-Weltkoordinaten der Bildpunkte der Kanten der Begrenzungsboxen der Fahrzeuge finden und dann die Weltkoordinaten der Kanten des Quaders und des Projekts schätzen es zurück zum Bild, um es anzuzeigen.Transforming 2D-Bildkoordinaten in 3D-Welt mit z = 0

Also ich bin neu in Computer Vision und OpenCV, aber in meinem Wissen, ich brauche nur 4 Punkte auf dem Bild und müssen die Welt Koordinaten dieser 4 Punkte und verwenden Sie solvePNP in OpenCV, um die Rotation und Übersetzung zu erhalten Vektoren (ich habe bereits die Kameramatrix und Verzerrungskoeffizienten). Dann muss ich Rodrigues verwenden, um den Rotationsvektor in eine Rotationsmatrix zu transformieren und sie dann mit dem Translationsvektor zu verketten, um meine extrinsische Matrix zu erhalten, und dann die extrinsische Matrix mit der Kameramatrix multiplizieren, um meine Projektionsmatrix zu erhalten. Da meine z-Koordinate Null ist, muss ich die dritte Spalte aus der Projektionsmatrix entfernen, die die Homographie-Matrix zum Umwandeln der 2D-Bildpunkte in 3D-Weltpunkte ergibt. Jetzt finde ich das Inverse der Homographiematrix, die mir die Homographie zwischen den 3D-Weltpunkten zu 2D-Bildpunkten gibt. Danach multipliziere ich die Bildpunkte [x, y, 1] t mit der inversen homographischen Matrix, um [wX, wY, w] t zu erhalten, und dividiere den gesamten Vektor durch den Skalar w, um [X, Y, 1] zu erhalten gibt mir die X- und Y-Werte der Weltkoordinaten.

Mein Code sieht wie folgt aus:

#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; 

ich die Bildkoordinaten der vier bekannten Welt Punkte haben und hartcodiert es zur Vereinfachung. image_points enthalten die Bildkoordinaten der vier Punkte und world_points enthalten die Weltkoordinaten der vier Punkte. Ich betrachte den ersten Weltpunkt als den Ursprung (0, 0, 0) in der Weltachse und benutze bekannte Entfernung, indem ich die Koordinaten der anderen vier Punkte berechne. Nach der Berechnung der inversen Homographiematrix multipliziere ich sie nun mit [image_points [0] .x, image_points [0]. Y, 1] t, was mit der Weltkoordinate (0, 0, 0) zusammenhängt. Dann teile ich das Ergebnis durch die dritte Komponente w, um [X, Y, 1] zu erhalten. Aber nach dem Ausdrucken der Werte von X und Y stellt sich heraus, dass sie nicht 0, 0 sind. Was mache ich falsch?

Der Ausgang meines Codes ist wie folgt:

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

Wenn Sie wissen, dass der 3D-Punkt auf einer Ebene liegt, können Sie den 3D-Punkt im Kamerarahmen mithilfe des Schnittpunkts zwischen einem Lichtstrahl und einer Ebene berechnen. Verwenden Sie dann die Kamerapose, um den 3D-Punkt im Kamerarahmen in den Objektrahmen zu transformieren. – Catree

Antwort

1

Ihre Argumentation ist solide, aber Sie werden einige Fehler in der letzten Abteilung machen .. oder bin ich etwas fehlt?

Ihr Ergebnis vor W Division ist:

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

Jetzt müssen wir dies normalisieren, indem sie alle Koordinaten von W Teilen (das dritte Element des Arrays), wie Sie in Ihrer Frage beschrieben. so:

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

was zur Folge hat:

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

die zu verdammt nah ist [0,0].

Verwandte Themen