我在天花板上有一個魚眼攝像頭,我想在地板上找到一些點。我將參考系統(真實世界)的原點放在相機下方,我想知道每個物體的位置,以釐米爲單位。此圖爲本:圖像點(像素)到現實世界座標(米)
首先,我也做了相機校準和我已經獲得的下一個結果與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釐米
點的其餘部分也顯示錯誤太大了......我用更多的積分,但結果並不完善。我不知道我錯了哪裏,有誰能幫助我?
在此先感謝。
有可能校準沒有問題,而且你有效地將圖像無畸變了兩次(請參閱我的答案以獲得解釋)。 – rob3c