摄像头标定
void calRealPoint(std::vector<std::vector<cv::Point3f>>& obj, int boardwidth, int boardheight, int imgNumber, int squaresize)
{
// Mat imgpoint(boardheight, boardwidth, CV_32FC3,Scalar(0,0,0));
std::vector<cv::Point3f> imgpoint;
for (int rowIndex = 0; rowIndex < boardheight; rowIndex++)
{
for (int colIndex = 0; colIndex < boardwidth; colIndex++)
{
// imgpoint.at<Vec3f>(rowIndex, colIndex) = Vec3f(rowIndex * squaresize, colIndex*squaresize, 0);
imgpoint.push_back(cv::Point3f(rowIndex * squaresize, colIndex * squaresize, 0));
}
}
for (int imgIndex = 0; imgIndex < imgNumber; imgIndex++)
{
obj.push_back(imgpoint);
}
}
void Camera::initCameraparam()
{
intrinsic.create(3,3, CV_64FC1);
distortion_coeff.create(5,1,CV_64FC1);
{
// Mat imgpoint(boardheight, boardwidth, CV_32FC3,Scalar(0,0,0));
std::vector<cv::Point3f> imgpoint;
for (int rowIndex = 0; rowIndex < boardheight; rowIndex++)
{
for (int colIndex = 0; colIndex < boardwidth; colIndex++)
{
// imgpoint.at<Vec3f>(rowIndex, colIndex) = Vec3f(rowIndex * squaresize, colIndex*squaresize, 0);
imgpoint.push_back(cv::Point3f(rowIndex * squaresize, colIndex * squaresize, 0));
}
}
for (int imgIndex = 0; imgIndex < imgNumber; imgIndex++)
{
obj.push_back(imgpoint);
}
}
void Camera::initCameraparam()
{
intrinsic.create(3,3, CV_64FC1);
distortion_coeff.create(5,1,CV_64FC1);
intrinsic.at<double>(0, 0) = 256.8093262; //fx
intrinsic.at<double>(0, 2) = 160.2826538; //cx
intrinsic.at<double>(1, 1) = 254.7511139; //fy
intrinsic.at<double>(1, 2) = 127.6264572; //cy
intrinsic.at<double>(0, 2) = 160.2826538; //cx
intrinsic.at<double>(1, 1) = 254.7511139; //fy
intrinsic.at<double>(1, 2) = 127.6264572; //cy
intrinsic.at<double>(0, 1) = 0;
intrinsic.at<double>(1, 0) = 0;
intrinsic.at<double>(2, 0) = 0;
intrinsic.at<double>(2, 1) = 0;
intrinsic.at<double>(2, 2) = 1;
intrinsic.at<double>(1, 0) = 0;
intrinsic.at<double>(2, 0) = 0;
intrinsic.at<double>(2, 1) = 0;
intrinsic.at<double>(2, 2) = 1;
/*
k1 k2 p1 p2 p3
*/
distortion_coeff.at<double>(0, 0) = -0.193740; //k1
distortion_coeff.at<double>(1, 0) = -0.378588; //k2
distortion_coeff.at<double>(2, 0) = 0.028980; //p1
distortion_coeff.at<double>(3, 0) = 0.008136; //p2
distortion_coeff.at<double>(4, 0) = 0; //p3
}
void Camera::outputCameraParam()
{
std::cout << "fx :" << intrinsic.at<double>(0, 0) << std::endl << "fy :" << intrinsic.at<double>(1, 1) << std::endl;
std::cout << "cx :" << intrinsic.at<double>(0, 2) << std::endl << "cy :" << intrinsic.at<double>(1, 2) << std::endl;
k1 k2 p1 p2 p3
*/
distortion_coeff.at<double>(0, 0) = -0.193740; //k1
distortion_coeff.at<double>(1, 0) = -0.378588; //k2
distortion_coeff.at<double>(2, 0) = 0.028980; //p1
distortion_coeff.at<double>(3, 0) = 0.008136; //p2
distortion_coeff.at<double>(4, 0) = 0; //p3
}
void Camera::outputCameraParam()
{
std::cout << "fx :" << intrinsic.at<double>(0, 0) << std::endl << "fy :" << intrinsic.at<double>(1, 1) << std::endl;
std::cout << "cx :" << intrinsic.at<double>(0, 2) << std::endl << "cy :" << intrinsic.at<double>(1, 2) << std::endl;
std::cout << "k1 :" << distortion_coeff.at<double>(0, 0) << std::endl;
std::cout << "k2 :" << distortion_coeff.at<double>(1, 0) << std::endl;
std::cout << "p1 :" << distortion_coeff.at<double>(2, 0) << std::endl;
std::cout << "p2 :" << distortion_coeff.at<double>(3, 0) << std::endl;
std::cout << "p3 :" << distortion_coeff.at<double>(4, 0) << std::endl;
}
void Camera::CameraInit()
{
cv::Mat img;
int goodFeatNums = 0;
cv::namedWindow("chessboard");
//std::cout << "Plaeas input" << std::endl;
//std::string
std::string filename, filedir;
int i = 0;
while (goodFeatNums < imageNums)
{
filedir = "E:\\Code_zoom\\OpenCVcode\\CV\\CV\\Camera_pic\\Lpic\\Lpic_";
filename = filedir + std::to_string(i) + ".jpg";
i++;
rgbImage = cv::imread(filename, CV_LOAD_IMAGE_COLOR);
cv::cvtColor(rgbImage,grayImage,CV_RGB2GRAY);
cv::imshow("Reload Image",grayImage);
bool isFind = findChessboardCorners(rgbImage, boardSize, corner, 0);
if (isFind == true) //所有角点都被找到 说明这幅图像是可行的
{
/*
Size(5,5) 搜索窗口的一半大小
Size(-1,-1) 死区的一半尺寸
TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 20, 0.1)迭代终止条件
*/
cornerSubPix(grayImage, corner, cv::Size(5, 5), cv::Size(-1, -1), cv::TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 20, 0.1));
drawChessboardCorners(rgbImage, boardSize, corner, isFind);
cv::imshow("chessboard", rgbImage);
corners.push_back(corner);
goodFeatNums++;
std::cout << "The image is good" << std::endl;
}
else
{
std::cout << "The image is bad feature" << std::endl;
}
if (cv::waitKey(10) == 'q')
break;
}
std::cout << "k2 :" << distortion_coeff.at<double>(1, 0) << std::endl;
std::cout << "p1 :" << distortion_coeff.at<double>(2, 0) << std::endl;
std::cout << "p2 :" << distortion_coeff.at<double>(3, 0) << std::endl;
std::cout << "p3 :" << distortion_coeff.at<double>(4, 0) << std::endl;
}
void Camera::CameraInit()
{
cv::Mat img;
int goodFeatNums = 0;
cv::namedWindow("chessboard");
//std::cout << "Plaeas input" << std::endl;
//std::string
std::string filename, filedir;
int i = 0;
while (goodFeatNums < imageNums)
{
filedir = "E:\\Code_zoom\\OpenCVcode\\CV\\CV\\Camera_pic\\Lpic\\Lpic_";
filename = filedir + std::to_string(i) + ".jpg";
i++;
rgbImage = cv::imread(filename, CV_LOAD_IMAGE_COLOR);
cv::cvtColor(rgbImage,grayImage,CV_RGB2GRAY);
cv::imshow("Reload Image",grayImage);
bool isFind = findChessboardCorners(rgbImage, boardSize, corner, 0);
if (isFind == true) //所有角点都被找到 说明这幅图像是可行的
{
/*
Size(5,5) 搜索窗口的一半大小
Size(-1,-1) 死区的一半尺寸
TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 20, 0.1)迭代终止条件
*/
cornerSubPix(grayImage, corner, cv::Size(5, 5), cv::Size(-1, -1), cv::TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 20, 0.1));
drawChessboardCorners(rgbImage, boardSize, corner, isFind);
cv::imshow("chessboard", rgbImage);
corners.push_back(corner);
goodFeatNums++;
std::cout << "The image is good" << std::endl;
}
else
{
std::cout << "The image is bad feature" << std::endl;
}
if (cv::waitKey(10) == 'q')
break;
}
initCameraparam();
print("initCamera successed");
calRealPoint(objRealPoint, boardWidth, boardHeight, imageNums, squareSize);//计算世界坐标值
print("cal real successed");
cv::calibrateCamera(objRealPoint, corners, cv::Size(imageWidth, imageHeight), intrinsic, distortion_coeff, rvecs, tvecs, 0);
//相机标定计算标定矩阵和偏移矩阵
print("calibrateCamera successed");
outputCameraParam();//打印矩阵值
print("output successed");
cv::Mat uImage;
cv::undistort(rgbImage,uImage,intrinsic,distortion_coeff);
//rgbImage 转换成一个无偏移的图像uImage,intriinsic是内参数,distortion_coeff 为相机外参数(畸变)
cv::imshow("undistort image",uImage);
cv::imshow("initial image",rgbImage);
print("imshow OK");
cv::waitKey(0);
}
print("initCamera successed");
calRealPoint(objRealPoint, boardWidth, boardHeight, imageNums, squareSize);//计算世界坐标值
print("cal real successed");
cv::calibrateCamera(objRealPoint, corners, cv::Size(imageWidth, imageHeight), intrinsic, distortion_coeff, rvecs, tvecs, 0);
//相机标定计算标定矩阵和偏移矩阵
print("calibrateCamera successed");
outputCameraParam();//打印矩阵值
print("output successed");
cv::Mat uImage;
cv::undistort(rgbImage,uImage,intrinsic,distortion_coeff);
//rgbImage 转换成一个无偏移的图像uImage,intriinsic是内参数,distortion_coeff 为相机外参数(畸变)
cv::imshow("undistort image",uImage);
cv::imshow("initial image",rgbImage);
print("imshow OK");
cv::waitKey(0);
}
参考地址:https://blog.csdn.net/xiaoxuebajie/article/details/78213573