2 #include <yarp/cv/Cv.h>
8 moduleName=rf.check(
"name", Value(
"stereoCalib"),
"module name (string)").asString().c_str();
9 robotName=rf.check(
"robotName",Value(
"icub"),
"module name (string)").asString().c_str();
11 this->inputLeftPortName =
"/"+moduleName;
12 this->inputLeftPortName +=rf.check(
"imgLeft",Value(
"/cam/left:i"),
"Input image port (string)").asString().c_str();
14 this->inputRightPortName =
"/"+moduleName;
15 this->inputRightPortName += rf.check(
"imgRight", Value(
"/cam/right:i"),
"Input image port (string)").asString().c_str();
17 this->outNameRight =
"/"+moduleName;
18 this->outNameRight += rf.check(
"outRight",Value(
"/cam/right:o"),
"Output image port (string)").asString().c_str();
20 this->outNameLeft =
"/"+moduleName;
21 this->outNameLeft +=rf.check(
"outLeft",Value(
"/cam/left:o"),
"Output image port (string)").asString().c_str();
23 Bottle stereoCalibOpts=rf.findGroup(
"STEREO_CALIBRATION_CONFIGURATION");
24 this->boardWidth= stereoCalibOpts.check(
"boardWidth", Value(8)).asInt32();
25 this->boardHeight= stereoCalibOpts.check(
"boardHeight", Value(6)).asInt32();
26 this->numOfPairs= stereoCalibOpts.check(
"numberOfPairs", Value(30)).asInt32();
27 this->squareSize= (float)stereoCalibOpts.check(
"boardSize", Value(0.09241)).asFloat64();
28 this->boardType= stereoCalibOpts.check(
"boardType", Value(
"CHESSBOARD")).asString();
29 this->commandPort=commPort;
30 this->imageDir=imageDir;
31 this->startCalibration=0;
32 this->currentPathDir=rf.getHomeContextPath().c_str();
33 int tmp=stereoCalibOpts.check(
"MonoCalib", Value(0)).asInt32();
34 this->stereo=
tmp?
false:
true;
35 this->camCalibFile=rf.getHomeContextPath().c_str();
36 this->standalone = rf.check(
"standalone");
37 string fileName=
"outputCalib.ini";
39 this->camCalibFile=this->camCalibFile+
"/"+fileName.c_str();
44 if (!imagePortInLeft.open(inputLeftPortName.c_str())) {
45 cout <<
": unable to open port " << inputLeftPortName << endl;
49 if (!imagePortInRight.open(inputRightPortName.c_str())) {
50 cout <<
": unable to open port " << inputRightPortName << endl;
54 if (!outPortLeft.open(outNameLeft.c_str())) {
55 cout <<
": unable to open port " << outNameLeft << endl;
59 if (!outPortRight.open(outNameRight.c_str())) {
60 cout <<
": unable to open port " << outNameRight << endl;
65 if(!stereo || standalone)
return true;
68 optHead.put(
"device",
"remote_controlboard");
69 optHead.put(
"remote",(
"/"+robotName+
"/head").c_str());
70 optHead.put(
"local",
"/"+moduleName+
"/client/head");
71 if (polyHead.open(optHead))
72 polyHead.view(posHead);
75 cout<<
"Devices not available"<<endl;
80 optTorso.put(
"device",
"remote_controlboard");
81 optTorso.put(
"remote",(
"/"+robotName+
"/torso").c_str());
82 optTorso.put(
"local",
"/"+moduleName+
"/client/torso");
85 if (polyTorso.open(optTorso))
86 polyTorso.view(posTorso);
89 yWarning(
"Unable to connect to torso! Continuing without...");
93 yarp::sig::Vector head_angles(6,0.0);
94 posHead->getEncoders(head_angles.data());
96 yarp::sig::Vector torso_angles(3,0.0);
98 posTorso->getEncoders(torso_angles.data());
100 qL.resize(torso_angles.length()+head_angles.length()-1);
101 for(
size_t i=0; i<torso_angles.length(); i++)
102 qL[i]=torso_angles[torso_angles.length()-i-1];
104 for(
size_t i=0; i<head_angles.length()-2; i++)
105 qL[i+torso_angles.length()]=head_angles[i];
106 qL[7]=head_angles[4]+(0.5-(
LEFT))*head_angles[5];
109 qR.resize(torso_angles.length()+head_angles.length()-1);
110 for(
size_t i=0; i<torso_angles.length(); i++)
111 qR[i]=torso_angles[torso_angles.length()-i-1];
113 for(
size_t i=0; i<head_angles.length()-2; i++)
114 qR[i+torso_angles.length()]=head_angles[i];
115 qR[7]=head_angles[4]+(0.5-(
RIGHT))*head_angles[5];
124 yInfo(
"Running Stereo Calibration Mode... \n");
129 yInfo(
"Running Mono Calibration Mode... Connect only one eye \n");
133 void stereoCalibThread::stereoCalibRun()
135 imageL=
new ImageOf<PixelRgb>;
136 imageR=
new ImageOf<PixelRgb>;
145 Size boardSize, imageSize;
146 boardSize.width=this->boardWidth;
147 boardSize.height=this->boardHeight;
149 while (!isStopping()) {
150 ImageOf<PixelRgb> *tmpL = imagePortInLeft.read(
false);
151 ImageOf<PixelRgb> *tmpR = imagePortInRight.read(
false);
156 imagePortInLeft.getEnvelope(TSLeft);
162 imagePortInRight.getEnvelope(TSRight);
166 if(initL && initR && checkTS(TSLeft.getTime(),TSRight.getTime())){
172 if(startCalibration>0) {
174 string pathImg=imageDir;
175 preparePath(pathImg.c_str(),pathL,pathR,count);
178 Left=yarp::cv::toCvMat(*imageL);
179 Right=yarp::cv::toCvMat(*imageR);
181 std::vector<Point2f> pointbufL;
182 std::vector<Point2f> pointbufR;
183 if(boardType ==
"CIRCLES_GRID") {
184 foundL = findCirclesGrid(Left, boardSize, pointbufL, CALIB_CB_SYMMETRIC_GRID | CALIB_CB_CLUSTERING);
185 foundR = findCirclesGrid(Right, boardSize, pointbufR, CALIB_CB_SYMMETRIC_GRID | CALIB_CB_CLUSTERING);
186 }
else if(boardType ==
"ASYMMETRIC_CIRCLES_GRID") {
187 foundL = findCirclesGrid(Left, boardSize, pointbufL, CALIB_CB_ASYMMETRIC_GRID | CALIB_CB_CLUSTERING);
188 foundR = findCirclesGrid(Right, boardSize, pointbufR, CALIB_CB_ASYMMETRIC_GRID | CALIB_CB_CLUSTERING);
190 foundL = findChessboardCorners(Left, boardSize, pointbufL, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE);
191 foundR = findChessboardCorners(Right, boardSize, pointbufR, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE);
194 if(foundL && foundR) {
195 cvtColor(Left,Left,CV_RGB2BGR);
196 cvtColor(Right,Right,CV_RGB2BGR);
197 saveStereoImage(pathImg.c_str(),Left,Right,count);
199 imageListR.push_back(imr);
200 imageListL.push_back(iml);
201 imageListLR.push_back(iml);
202 imageListLR.push_back(imr);
205 drawChessboardCorners(Left, boardSize, cL, foundL);
206 drawChessboardCorners(Right, boardSize, cR, foundR);
210 if(count>numOfPairs) {
211 yInfo(
" Running Left Camera Calibration... \n");
212 monoCalibration(imageListL,this->boardWidth,this->boardHeight,this->Kleft,this->DistL);
214 yInfo(
" Running Right Camera Calibration... \n");
215 monoCalibration(imageListR,this->boardWidth,this->boardHeight,this->Kright,this->DistR);
217 stereoCalibration(imageListLR, this->boardWidth,this->boardHeight,this->squareSize);
219 yInfo(
" Saving Calibration Results... \n");
220 updateIntrinsics(Right.cols,Right.rows,Kright.at<
double>(0,0),Kright.at<
double>(1,1),Kright.at<
double>(0,2),Kright.at<
double>(1,2),DistR.at<
double>(0,0),DistR.at<
double>(0,1),DistR.at<
double>(0,2),DistR.at<
double>(0,3),
"CAMERA_CALIBRATION_RIGHT");
221 updateIntrinsics(Left.cols,Left.rows,Kleft.at<
double>(0,0),Kleft.at<
double>(1,1),Kleft.at<
double>(0,2),Kleft.at<
double>(1,2),DistL.at<
double>(0,0),DistL.at<
double>(0,1),DistL.at<
double>(0,2),DistL.at<
double>(0,3),
"CAMERA_CALIBRATION_LEFT");
223 Mat Rot=Mat::eye(3,3,CV_64FC1);
226 updateExtrinsics(this->R,this->T,
"STEREO_DISPARITY");
228 yInfo(
"Calibration Results Saved in %s \n", camCalibFile.c_str());
238 ImageOf<PixelRgb>& outimL=outPortLeft.prepare();
242 ImageOf<PixelRgb>& outimR=outPortRight.prepare();
244 outPortRight.write();
246 if(foundL && foundR && startCalibration==1)
259 void stereoCalibThread::monoCalibRun()
261 while(imagePortInLeft.getInputCount()==0 && imagePortInRight.getInputCount()==0)
263 yInfo(
"Connect one camera.. \n");
271 bool left= imagePortInLeft.getInputCount()>0?
true:
false;
280 yInfo(
"CALIBRATING %s CAMERA \n",cameraName.c_str());
284 Size boardSize, imageSize;
285 boardSize.width=this->boardWidth;
286 boardSize.height=this->boardHeight;
290 while (!isStopping()) {
292 imageL = imagePortInLeft.read(
false);
294 imageL = imagePortInRight.read(
false);
299 if(startCalibration>0) {
301 string pathImg=imageDir;
302 preparePath(pathImg.c_str(),pathL,pathR,count);
304 Left=yarp::cv::toCvMat(*imageL);
305 std::vector<Point2f> pointbufL;
307 if(boardType ==
"CIRCLES_GRID") {
308 foundL = findCirclesGrid(Left, boardSize, pointbufL, CALIB_CB_SYMMETRIC_GRID | CALIB_CB_CLUSTERING);
309 }
else if(boardType ==
"ASYMMETRIC_CIRCLES_GRID") {
310 foundL = findCirclesGrid(Left, boardSize, pointbufL, CALIB_CB_ASYMMETRIC_GRID | CALIB_CB_CLUSTERING);
312 foundL = findChessboardCorners(Left, boardSize, pointbufL, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE);
316 cvtColor(Left,Left,CV_RGB2BGR);
317 saveImage(pathImg.c_str(),Left,count);
318 imageListL.push_back(iml);
320 drawChessboardCorners(Left, boardSize, cL, foundL);
324 if(count>numOfPairs) {
325 yInfo(
" Running %s Camera Calibration... \n", cameraName.c_str());
326 monoCalibration(imageListL,this->boardWidth,this->boardHeight,this->Kleft,this->DistL);
328 yInfo(
" Saving Calibration Results... \n");
329 updateIntrinsics(Left.cols,Left.rows,Kleft.at<
double>(0,0),Kleft.at<
double>(1,1),Kleft.at<
double>(0,2),
330 Kleft.at<
double>(1,2),DistL.at<
double>(0,0),DistL.at<
double>(0,1),DistL.at<
double>(0,2),
331 DistL.at<
double>(0,3),left?
"CAMERA_CALIBRATION_LEFT":
"CAMERA_CALIBRATION_RIGHT");
332 yInfo(
"Calibration Results Saved in %s \n", camCalibFile.c_str());
340 ImageOf<PixelRgb>& outimL=outPortLeft.prepare();
344 ImageOf<PixelRgb>& outimR=outPortRight.prepare();
346 outPortRight.write();
348 if(foundL && startCalibration==1)
359 imagePortInRight.close();
360 imagePortInLeft.close();
362 outPortRight.close();
363 commandPort->close();
365 if (polyHead.isValid())
368 if (polyTorso.isValid())
374 imagePortInRight.interrupt();
375 imagePortInLeft.interrupt();
376 outPortLeft.interrupt();
377 outPortRight.interrupt();
378 commandPort->interrupt();
382 lock_guard<mutex> lck(mtx);
387 lock_guard<mutex> lck(mtx);
391 void stereoCalibThread::printMatrix(Mat &matrix) {
393 int col =matrix.cols;
395 for(
int i = 0; i < matrix.rows; i++)
397 const double* Mi = matrix.ptr<
double>(i);
398 for(
int j = 0; j < matrix.cols; j++)
399 cout << Mi[j] <<
" ";
406 bool stereoCalibThread::checkTS(
double TSLeft,
double TSRight,
double th) {
407 double diff=fabs(TSLeft-TSRight);
414 void stereoCalibThread::preparePath(
const char * imageDir,
char* pathL,
char* pathR,
int count) {
416 sprintf(num,
"%i", count);
419 strncpy(pathL,imageDir, strlen(imageDir));
420 pathL[strlen(imageDir)]=
'\0';
421 strcat(pathL,
"left");
423 strcat(pathL,
".png");
425 strncpy(pathR,imageDir, strlen(imageDir));
426 pathR[strlen(imageDir)]=
'\0';
427 strcat(pathR,
"right");
429 strcat(pathR,
".png");
434 void stereoCalibThread::saveStereoImage(
const char * imageDir,
const Mat& left,
const Mat& right,
int num) {
437 preparePath(imageDir, pathL,pathR,num);
439 yInfo(
"Saving images number %d \n",num);
442 imwrite(pathR,right);
445 void stereoCalibThread::saveImage(
const char * imageDir,
const Mat& left,
int num) {
447 preparePath(imageDir, pathL,pathR,num);
449 yInfo(
"Saving images number %d \n",num);
454 bool stereoCalibThread::updateIntrinsics(
int width,
int height,
double fx,
double fy,
double cx,
double cy,
double k1,
double k2,
double p1,
double p2,
const string& groupname){
456 std::vector<string> lines;
461 in.open(camCalibFile.c_str());
466 bool sectionFound =
false;
467 bool sectionClosed =
false;
470 while(std::getline(in, line)){
472 if (sectionFound ==
true && line.find(
"[", 0) != string::npos)
473 sectionClosed =
true;
475 if (line.find(
string(
"[") + groupname +
string(
"]"), 0) != string::npos)
481 if (sectionFound ==
true && sectionClosed ==
false){
483 if (line.find(
"w",0) ==0){
486 line =
"w " + string(ss.str());
489 if (line.find(
"h",0) ==0){
492 line =
"h " + string(ss.str());
495 if (line.find(
"fx",0) != string::npos){
498 line =
"fx " + string(ss.str());
501 if (line.find(
"fy",0) != string::npos){
504 line =
"fy " + string(ss.str());
507 if (line.find(
"cx",0) != string::npos){
510 line =
"cx " + string(ss.str());
513 if (line.find(
"cy",0) != string::npos){
516 line =
"cy " + string(ss.str());
519 if (line.find(
"k1",0) != string::npos){
522 line =
"k1 " + string(ss.str());
525 if (line.find(
"k2",0) != string::npos){
528 line =
"k2 " + string(ss.str());
531 if (line.find(
"p1",0) != string::npos){
534 line =
"p1 " + string(ss.str());
537 if (line.find(
"p2",0) != string::npos){
540 line =
"p2 " + string(ss.str());
545 lines.push_back(line);
553 cout <<
"Camera calibration parameter section " + string(
"[") + groupname + string(
"]") +
" not found in file " << camCalibFile <<
". Adding group..." << endl;
558 out.open(camCalibFile.c_str(), ios::trunc);
560 for (
int i = 0; i < (int)lines.size(); i++)
561 out << lines[i] << endl;
578 out << string(
"[") + groupname + string(
"]") << endl;
580 out <<
"w " << width << endl;
581 out <<
"h " << height << endl;
582 out <<
"fx " << fx << endl;
583 out <<
"fy " << fy << endl;
584 out <<
"cx " << cx << endl;
585 out <<
"cy " << cy << endl;
586 out <<
"k1 " << k1 << endl;
587 out <<
"k2 " << k2 << endl;
588 out <<
"p1 " << p1 << endl;
589 out <<
"p2 " << p2 << endl;
600 void stereoCalibThread::monoCalibration(
const vector<string>& imageList,
int boardWidth,
int boardHeight, Mat &K, Mat &Dist)
602 vector<vector<Point2f> > imagePoints;
603 Size boardSize, imageSize;
604 boardSize.width=boardWidth;
605 boardSize.height=boardHeight;
609 float squareSize = 1.f, aspectRatio = 1.f;
613 for(i = 0; i<(int)imageList.size();i++)
616 view = cv::imread(imageList[i], 1);
617 imageSize =
view.size();
618 vector<Point2f> pointbuf;
619 cvtColor(
view, viewGray, CV_BGR2GRAY);
622 if(boardType ==
"CIRCLES_GRID") {
623 found = findCirclesGrid(
view, boardSize, pointbuf, CALIB_CB_SYMMETRIC_GRID | CALIB_CB_CLUSTERING);
624 }
else if(boardType ==
"ASYMMETRIC_CIRCLES_GRID") {
625 found = findCirclesGrid(
view, boardSize, pointbuf, CALIB_CB_ASYMMETRIC_GRID | CALIB_CB_CLUSTERING);
627 found = findChessboardCorners(
view, boardSize, pointbuf,
628 CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE);
633 drawChessboardCorners(
view, boardSize, Mat(pointbuf), found );
634 imagePoints.push_back(pointbuf);
638 std::vector<Mat> rvecs, tvecs;
639 std::vector<float> reprojErrs;
640 double totalAvgErr = 0;
642 K = Mat::eye(3, 3, CV_64F);
643 if( flags & CV_CALIB_FIX_ASPECT_RATIO )
644 K.at<
double>(0,0) = aspectRatio;
648 std::vector<std::vector<Point3f> > objectPoints(1);
649 calcChessboardCorners(boardSize, squareSize, objectPoints[0]);
650 objectPoints.resize(imagePoints.size(),objectPoints[0]);
652 double rms = calibrateCamera(objectPoints, imagePoints, imageSize, K,
653 Dist, rvecs, tvecs,CV_CALIB_FIX_K3);
654 yInfo(
"RMS error reported by calibrateCamera: %g\n", rms);
659 void stereoCalibThread::stereoCalibration(
const vector<string>& imagelist,
int boardWidth,
int boardHeight,
float sqsize)
662 boardSize.width=boardWidth;
663 boardSize.height=boardHeight;
664 if( imagelist.size() % 2 != 0 )
666 cout <<
"Error: the image list contains odd (non-even) number of elements\n";
670 const int maxScale = 2;
673 std::vector<std::vector<Point2f> > imagePoints[2];
676 int i, j, k, nimages = (int)imagelist.size()/2;
678 imagePoints[0].resize(nimages);
679 imagePoints[1].resize(nimages);
680 std::vector<string> goodImageList;
681 bool differentSizes =
false;
683 for( i = j = 0; i < nimages; i++ )
685 for( k = 0; k < 2; k++ )
687 const string& filename = imagelist[i*2+k];
688 Mat img = cv::imread(filename, 0);
691 if( imageSize == Size() )
692 imageSize = img.size();
693 else if( img.size() != imageSize )
695 yWarning() <<
"The image " << filename <<
" has the size different from the first image size.\n";
696 differentSizes =
true;
699 std::vector<Point2f>& corners = imagePoints[k][j];
700 for(
int scale = 1; scale <= maxScale; scale++ )
706 resize(img, timg, Size(), scale, scale);
708 if(boardType ==
"CIRCLES_GRID") {
709 found = findCirclesGrid(timg, boardSize, corners, CALIB_CB_SYMMETRIC_GRID | CALIB_CB_CLUSTERING);
710 }
else if(boardType ==
"ASYMMETRIC_CIRCLES_GRID") {
711 found = findCirclesGrid(timg, boardSize, corners, CALIB_CB_ASYMMETRIC_GRID | CALIB_CB_CLUSTERING);
713 found = findChessboardCorners(timg, boardSize, corners,
714 CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_NORMALIZE_IMAGE);
721 Mat cornersMat(corners);
722 cornersMat *= 1./scale;
732 goodImageList.push_back(imagelist[i*2]);
733 goodImageList.push_back(imagelist[i*2+1]);
737 yInfo(
"%i pairs have been successfully detected.\n",j);
741 yError(
"Error: too few pairs detected \n");
745 imagePoints[0].resize(nimages);
746 imagePoints[1].resize(nimages);
748 std::vector<std::vector<Point3f> > objectPoints(1);
749 calcChessboardCorners(boardSize, squareSize, objectPoints[0]);
750 objectPoints.resize(nimages, objectPoints[0]);
752 yInfo(
"Running stereo calibration ...\n");
754 Mat cameraMatrix[2], distCoeffs[2];
756 if(this->Kleft.empty() || this->Kright.empty())
759 yError(
"Images have different sizes. Please make sure to compute intrinsic parameters before running stereo calibration. Quitting...");
762 double rms = stereoCalibrate(objectPoints, imagePoints[0], imagePoints[1],
763 this->Kleft, this->DistL,
764 this->Kright, this->DistR,
765 imageSize, this->R, this->T, E,
F,
766 #ifdef OPENCV_GREATER_2
767 CV_CALIB_FIX_ASPECT_RATIO + CV_CALIB_ZERO_TANGENT_DIST + CV_CALIB_SAME_FOCAL_LENGTH + CV_CALIB_FIX_K3,
768 TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 100, 1
e-5));
770 TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 100, 1
e-5),
771 CV_CALIB_FIX_ASPECT_RATIO + CV_CALIB_ZERO_TANGENT_DIST + CV_CALIB_SAME_FOCAL_LENGTH + CV_CALIB_FIX_K3);
773 yInfo(
"done with RMS error= %f\n",rms);
776 yInfo(
"Using precomputed intrinsic parameters");
777 double rms = stereoCalibrate(objectPoints, imagePoints[0], imagePoints[1],
778 this->Kleft, this->DistL,
779 this->Kright, this->DistR,
780 imageSize, this->R, this->T, E,
F,
781 #ifdef OPENCV_GREATER_2
782 CV_CALIB_FIX_ASPECT_RATIO + CV_CALIB_FIX_INTRINSIC + CV_CALIB_FIX_K3);
783 TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 100, 1
e-5),
785 TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 100, 1
e-5),
786 CV_CALIB_FIX_ASPECT_RATIO + CV_CALIB_FIX_INTRINSIC + CV_CALIB_FIX_K3);
788 yInfo(
"done with RMS error= %f\n",rms);
791 cameraMatrix[0] = this->Kleft;
792 cameraMatrix[1] = this->Kright;
793 distCoeffs[0]=this->DistL;
794 distCoeffs[1]=this->DistR;
800 std::vector<Vec3f> lines[2];
801 for( i = 0; i < nimages; i++ )
803 int npt = (int)imagePoints[0][i].size();
805 for( k = 0; k < 2; k++ )
807 imgpt[k] = Mat(imagePoints[k][i]);
808 undistortPoints(imgpt[k], imgpt[k], cameraMatrix[k], distCoeffs[k], Mat(), cameraMatrix[k]);
809 computeCorrespondEpilines(imgpt[k], k+1,
F, lines[k]);
811 for( j = 0; j < npt; j++ )
813 double errij = fabs(imagePoints[0][i][j].
x*lines[1][j][0] +
814 imagePoints[0][i][j].
y*lines[1][j][1] + lines[1][j][2]) +
815 fabs(imagePoints[1][i][j].
x*lines[0][j][0] +
816 imagePoints[1][i][j].
y*lines[0][j][1] + lines[0][j][2]);
821 yInfo(
"average reprojection err = %f\n",err/npoints);
826 void stereoCalibThread::saveCalibration(
const string& extrinsicFilePath,
const string& intrinsicFilePath){
828 if( Kleft.empty() || Kright.empty() || DistL.empty() || DistR.empty() || R.empty() ||
T.empty()) {
829 cout <<
"Error: cameras are not calibrated! Run the calibration or set intrinsic and extrinsic parameters \n";
833 FileStorage fs(intrinsicFilePath+
".yml", cv::FileStorage::Mode::WRITE);
836 fs <<
"M1" << Kleft <<
"D1" << DistL <<
"M2" << Kright <<
"D2" << DistR;
840 cout <<
"Error: can not save the intrinsic parameters\n";
842 fs.open(extrinsicFilePath+
".yml", cv::FileStorage::Mode::WRITE);
845 fs <<
"R" << R <<
"T" <<
T <<
"Q" << Q;
849 cout <<
"Error: can not save the intrinsic parameters\n";
853 void stereoCalibThread::calcChessboardCorners(Size boardSize,
float squareSize, vector<Point3f>& corners)
857 if(boardType ==
"ASYMMETRIC_CIRCLES_GRID") {
858 for(
int i = 0; i < boardSize.height; i++ )
859 for(
int j = 0; j < boardSize.width; j++ )
860 corners.push_back(Point3f(
float((2*j + i % 2)*squareSize),
float(i*squareSize), 0));
862 for(
int i = 0; i < boardSize.height; i++ )
863 for(
int j = 0; j < boardSize.width; j++ )
864 corners.push_back(Point3f(
float(j*squareSize),
865 float(i*squareSize), 0));
869 bool stereoCalibThread::updateExtrinsics(Mat Rot, Mat Tr,
const string& groupname)
871 std::vector<string> lines;
875 in.open(camCalibFile.c_str());
880 bool sectionFound =
false;
881 bool sectionClosed =
false;
884 while(std::getline(in, line)){
886 if (sectionFound ==
true && line.find(
"[", 0) != string::npos)
887 sectionClosed =
true;
889 if (line.find(
string(
"[") + groupname +
string(
"]"), 0) != string::npos)
895 if (sectionFound ==
true && sectionClosed ==
false){
897 if (line.find(
"HN",0) != string::npos){
899 ss <<
" (" << Rot.at<
double>(0,0) <<
" " << Rot.at<
double>(0,1) <<
" " << Rot.at<
double>(0,2) <<
" " << Tr.at<
double>(0,0) <<
" "
900 << Rot.at<
double>(1,0) <<
" " << Rot.at<
double>(1,1) <<
" " << Rot.at<
double>(1,2) <<
" " << Tr.at<
double>(1,0) <<
" "
901 << Rot.at<
double>(2,0) <<
" " << Rot.at<
double>(2,1) <<
" " << Rot.at<
double>(2,2) <<
" " << Tr.at<
double>(2,0) <<
" "
902 << 0.0 <<
" " << 0.0 <<
" " << 0.0 <<
" " << 1.0 <<
")";
903 line =
"HN" + string(ss.str());
907 if (line.find(
"QL", 0) != string::npos) {
908 line =
"QL (" + string(qL.toString().c_str()) +
")";
910 if (line.find(
"QR", 0) != string::npos) {
911 line =
"QR (" + string(qR.toString().c_str()) +
")";
916 lines.push_back(line);
924 cout <<
"Camera calibration parameter section " + string(
"[") + groupname + string(
"]") +
" not found in file " << camCalibFile <<
". Adding group..." << endl;
929 out.open(camCalibFile.c_str(), ios::trunc);
931 for (
int i = 0; i < (int)lines.size(); i++)
932 out << lines[i] << endl;
950 out << string(
"[") + groupname + string(
"]") << endl;
951 out <<
"HN (" << Rot.at<
double>(0,0) <<
" " << Rot.at<
double>(0,1) <<
" " << Rot.at<
double>(0,2) <<
" " << Tr.at<
double>(0,0) <<
" "
952 << Rot.at<
double>(1,0) <<
" " << Rot.at<
double>(1,1) <<
" " << Rot.at<
double>(1,2) <<
" " << Tr.at<
double>(1,0) <<
" "
953 << Rot.at<
double>(2,0) <<
" " << Rot.at<
double>(2,1) <<
" " << Rot.at<
double>(2,2) <<
" " << Tr.at<
double>(2,0) <<
" "
954 << 0.0 <<
" " << 0.0 <<
" " << 0.0 <<
" " << 1.0 <<
")";
956 out <<
"QL (" << qL.toString().c_str() <<
")" << endl;
957 out <<
"QR (" << qR.toString().c_str() <<
")" << endl;
stereoCalibThread(ResourceFinder &rf, Port *commPort, const char *imageDir)
void append(const size_t index, shared_ptr< Epsilon_neighbours_t > en)
constexpr double CTRL_DEG2RAD
PI/180.