29 #include "ui_calibrationDialog.h" 31 #include <opencv2/core/core.hpp> 32 #include <opencv2/imgproc/imgproc.hpp> 33 #include <opencv2/imgproc/imgproc_c.h> 34 #include <opencv2/calib3d/calib3d.hpp> 35 #if CV_MAJOR_VERSION >= 3 36 #include <opencv2/calib3d/calib3d_c.h> 38 #include <opencv2/highgui/highgui.hpp> 40 #include <QFileDialog> 41 #include <QMessageBox> 42 #include <QCloseEvent> 57 rightSuffix_(
"right"),
58 savingDirectory_(savingDirectory),
59 processingData_(
false),
60 savedCalibration_(
false)
75 qRegisterMetaType<cv::Mat>(
"cv::Mat");
77 ui_ =
new Ui_calibrationDialog();
80 connect(ui_->pushButton_calibrate, SIGNAL(clicked()),
this, SLOT(
calibrate()));
81 connect(ui_->pushButton_restart, SIGNAL(clicked()),
this, SLOT(
restart()));
82 connect(ui_->pushButton_save, SIGNAL(clicked()),
this, SLOT(
save()));
83 connect(ui_->checkBox_switchImages, SIGNAL(stateChanged(
int)),
this, SLOT(
restart()));
84 connect(ui_->checkBox_unlock, SIGNAL(stateChanged(
int)), SLOT(
unlock()));
86 connect(ui_->spinBox_boardWidth, SIGNAL(valueChanged(
int)),
this, SLOT(
setBoardWidth(
int)));
87 connect(ui_->spinBox_boardHeight, SIGNAL(valueChanged(
int)),
this, SLOT(
setBoardHeight(
int)));
88 connect(ui_->doubleSpinBox_squareSize, SIGNAL(valueChanged(
double)),
this, SLOT(
setSquareSize(
double)));
89 connect(ui_->spinBox_maxScale, SIGNAL(valueChanged(
int)),
this, SLOT(
setMaxScale(
int)));
91 connect(ui_->buttonBox, SIGNAL(rejected()),
this, SLOT(close()));
93 ui_->image_view->setFocus();
95 ui_->progressBar_count->setMaximum(
COUNT_MIN);
96 ui_->progressBar_count->setFormat(
"%v");
97 ui_->progressBar_count_2->setMaximum(
COUNT_MIN);
98 ui_->progressBar_count_2->setFormat(
"%v");
100 ui_->radioButton_raw->setChecked(
true);
102 ui_->checkBox_switchImages->setChecked(switchImages);
104 ui_->checkBox_fisheye->setChecked(
false);
105 ui_->checkBox_fisheye->setEnabled(
false);
120 settings.beginGroup(group);
122 settings.setValue(
"board_width",
ui_->spinBox_boardWidth->value());
123 settings.setValue(
"board_height",
ui_->spinBox_boardHeight->value());
124 settings.setValue(
"board_square_size",
ui_->doubleSpinBox_squareSize->value());
125 settings.setValue(
"max_scale",
ui_->spinBox_maxScale->value());
126 settings.setValue(
"geometry", this->saveGeometry());
137 settings.beginGroup(group);
139 this->
setBoardWidth(settings.value(
"board_width",
ui_->spinBox_boardWidth->value()).toInt());
140 this->
setBoardHeight(settings.value(
"board_height",
ui_->spinBox_boardHeight->value()).toInt());
141 this->
setSquareSize(settings.value(
"board_square_size",
ui_->doubleSpinBox_squareSize->value()).toDouble());
142 this->
setMaxScale(settings.value(
"max_scale",
ui_->spinBox_maxScale->value()).toDouble());
143 QByteArray bytes = settings.value(
"geometry", QByteArray()).toByteArray();
146 this->restoreGeometry(bytes);
168 ui_->groupBox_progress->setVisible(visible);
173 ui_->checkBox_switchImages->setChecked(switched);
182 ui_->groupBox_progress->setVisible(
true);
188 ui_->progressBar_count_2->setVisible(
stereo_);
197 ui_->label_baseline_name->setVisible(
stereo_);
202 ui_->radioButton_stereoRectified->setVisible(
stereo_);
203 ui_->checkBox_switchImages->setVisible(
stereo_);
208 if(width !=
ui_->spinBox_boardWidth->value())
210 ui_->spinBox_boardWidth->setValue(width);
217 if(height !=
ui_->spinBox_boardHeight->value())
219 ui_->spinBox_boardHeight->setValue(height);
226 if(size !=
ui_->doubleSpinBox_squareSize->value())
228 ui_->doubleSpinBox_squareSize->setValue(size);
235 if(scale !=
ui_->spinBox_maxScale->value())
237 ui_->spinBox_maxScale->setValue(scale);
248 QMessageBox::StandardButton b = QMessageBox::question(
this, tr(
"Save calibration?"),
249 tr(
"The camera is calibrated but you didn't " 250 "save the calibration, do you want to save it?"),
251 QMessageBox::Yes | QMessageBox::Ignore | QMessageBox::Cancel, QMessageBox::Yes);
253 if(b == QMessageBox::Yes)
260 else if(b == QMessageBox::Ignore)
269 if(event->isAccepted())
285 QMetaObject::invokeMethod(
this,
"processImages",
288 Q_ARG(QString, QString(e->
cameraName().c_str())));
297 UDEBUG(
"Processing images");
302 if(!cameraName.isEmpty())
307 if(
ui_->label_serial->text().isEmpty())
312 std::vector<cv::Mat> inputRawImages(2);
313 if(
ui_->checkBox_switchImages->isChecked())
315 inputRawImages[0] = imageRight;
316 inputRawImages[1] = imageLeft;
320 inputRawImages[0] = imageLeft;
321 inputRawImages[1] = imageRight;
324 std::vector<cv::Mat> images(2);
325 images[0] = inputRawImages[0];
326 images[1] = inputRawImages[1];
330 bool boardFound[2] = {
false};
331 bool boardAccepted[2] = {
false};
332 bool readyToCalibrate[2] = {
false};
334 std::vector<std::vector<cv::Point2f> > pointBuf(2);
336 bool depthDetected =
false;
337 for(
int id=0;
id<(
stereo_?2:1); ++id)
340 if(!images[
id].empty())
342 if(images[
id].type() == CV_16UC1)
345 cv::minMaxLoc(images[
id], &min, &max);
346 UDEBUG(
"Camera IR %d: min=%f max=%f",
id, min, max);
356 depthDetected =
true;
359 viewGray = cv::Mat(images[
id].rows, images[
id].cols, CV_8UC1);
360 for(
int i=0; i<images[id].rows; ++i)
362 for(
int j=0; j<images[id].cols; ++j)
364 viewGray.at<
unsigned char>(i, j) = (
unsigned char)
std::min(
float(
std::max(images[
id].at<unsigned short>(i,j) -
minIrs_[
id], 0)) * factor, 255.0
f);
367 cvtColor(viewGray, images[
id], cv::COLOR_GRAY2BGR);
369 else if(images[
id].channels() == 3)
371 cvtColor(images[
id], viewGray, cv::COLOR_BGR2GRAY);
375 viewGray = images[id];
376 cvtColor(viewGray, images[
id], cv::COLOR_GRAY2BGR);
381 UERROR(
"Image %d is empty!! Should not!",
id);
388 if(!
ui_->pushButton_save->isEnabled())
390 cv::Size boardSize(
ui_->spinBox_boardWidth->value(),
ui_->spinBox_boardHeight->value());
391 if(!viewGray.empty())
393 int flags = CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_NORMALIZE_IMAGE;
395 if(!viewGray.empty())
397 int maxScale =
ui_->spinBox_maxScale->value();
404 cv::resize(viewGray, timg, cv::Size(),
scale,
scale, CV_INTER_CUBIC);
405 boardFound[id] = cv::findChessboardCorners(timg, boardSize, pointBuf[
id], flags);
410 cv::Mat cornersMat(pointBuf[
id]);
411 cornersMat *= 1./
scale;
422 float minSquareDistance = -1.0f;
423 for(
unsigned int i=0; i<pointBuf[id].size()-1; ++i)
425 float d = cv::norm(pointBuf[
id][i] - pointBuf[
id][i+1]);
426 if(minSquareDistance == -1.0
f || minSquareDistance > d)
428 minSquareDistance = d;
431 float radius = minSquareDistance/2.0f +0.5f;
432 cv::cornerSubPix( viewGray, pointBuf[
id], cv::Size(radius, radius), cv::Size(-1,-1),
433 cv::TermCriteria( CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1 ));
436 cv::drawChessboardCorners(images[
id], boardSize, cv::Mat(pointBuf[
id]), boardFound[
id]);
438 std::vector<float> params(4,0);
439 getParams(pointBuf[
id], boardSize,
imageSize_[
id], params[0], params[1], params[2], params[3]);
441 bool addSample =
true;
454 boardAccepted[id] =
true;
459 UINFO(
"[%d] Added board, total=%d. (x=%f, y=%f, size=%f, skew=%f)",
id, (
int)
imagePoints_[
id].size(), params[0], params[1], params[2], params[3]);
463 std::vector<float> xRange(2,
imageParams_[
id][0].at(0));
464 std::vector<float> yRange(2,
imageParams_[
id][0].at(1));
465 std::vector<float> sizeRange(2,
imageParams_[
id][0].at(2));
466 std::vector<float> skewRange(2,
imageParams_[
id][0].at(3));
485 float xGood = xRange[1] - xRange[0];
486 float yGood = yRange[1] - yRange[0];
487 float sizeGood = sizeRange[1] - sizeRange[0];
488 float skewGood = skewRange[1] - skewRange[0];
492 ui_->progressBar_x->setValue(xGood*100);
493 ui_->progressBar_y->setValue(yGood*100);
494 ui_->progressBar_size->setValue(sizeGood*100);
495 ui_->progressBar_skew->setValue(skewGood*100);
504 ui_->progressBar_x_2->setValue(xGood*100);
505 ui_->progressBar_y_2->setValue(yGood*100);
506 ui_->progressBar_size_2->setValue(sizeGood*100);
507 ui_->progressBar_skew_2->setValue(skewGood*100);
516 if(
imagePoints_[
id].size() >=
COUNT_MIN && xGood > 0.5 && yGood > 0.5 && sizeGood > 0.4 && skewGood > 0.5)
518 readyToCalibrate[id] =
true;
522 if(inputRawImages[
id].type() == CV_16UC1)
527 for(
size_t i = 0; i < pointBuf[id].size(); ++i)
529 const cv::Point2f &p = pointBuf[id][i];
532 roi.width =
std::min(roi.width, inputRawImages[
id].cols - roi.x);
533 roi.height =
std::min(roi.height, inputRawImages[
id].rows - roi.y);
537 cv::minMaxLoc(inputRawImages[
id](roi), &min, &max);
551 ui_->label_baseline->setVisible(!depthDetected);
552 ui_->label_baseline_name->setVisible(!depthDetected);
554 if(
stereo_ && ((boardAccepted[0] && boardFound[1]) || (boardAccepted[1] && boardFound[0])))
561 if(!
stereo_ && readyToCalibrate[0])
570 if(
ui_->radioButton_rectified->isChecked())
572 if(
models_[0].isValidForRectification())
574 images[0] =
models_[0].rectifyImage(images[0]);
576 if(
models_[1].isValidForRectification())
578 images[1] =
models_[1].rectifyImage(images[1]);
581 else if(
ui_->radioButton_stereoRectified->isChecked() &&
590 if(
ui_->checkBox_showHorizontalLines->isChecked())
592 for(
int id=0;
id<(
stereo_?2:1); ++id)
597 cv::line(images[
id], cv::Point(0, i), cv::Point(
imageSize_[
id].width, i), CV_RGB(0,255,0));
602 ui_->label_left->setText(tr(
"%1x%2").arg(images[0].cols).arg(images[0].rows));
605 ui_->image_view->setImage(
uCvMat2QImage(images[0]).mirrored(
ui_->checkBox_mirror->isChecked(),
false));
608 ui_->label_right->setText(tr(
"%1x%2").arg(images[1].cols).arg(images[1].rows));
609 ui_->image_view_2->setImage(
uCvMat2QImage(images[1]).mirrored(
ui_->checkBox_mirror->isChecked(),
false));
632 ui_->pushButton_calibrate->setEnabled(
ui_->checkBox_unlock->isChecked());
633 ui_->checkBox_fisheye->setEnabled(
ui_->checkBox_unlock->isChecked());
634 ui_->pushButton_save->setEnabled(
false);
635 ui_->radioButton_raw->setChecked(
true);
636 ui_->radioButton_rectified->setEnabled(
false);
637 ui_->radioButton_stereoRectified->setEnabled(
false);
639 ui_->progressBar_count->reset();
641 ui_->progressBar_x->reset();
642 ui_->progressBar_y->reset();
643 ui_->progressBar_size->reset();
644 ui_->progressBar_skew->reset();
646 ui_->progressBar_count_2->reset();
648 ui_->progressBar_x_2->reset();
649 ui_->progressBar_y_2->reset();
650 ui_->progressBar_size_2->reset();
651 ui_->progressBar_skew_2->reset();
653 ui_->label_serial->clear();
654 ui_->label_fx->setNum(0);
655 ui_->label_fy->setNum(0);
656 ui_->label_cx->setNum(0);
657 ui_->label_cy->setNum(0);
658 ui_->label_baseline->setNum(0);
659 ui_->label_error->setNum(0);
660 ui_->lineEdit_K->clear();
661 ui_->lineEdit_D->clear();
662 ui_->lineEdit_R->clear();
663 ui_->lineEdit_P->clear();
664 ui_->label_fx_2->setNum(0);
665 ui_->label_fy_2->setNum(0);
666 ui_->label_cx_2->setNum(0);
667 ui_->label_cy_2->setNum(0);
668 ui_->lineEdit_K_2->clear();
669 ui_->lineEdit_D_2->clear();
670 ui_->lineEdit_R_2->clear();
671 ui_->lineEdit_P_2->clear();
676 ui_->pushButton_calibrate->setEnabled(
true);
677 ui_->checkBox_fisheye->setEnabled(
true);
685 QMessageBox mb(QMessageBox::Information,
686 tr(
"Calibrating..."),
687 tr(
"Operation in progress..."));
689 QApplication::processEvents();
691 QApplication::processEvents();
693 std::vector<std::vector<cv::Point3f> > objectPoints(1);
694 cv::Size boardSize(
ui_->spinBox_boardWidth->value(),
ui_->spinBox_boardHeight->value());
695 float squareSize =
ui_->doubleSpinBox_squareSize->value();
697 for(
int i = 0; i < boardSize.height; ++i )
698 for(
int j = 0; j < boardSize.width; ++j )
699 objectPoints[0].push_back(cv::Point3f(
float( j*squareSize ),
float( i*squareSize ), 0));
701 for(
int id=0;
id<(
stereo_?2:1); ++id)
705 objectPoints.resize(
imagePoints_[
id].size(), objectPoints[0]);
708 std::vector<cv::Mat> rvecs, tvecs;
709 std::vector<float> reprojErrs;
711 K = cv::Mat::eye(3,3,CV_64FC1);
715 #if CV_MAJOR_VERSION > 2 or (CV_MAJOR_VERSION == 2 and (CV_MINOR_VERSION >4 or (CV_MINOR_VERSION == 4 and CV_SUBMINOR_VERSION >=10))) 716 bool fishEye =
ui_->checkBox_fisheye->isChecked();
729 cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC |
730 cv::fisheye::CALIB_CHECK_COND |
731 cv::fisheye::CALIB_FIX_SKEW);
733 catch(
const cv::Exception &
e)
735 UERROR(
"Error: %s (try restarting the calibration)", e.what());
736 QMessageBox::warning(
this, tr(
"Calibration failed!"), tr(
"Error: %1 (try restarting the calibration)").arg(e.what()));
744 rms = cv::calibrateCamera(objectPoints,
753 UINFO(
"Re-projection error reported by calibrateCamera: %f", rms);
756 std::vector<cv::Point2f> imagePoints2;
757 int i, totalPoints = 0;
758 double totalErr = 0, err;
759 reprojErrs.resize(objectPoints.size());
761 for( i = 0; i < (int)objectPoints.size(); ++i )
763 #if CV_MAJOR_VERSION > 2 or (CV_MAJOR_VERSION == 2 and (CV_MINOR_VERSION >4 or (CV_MINOR_VERSION == 4 and CV_SUBMINOR_VERSION >=10))) 766 cv::fisheye::projectPoints( cv::Mat(objectPoints[i]), imagePoints2, rvecs[i], tvecs[i], K, D);
771 cv::projectPoints( cv::Mat(objectPoints[i]), rvecs[i], tvecs[i], K, D, imagePoints2);
773 err = cv::norm(cv::Mat(
imagePoints_[
id][i]), cv::Mat(imagePoints2), CV_L2);
775 int n = (int)objectPoints[i].size();
776 reprojErrs[i] = (float)
std::sqrt(err*err/n);
781 double totalAvgErr =
std::sqrt(totalErr/totalPoints);
783 UINFO(
"avg re projection error = %f", totalAvgErr);
785 cv::Mat P(3,4,CV_64FC1);
786 P.at<
double>(2,3) = 1;
787 K.copyTo(P.colRange(0,3).rowRange(0,3));
789 #if CV_MAJOR_VERSION > 2 or (CV_MAJOR_VERSION == 2 and (CV_MINOR_VERSION >4 or (CV_MINOR_VERSION == 4 and CV_SUBMINOR_VERSION >=10))) 793 cv::Mat newD = cv::Mat::zeros(1,6,CV_64FC1);
794 newD.at<
double>(0,0) = D.at<
double>(0,0);
795 newD.at<
double>(0,1) = D.at<
double>(0,1);
796 newD.at<
double>(0,4) = D.at<
double>(0,2);
797 newD.at<
double>(0,5) = D.at<
double>(0,3);
802 std::cout <<
"K = " << K << std::endl;
803 std::cout <<
"D = " << D << std::endl;
804 std::cout <<
"width = " <<
imageSize_[id].width << std::endl;
805 std::cout <<
"height = " <<
imageSize_[id].height << std::endl;
815 ui_->label_error->setNum(totalAvgErr);
817 std::stringstream strK, strD, strR, strP;
822 ui_->lineEdit_K->setText(strK.str().c_str());
823 ui_->lineEdit_D->setText(strD.str().c_str());
824 ui_->lineEdit_R->setText(strR.str().c_str());
825 ui_->lineEdit_P->setText(strP.str().c_str());
833 ui_->label_error_2->setNum(totalAvgErr);
835 std::stringstream strK, strD, strR, strP;
840 ui_->lineEdit_K_2->setText(strK.str().c_str());
841 ui_->lineEdit_D_2->setText(strD.str().c_str());
842 ui_->lineEdit_R_2->setText(strR.str().c_str());
843 ui_->lineEdit_P_2->setText(strP.str().c_str());
851 std::stringstream strR1, strP1, strR2, strP2;
856 ui_->lineEdit_R->setText(strR1.str().c_str());
857 ui_->lineEdit_P->setText(strP1.str().c_str());
858 ui_->lineEdit_R_2->setText(strR2.str().c_str());
859 ui_->lineEdit_P_2->setText(strP2.str().c_str());
869 models_[0].initRectificationMap();
870 models_[1].initRectificationMap();
871 ui_->radioButton_rectified->setEnabled(
true);
872 ui_->radioButton_stereoRectified->setEnabled(
true);
873 ui_->radioButton_stereoRectified->setChecked(
true);
874 ui_->pushButton_save->setEnabled(
true);
876 else if(
models_[0].isValidForRectification())
878 models_[0].initRectificationMap();
879 ui_->radioButton_rectified->setEnabled(
true);
880 ui_->radioButton_rectified->setChecked(
true);
884 UINFO(
"End calibration");
893 UERROR(
"No stereo correspondences!");
898 if (left.
K_raw().empty() || left.
D_raw().empty())
900 UERROR(
"Empty intrinsic parameters (K, D) for the %s camera! Aborting stereo calibration...",
leftSuffix_.toStdString().c_str());
903 if (right.
K_raw().empty() || right.
D_raw().empty())
905 UERROR(
"Empty intrinsic parameters (K, D) for the %s camera! Aborting stereo calibration...",
rightSuffix_.toStdString().c_str());
911 UERROR(
"left model (%dx%d) has not the same size as the processed images (%dx%d)",
918 UERROR(
"right model (%dx%d) has not the same size as the processed images (%dx%d)",
927 std::vector<std::vector<cv::Point3f> > objectPoints(1);
928 cv::Size boardSize(
ui_->spinBox_boardWidth->value(),
ui_->spinBox_boardHeight->value());
929 float squareSize =
ui_->doubleSpinBox_squareSize->value();
931 for (
int i = 0; i < boardSize.height; ++i)
932 for (
int j = 0; j < boardSize.width; ++j)
933 objectPoints[0].push_back(cv::Point3f(
float(j*squareSize),
float(i*squareSize), 0));
937 #if CV_MAJOR_VERSION > 2 or (CV_MAJOR_VERSION == 2 and (CV_MINOR_VERSION >4 or (CV_MINOR_VERSION == 4 and CV_SUBMINOR_VERSION >=10))) 938 bool fishEye = left.
D_raw().cols == 6;
942 cv::Mat D_left(1,4,CV_64FC1);
943 D_left.at<
double>(0,0) = left.
D_raw().at<
double>(0,0);
944 D_left.at<
double>(0,1) = left.
D_raw().at<
double>(0,1);
945 D_left.at<
double>(0,2) = left.
D_raw().at<
double>(0,4);
946 D_left.at<
double>(0,3) = left.
D_raw().at<
double>(0,5);
947 cv::Mat D_right(1,4,CV_64FC1);
949 D_right.at<
double>(0,0) = right.
D_raw().at<
double>(0,0);
950 D_right.at<
double>(0,1) = right.
D_raw().at<
double>(0,1);
951 D_right.at<
double>(0,2) = right.
D_raw().at<
double>(0,4);
952 D_right.at<
double>(0,3) = right.
D_raw().at<
double>(0,5);
954 rms = cv::fisheye::stereoCalibrate(
958 left.
K_raw(), D_left,
959 right.
K_raw(), D_right,
961 cv::CALIB_FIX_INTRINSIC,
962 cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 100, 1
e-5));
967 #if CV_MAJOR_VERSION < 3 968 rms = cv::stereoCalibrate(
974 imageSize, R, T, E, F,
975 cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 100, 1
e-5),
976 cv::CALIB_FIX_INTRINSIC);
978 rms = cv::stereoCalibrate(
984 imageSize, R, T, E, F,
985 cv::CALIB_FIX_INTRINSIC,
986 cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 100, 1
e-5));
989 UINFO(
"stereo calibration... done with RMS error=%f", rms);
991 std::cout <<
"R = " << R << std::endl;
992 std::cout <<
"T = " << T << std::endl;
993 std::cout <<
"E = " << E << std::endl;
994 std::cout <<
"F = " << F << std::endl;
998 UINFO(
"Compute stereo rectification");
1000 cv::Mat R1, R2, P1, P2, Q;
1001 cv::stereoRectify(left.
K_raw(), left.
D_raw(),
1003 imageSize, R, T, R1, R2, P1, P2, Q,
1004 cv::CALIB_ZERO_DISPARITY, 0, imageSize);
1008 std::vector<cv::Vec3f> lines[2];
1009 UINFO(
"Computing avg re-projection error...");
1016 cv::undistortPoints(imgpt0, imgpt0, left.
K_raw(), left.
D_raw(), R1, P1);
1017 cv::undistortPoints(imgpt1, imgpt1, right.
K_raw(), right.
D_raw(), R2, P2);
1018 computeCorrespondEpilines(imgpt0, 1, F, lines[0]);
1019 computeCorrespondEpilines(imgpt1, 2, F, lines[1]);
1021 for(
int j = 0; j < npt; j++ )
1031 double totalAvgErr = err/(double)npoints;
1032 UINFO(
"stereo avg re projection error = %f", totalAvgErr);
1060 QString cameraName =
models_[0].name().c_str();
1061 QString filePath = QFileDialog::getSaveFileName(
this, tr(
"Export"),
savingDirectory_+
"/"+cameraName+
".yaml",
"*.yaml");
1063 if(!filePath.isEmpty())
1065 QString name = QFileInfo(filePath).baseName();
1066 QString dir = QFileInfo(filePath).absoluteDir().absolutePath();
1067 models_[0].setName(name.toStdString());
1070 QMessageBox::information(
this, tr(
"Export"), tr(
"Calibration file saved to \"%1\".").arg(filePath));
1071 UINFO(
"Saved \"%s\"!", filePath.toStdString().c_str());
1077 UERROR(
"Error saving \"%s\"", filePath.toStdString().c_str());
1086 QString filePath = QFileDialog::getSaveFileName(
this, tr(
"Export"),
savingDirectory_ +
"/" + cameraName,
"*.yaml");
1087 QString name = QFileInfo(filePath).baseName();
1088 QString dir = QFileInfo(filePath).absoluteDir().absolutePath();
1091 bool switched =
ui_->checkBox_switchImages->isChecked();
1093 std::string base = (dir+QDir::separator()+name).toStdString();
1096 std::string posePath = base+
"_pose.yaml";
1099 QMessageBox::information(
this, tr(
"Export"), tr(
"Calibration files saved:\n \"%1\"\n \"%2\"\n \"%3\".").
1100 arg(leftPath.c_str()).arg(rightPath.c_str()).arg(posePath.c_str()));
1101 UINFO(
"Saved \"%s\" and \"%s\"!", leftPath.c_str(), rightPath.c_str());
1107 UERROR(
"Error saving \"%s\" and \"%s\"", leftPath.c_str(), rightPath.c_str());
1121 cv::Point2f up_left = corners[0];
1122 cv::Point2f up_right = corners[boardSize.width-1];
1123 cv::Point2f down_right = corners[corners.size()-1];
1124 cv::Point2f down_left = corners[corners.size()-boardSize.width];
1125 cv::Point2f a = up_right - up_left;
1126 cv::Point2f b = down_right - up_right;
1127 cv::Point2f c = down_left - down_right;
1128 cv::Point2f p = b + c;
1129 cv::Point2f q = a + b;
1130 return std::fabs(p.x*q.y - p.y*q.x) / 2.0f;
1139 cv::Point2f up_left = corners[0];
1140 cv::Point2f up_right = corners[boardSize.width-1];
1141 cv::Point2f down_right = corners[corners.size()-1];
1145 cv::Point2f ab = up_left - up_right;
1146 cv::Point2f cb = down_right - up_right;
1147 float angle =
std::acos(ab.dot(cb) / (cv::norm(ab) * cv::norm(cb)));
1149 float r = 2.0f * std::fabs((CV_PI / 2.0
f) - angle);
1150 return r > 1.0f?1.0f:r;
1158 float & x,
float & y,
float & size,
float & skew)
1160 float area =
getArea(corners, boardSize);
1161 size =
std::sqrt(area / (imageSize.width * imageSize.height));
1162 skew =
getSkew(corners, boardSize);
1165 for(
unsigned int i=0; i<corners.size(); ++i)
1167 meanX += corners[i].x;
1168 meanY += corners[i].y;
1170 meanX /= corners.size();
1171 meanY /= corners.size();
1172 x = meanX / imageSize.width;
1173 y = meanY / imageSize.height;
void processImages(const cv::Mat &imageLeft, const cv::Mat &imageRight, const QString &cameraName)
const cv::Size & imageSize() const
GLM_FUNC_DECL genType min(genType const &x, genType const &y)
void setBoardWidth(int width)
GLM_FUNC_DECL vecType< T, P > sqrt(vecType< T, P > const &x)
std::vector< std::vector< std::vector< cv::Point2f > > > stereoImagePoints_
void loadSettings(QSettings &settings, const QString &group="")
const std::string & cameraName() const
GLM_FUNC_DECL genType e()
std::vector< unsigned short > minIrs_
void setSquareSize(double size)
GLM_FUNC_DECL T angle(detail::tquat< T, P > const &x)
std::vector< unsigned short > maxIrs_
void setSwitchedImages(bool switched)
virtual ~CalibrationDialog()
const std::string & getRightSuffix() const
const cv::Mat & imageRaw() const
GLM_FUNC_DECL genType step(genType const &edge, genType const &x)
void initRectificationMap()
void setBoardHeight(int height)
rtabmap::StereoCameraModel stereoModel_
#define UASSERT(condition)
virtual void closeEvent(QCloseEvent *event)
const CameraModel & left() const
std::vector< std::vector< std::vector< cv::Point2f > > > imagePoints_
void getParams(const std::vector< cv::Point2f > &corners, const cv::Size &boardSize, const cv::Size &imageSize, float &x, float &y, float &size, float &skew)
QImage uCvMat2QImage(const cv::Mat &image, bool isBgr=true, uCvQtDepthColorMap colorMap=uCvQtDepthWhiteToBlack)
CvImagePtr cvtColor(const CvImageConstPtr &source, const std::string &encoding)
virtual std::string getClassName() const =0
bool isValidForRectification() const
std::vector< rtabmap::CameraModel > models_
bool save(const std::string &directory, bool ignoreStereoTransform=true) const
const cv::Mat & depthOrRightRaw() const
DiscreteDepthDistortionModel RTABMAP_EXP calibrate(const std::map< int, rtabmap::SensorData > &sequence, const std::map< int, rtabmap::Transform > &trajectory, const pcl::PointCloud< pcl::PointXYZ >::Ptr &map, double coneRadius=0.02, double coneStdevThresh=0.03)
cv::Mat rectifyImage(const cv::Mat &raw, int interpolation=cv::INTER_LINEAR) const
void uSleep(unsigned int ms)
CalibrationDialog(bool stereo=false, const QString &savingDirectory=".", bool switchImages=false, QWidget *parent=0)
void setStereoMode(bool stereo, const QString &leftSuffix="left", const QString &rightSuffix="right")
void setProgressVisibility(bool visible)
GLM_FUNC_DECL genType max(genType const &x, genType const &y)
bool isValidForRectification() const
const CameraModel & right() const
void setMaxScale(int scale)
ULogger class and convenient macros.
GLM_FUNC_DECL genType acos(genType const &x)
void setName(const std::string &name, const std::string &leftSuffix="left", const std::string &rightSuffix="right")
std::vector< cv::Size > imageSize_
float getArea(const std::vector< cv::Point2f > &corners, const cv::Size &boardSize)
std::vector< std::vector< std::vector< float > > > imageParams_
const SensorData & data() const
Ui_calibrationDialog * ui_
virtual bool handleEvent(UEvent *event)
void unregisterFromEventsManager()
void saveSettings(QSettings &settings, const QString &group="") const
const std::string & getLeftSuffix() const
void setCameraName(const QString &name)
float getSkew(const std::vector< cv::Point2f > &corners, const cv::Size &boardSize)
StereoCameraModel stereoCalibration(const CameraModel &left, const CameraModel &right, bool ignoreStereoRectification) const
const std::string & name() const