2016-06-08 105 views
2

我在天花板上有一個魚眼攝像頭,我想在地板上找到一些點。我將參考系統(真實世界)的原點放在相機下方,我想知道每個物體的位置,以釐米爲單位。此圖爲本:圖像點(像素)到現實世界座標(米)

Reference system - Real world

首先,我也做了相機校準和我已經獲得的下一個結果與1.11的RMS:

Undistorted image after calibration

作爲校準的結果我獲得了內部參數(相機矩陣),所以我使用cv :: solvePnP來獲得旋轉和平移向量。爲了應用這一點,我在未失真圖像中標記了一些點(以像素爲單位),並根據我的參考系統在真實世界中對它們進行了測量。

例如,原點是在1024x768的圖像的中心,所以:

  • 點0:ImagePoint(512,384)[像素] - > ObjectPoint(0,0)[釐米]

下一個代碼說明了這一:

std::vector<cv::Point2f> imagePointsPix; 
std::vector<cv::Point3f> objectPointsCm; 
imagePointsPix.push_back(cv::Point2f(512.,384.)); 
imagePointsPix.push_back(cv::Point2f(404.,512.));  
imagePointsPix.push_back(cv::Point2f(666.,211.)); 
imagePointsPix.push_back(cv::Point2f(519.,66.)); 

objectPointsCm.push_back(cv::Point3f(0., 0., 0.)); 
objectPointsCm.push_back(cv::Point3f(-80.,-132.,0.)); 
objectPointsCm.push_back(cv::Point3f(120.,188.,0.)); 
objectPointsCm.push_back(cv::Point3f(-40.,268.,0.)); 

cv::Mat rvec(1,3,cv::DataType<double>::type); 
cv::Mat tvec(1,3,cv::DataType<double>::type); 
cv::Mat rotationMatrix(3,3,cv::DataType<double>::type); 

cv::solvePnP(objectPointsCm, imagePointsPix, cameraMatrix, distCoeffs, rvec, tvec, 0, SOLVEPNP_ITERATIVE); 
cv::Rodrigues(rvec,rotationMatrix); 

現在我有相機矩陣,旋轉矩陣和翻譯中矢量,所以通過使用作爲this參考我能夠計算任何點,如果我有它的位置像素。這是代碼:

cv::Mat uvPoint = cv::Mat::ones(3,1,cv::DataType<double>::type); //u,v,1 
uvPoint.at<double>(0,0) = 512.; //img point for which we want its real coordinates 
uvPoint.at<double>(1,0) = 384.; 
cv::Mat tempMat, tempMat2; 
double s; 
tempMat = rotationMatrix.inv() * cameraMatrix.inv() * uvPoint; 
tempMat2 = rotationMatrix.inv() * tvec; 
s = 0 + tempMat2.at<double>(2,0); //before 0 it was 285, which represents the height Zconst 
s /= tempMat.at<double>(2,0); 
std::cout << "P = " << rotationMatrix.inv() * (s * cameraMatrix.inv() * uvPoint - tvec) << std::endl; 

我得到這個結果的相同點我用我獲得的參數:

  • 點0 - >(0.213,3.391)(它應該是( 0,0))ERROR:3.69釐米
  • 點1 - >(-68.28,-112.82)(它應該是(-80,-132))ERROR:17.49釐米
  • 點2 - - >(84.48,1 37.61)(它應該是(120,188))錯誤:49.62釐米

點的其餘部分也顯示錯誤太大了......我用更多的積分,但結果並不完善。我不知道我錯了哪裏,有誰能幫助我?

在此先感謝。

回答

0

最後我發現錯誤是由失真係數引起的,即我的校準。我將cameraMatrix設置爲Identity矩陣(eye(3)),並將distCoefficients設置爲NULL,這樣solvePNP就認爲我有一個完美的相機。使用這種方法我得到了一個更低的錯誤。我將不得不做出更好的校準。

+0

有可能校準沒有問題,而且你有效地將圖像無畸變了兩次(請參閱我的答案以獲得解釋)。 – rob3c

1

看起來你可能會從solvePNP的角度有效地扭曲你的形象兩次。這是由於失真係數與已經從未失真圖像得到的點對應一起傳遞。

嘗試將實際相機矩陣從您的校準傳遞到solvePNP而不是單位矩陣,但仍將失真係數傳遞爲NULL以避免雙失真。