2016-06-08 237 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以避免双失真。

相关问题