文章来源:https://www.toymoban.com/news/detail-622240.html
void stereo_Calibrate::calibrateStereo()
{
int current = 1;
QDir dirL(imgsrcDirPathl+"/left");
QDir dirR(imgsrcDirPathl+"/right");
QStringList imagelistL;
QStringList imagelistR;
imagelistL<<"*.jpg"<<"*.bmp"<<"*.png";
imagelistR<<"*.jpg"<<"*.bmp"<<"*.png";
dirL.setNameFilters(imagelistL);
dirR.setNameFilters(imagelistR);
int imagecuont =dirL.count();
framenumber=dirL.count();
std::string dirpathL =imgsrcDirPathl.toStdString();
std::string dirpathR =imgsrcDirPathl.toStdString();
int success_n=0;
for(int i=0;i<imagecuont;i++)
{
std::string imagenameL =dirpathL+"/left/"+dirL[i].toStdString();
imageL = cv::imread(imagenameL);
cv::cvtColor(imageL,grayimageL,cv::ColorConversionCodes::COLOR_BGR2GRAY);
std::string imagenameR =dirpathR+"/right/"+dirR[i].toStdString();
imageR = cv::imread(imagenameR);
cv::cvtColor(imageR, grayimageR, cv::ColorConversionCodes::COLOR_BGR2GRAY);
bool foundL, foundR;
foundL = cv::findChessboardCorners(imageL,boardsize,cornerL);
foundR = cv::findChessboardCorners(imageR, boardsize, cornerR);
if (foundL == true && foundR == true)
{
cv::cornerSubPix(grayimageL,cornerL,cv::Size(11,11),cv::Size(-1,-1),cv::TermCriteria(cv::TermCriteria::MAX_ITER|cv::TermCriteria::EPS, 30, 1e-6));
cv::cornerSubPix(grayimageR, cornerR, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS, 30, 1e-6));
cv::drawChessboardCorners(imageL,boardsize,cornerL,foundL);
cv::drawChessboardCorners(imageR, boardsize, cornerR, foundR);
cv::Mat Tg;
cv::hconcat(imageL,imageR,Tg);
cv::imshow("F", Tg);
cv::moveWindow("F", 500, 100);
cv::waitKey();
imagepointL.push_back(cornerL);
imagepointR.push_back(cornerR);
success_n++;
std::cout << "The image " << current << " is good" << std::endl;
}
else
{
std::cout << "The image is bad please try again" << std::endl;
}
current++;
}
//===========================================================================================================================================单目标定矩阵写入
cv::Size square_size = cv::Size(cellSize_width, cellSize_height);
std::vector<std::vector<cv::Point3f>> object_pointsL; /* 保存标定板上角点的三维坐标 */
std::vector<cv::Mat> tvecsMatL; /* 每幅图像的旋转向量 */
std::vector<cv::Mat> rvecsMatL; /* 每幅图像的平移向量 */
std::vector<cv::Point3f> realPointL;
std::vector<std::vector<cv::Point3f>> object_pointsR; /* 保存标定板上角点的三维坐标 */
std::vector<cv::Mat> tvecsMatR; /* 每幅图像的旋转向量 */
std::vector<cv::Mat> rvecsMatR; /* 每幅图像的平移向量 */
std::vector<cv::Point3f> realPointR;
if(success_n!=0)
{
for(int i=0;i<success_n;i++)
{
for (int i = 0; i < boardhight; i++)
{
for (int j = 0; j < boardwidth; j++)
{
cv::Point3f tempPointL;
/* 假设标定板放在世界坐标系中z=0的平面上 */
tempPointL.x = i * square_size.width;
tempPointL.y = j * square_size.height;
tempPointL.z = 0;
realPointL.push_back(tempPointL);
}
}
object_pointsL.push_back(realPointL);
realPointL.clear();
}
for(int i=0;i<success_n;i++)
{
for (int i = 0; i < boardhight; i++)
{
for (int j = 0; j < boardwidth; j++)
{
cv::Point3f tempPointR;
/* 假设标定板放在世界坐标系中z=0的平面上 */
tempPointR.x = i * square_size.width;
tempPointR.y = j * square_size.height;
tempPointR.z = 0;
realPointR.push_back(tempPointR);
}
}
object_pointsR.push_back(realPointR);
realPointR.clear();
}
cv::calibrateCamera(object_pointsL, imagepointL, imageL.size(), L_cameraMatrix, L_distCoeffs, rvecsMatL, tvecsMatL,
cv::CALIB_FIX_K3, cv::TermCriteria(cv::TermCriteria::EPS+cv::TermCriteria::COUNT, ITER,accuracy));//---------------------------
cv::calibrateCamera(object_pointsR, imagepointR, imageR.size(), R_cameraMatrix, R_distCoeffs, rvecsMatR, tvecsMatR,
cv::CALIB_FIX_K3, cv::TermCriteria(cv::TermCriteria::EPS+cv::TermCriteria::COUNT, ITER,accuracy));//-----
//======================================================================================================================================单目标定矩阵写入
QMessageBox mesbox;
mesbox.setText("start stereoCalibrate!");
mesbox.exec();
worldpoint();
double err = cv::stereoCalibrate(objpoint, imagepointL, imagepointR, L_cameraMatrix, L_distCoeffs, R_cameraMatrix, R_distCoeffs, imagesize, R, T, E, F,
cv::CALIB_USE_INTRINSIC_GUESS, cv::TermCriteria(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 30, 1e-6));
qDebug()<< "The err = " << err ;
cv::stereoRectify(L_cameraMatrix,L_distCoeffs, R_cameraMatrix,R_distCoeffs,imagesize,R,T,R1,R2,P1,P2,Q, cv::CALIB_ZERO_DISPARITY, -1, imagesize, &validROIL, &validROIR);
cv::initUndistortRectifyMap(L_cameraMatrix,L_distCoeffs,R1,P1,imagesize, CV_32FC1,maplx,maply);
cv::initUndistortRectifyMap(R_cameraMatrix,R_distCoeffs,R2,P2,imagesize,CV_32FC1,maprx,mapry);
outputparam();
}
else
{
QMessageBox mesbox;
mesbox.setText("calibrate faile!");
mesbox.exec();
}
}
以上就是软件的主要代码,相信大家都可以做出来了。加油!文章来源地址https://www.toymoban.com/news/detail-622240.html
到了这里,关于相机标定小工具(单目+双目)技术分享的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!