通用的相机模型(薄镜公式):
有一种简化模型成为针孔照相机模型,根据相似三角形定理,基本投影方程为:
*相机校准
相机校准就是设置相机各种参数的过程,就是用相机拍摄特定的图案并分析得到的图像,然后再优化的过程中确定最佳的参数值。
OpenCV推荐使用国际象棋棋盘的图案生成用于校准的三维场景的集合,并且由于图案视平面的,因此我们可以假设棋盘位于Z=0且X和Y的坐标轴与网格对齐的位置。
原图:
使用cv::findChessboardCorners()和cv::drawChessboardCorners检测和绘制角点:
连接角点的萧条的次序,就是角点在向量中存储的次序。
相机校准原理:
代码:
CameraCalibrator类:
class CameraCalibrator
{
private:
//世界坐标系中的点
std::vector<std::vector<cv::Point3f>> objectPoints;
std::vector<std::vector<cv::Point2f>> imagePoints;
//输出矩阵
cv::Mat cameraMatrix;
cv::Mat distCoeffs;
//指定校准方式的标志
int flag;
cv::Mat map1, map2;
bool mustInitUndistort;
public:
int addChessboardPoints(const std::vector<std::string>& filelist, cv::Size& boardSize);
void addPoints(std::vector<cv::Point2f>& imageCorners, std::vector<cv::Point3f>& objectCorners);
double calibrate(cv::Size& imageSize);
cv::Mat remap(const cv::Mat& image)
{
cv::Mat undistorted;
if (mustInitUndistort)
{
cv::initUndistortRectifyMap(
cameraMatrix,//计算得到的相机矩阵
distCoeffs,//计算得到的畸变矩阵
cv::Mat(),//可选矫正项
cv::Mat(),//生成无畸变的相机矩阵
image.size(),//无畸变图像尺寸
CV_32FC1,//输出图片类型
map1, map2);//x和y映射功能
mustInitUndistort = false;
}
cv::remap(image, undistorted, map1, map2, cv::INTER_LINEAR);
}
};
int CameraCalibrator::addChessboardPoints(const std::vector<std::string>