29 #include "ui_createSimpleCalibrationDialog.h" 35 #include <QFileDialog> 36 #include <QPushButton> 37 #include <QMessageBox> 42 const QString & savingFolder,
43 const QString & cameraName,
46 savingFolder_(savingFolder),
47 cameraName_(cameraName)
54 ui_ =
new Ui_createSimpleCalibrationDialog();
57 connect(
ui_->buttonBox->button(QDialogButtonBox::Save), SIGNAL(clicked()),
this, SLOT(
saveCalibration()));
58 connect(
ui_->buttonBox, SIGNAL(rejected()),
this, SLOT(reject()));
60 connect(
ui_->comboBox_advanced, SIGNAL(currentIndexChanged(
int)),
ui_->stackedWidget, SLOT(setCurrentIndex(
int)));
63 connect(
ui_->comboBox_advanced, SIGNAL(currentIndexChanged(
int)),
this, SLOT(
updateStereoView()));
65 connect(
ui_->comboBox_advanced, SIGNAL(currentIndexChanged(
int)),
this, SLOT(
updateSaveStatus()));
67 connect(
ui_->doubleSpinBox_fx, SIGNAL(valueChanged(
double)),
this, SLOT(
updateSaveStatus()));
68 connect(
ui_->doubleSpinBox_fy, SIGNAL(valueChanged(
double)),
this, SLOT(
updateSaveStatus()));
70 connect(
ui_->doubleSpinBox_fx_l, SIGNAL(valueChanged(
double)),
this, SLOT(
updateSaveStatus()));
71 connect(
ui_->doubleSpinBox_fy_l, SIGNAL(valueChanged(
double)),
this, SLOT(
updateSaveStatus()));
72 connect(
ui_->doubleSpinBox_cx_l, SIGNAL(valueChanged(
double)),
this, SLOT(
updateSaveStatus()));
73 connect(
ui_->doubleSpinBox_cy_l, SIGNAL(valueChanged(
double)),
this, SLOT(
updateSaveStatus()));
74 connect(
ui_->lineEdit_D_l, SIGNAL(textEdited(
const QString &)),
this, SLOT(
updateSaveStatus()));
76 connect(
ui_->doubleSpinBox_fx_r, SIGNAL(valueChanged(
double)),
this, SLOT(
updateSaveStatus()));
77 connect(
ui_->doubleSpinBox_fy_r, SIGNAL(valueChanged(
double)),
this, SLOT(
updateSaveStatus()));
78 connect(
ui_->doubleSpinBox_cx_r, SIGNAL(valueChanged(
double)),
this, SLOT(
updateSaveStatus()));
79 connect(
ui_->doubleSpinBox_cy_r, SIGNAL(valueChanged(
double)),
this, SLOT(
updateSaveStatus()));
80 connect(
ui_->lineEdit_D_r, SIGNAL(textEdited(
const QString &)),
this, SLOT(
updateSaveStatus()));
85 connect(
ui_->doubleSpinBox_baseline, SIGNAL(valueChanged(
double)),
this, SLOT(
updateSaveStatus()));
86 connect(
ui_->lineEdit_RT, SIGNAL(textEdited(
const QString &)),
this, SLOT(
updateSaveStatus()));
88 ui_->stackedWidget->setCurrentIndex(
ui_->comboBox_advanced->currentIndex());
90 ui_->buttonBox->button(QDialogButtonBox::Save)->setEnabled(
false);
102 bool checked =
ui_->checkBox_stereo->isChecked();
103 ui_->doubleSpinBox_baseline->setVisible(checked);
104 ui_->label_baseline->setVisible(checked);
105 ui_->label_right->setVisible(checked);
106 ui_->doubleSpinBox_fx_r->setVisible(checked);
107 ui_->doubleSpinBox_fy_r->setVisible(checked);
108 ui_->doubleSpinBox_cx_r->setVisible(checked);
109 ui_->doubleSpinBox_cy_r->setVisible(checked);
110 ui_->lineEdit_D_r->setVisible(checked);
111 ui_->groupBox_stereo_extrinsics->setVisible(
ui_->comboBox_advanced->currentIndex() == 1 && checked);
112 ui_->label_left->setVisible(checked);
118 if(
ui_->comboBox_advanced->currentIndex() == 0 &&
119 ui_->doubleSpinBox_fx->value() > 0.0 &&
120 ui_->doubleSpinBox_fy->value() > 0.0 &&
121 ui_->spinBox_width->value() > 0 &&
122 ui_->spinBox_height->value() > 0 &&
123 (!
ui_->checkBox_stereo->isChecked() ||
ui_->doubleSpinBox_baseline->value() != 0.0))
128 else if(
ui_->comboBox_advanced->currentIndex() == 1 &&
129 ui_->doubleSpinBox_fx_l->value() > 0.0 &&
130 ui_->doubleSpinBox_fy_l->value() > 0.0 &&
131 ui_->doubleSpinBox_cx_l->value() > 0.0 &&
132 ui_->doubleSpinBox_cy_l->value() > 0.0 &&
133 (!
ui_->checkBox_stereo->isChecked() ||
ui_->doubleSpinBox_fx_r->value() > 0.0) &&
134 (!
ui_->checkBox_stereo->isChecked() ||
ui_->doubleSpinBox_fy_r->value() > 0.0) &&
135 (!
ui_->checkBox_stereo->isChecked() ||
ui_->doubleSpinBox_cx_r->value() > 0.0) &&
136 (!
ui_->checkBox_stereo->isChecked() ||
ui_->doubleSpinBox_cy_r->value() > 0.0) &&
137 ui_->spinBox_width->value() > 0 &&
138 ui_->spinBox_height->value() > 0 &&
139 !
ui_->lineEdit_D_l->text().isEmpty() &&
140 (!
ui_->checkBox_stereo->isChecked() || !
ui_->lineEdit_D_r->text().isEmpty()) &&
141 (!
ui_->checkBox_stereo->isChecked() || !
ui_->lineEdit_RT->text().isEmpty()))
144 QStringList distorsionsStrListL =
ui_->lineEdit_D_l->text().remove(
'[').remove(
']').replace(
',',
' ').replace(
';',
' ').simplified().trimmed().split(
' ');
145 QStringList distorsionsStrListR =
ui_->lineEdit_D_r->text().remove(
'[').remove(
']').replace(
',',
' ').replace(
';',
' ').simplified().trimmed().split(
' ');
146 std::string RT =
ui_->lineEdit_RT->text().remove(
'[').remove(
']').replace(
',',
' ').replace(
';',
' ').simplified().trimmed().toStdString();
148 if((distorsionsStrListL.size() == 4 || distorsionsStrListL.size() == 5 || distorsionsStrListL.size() == 8) &&
149 (!
ui_->checkBox_stereo->isChecked() || (distorsionsStrListR.size() == 4 || distorsionsStrListR.size() == 5 || distorsionsStrListR.size() == 8)) &&
155 ui_->buttonBox->button(QDialogButtonBox::Save)->setEnabled(valid);
161 QString name = QFileInfo(filePath).baseName();
162 QString dir = QFileInfo(filePath).absoluteDir().absolutePath();
163 if(!filePath.isEmpty())
167 float width =
ui_->spinBox_width->value();
168 float height =
ui_->spinBox_height->value();
169 if(
ui_->comboBox_advanced->currentIndex() == 0)
174 ui_->doubleSpinBox_fx->value(),
175 ui_->doubleSpinBox_fy->value(),
176 ui_->doubleSpinBox_cx->value(),
177 ui_->doubleSpinBox_cy->value(),
180 cv::Size(width, height));
186 cv::Mat K = cv::Mat::eye(3, 3, CV_64FC1);
187 K.at<
double>(0,0) =
ui_->doubleSpinBox_fx_l->value();
188 K.at<
double>(1,1) =
ui_->doubleSpinBox_fy_l->value();
189 K.at<
double>(0,2) =
ui_->doubleSpinBox_cx_l->value();
190 K.at<
double>(1,2) =
ui_->doubleSpinBox_cy_l->value();
191 cv::Mat R = cv::Mat::eye(3, 3, CV_64FC1);
192 cv::Mat P = cv::Mat::zeros(3, 4, CV_64FC1);
193 K.copyTo(cv::Mat(P, cv::Range(0,3), cv::Range(0,3)));
195 QStringList distorsionCoeffs =
ui_->lineEdit_D_l->text().remove(
'[').remove(
']').replace(
',',
' ').replace(
';',
' ').simplified().trimmed().split(
' ');
196 UASSERT(distorsionCoeffs.size() == 4 || distorsionCoeffs.size() == 5 || distorsionCoeffs.size() == 8);
197 cv::Mat D = cv::Mat::zeros(1, distorsionCoeffs.size(), CV_64FC1);
199 for(
int i=0; i<distorsionCoeffs.size(); ++i)
201 D.at<
double>(i) = distorsionCoeffs.at(i).toDouble(&ok);
204 QMessageBox::warning(
this, tr(
"Save"), tr(
"Error parsing left distortion coefficients \"%1\".").arg(
ui_->lineEdit_D_l->text()));
209 modelLeft =
CameraModel(name.toStdString(), cv::Size(width,height), K, D, R, P);
213 if(
ui_->checkBox_stereo->isChecked())
216 if(
ui_->comboBox_advanced->currentIndex() == 0)
220 ui_->doubleSpinBox_fx->value(),
221 ui_->doubleSpinBox_fy->value(),
222 ui_->doubleSpinBox_cx->value(),
223 ui_->doubleSpinBox_cy->value(),
225 ui_->doubleSpinBox_baseline->value()*-
ui_->doubleSpinBox_fx->value(),
226 cv::Size(width, height));
227 UASSERT(modelRight.isValidForProjection());
229 UASSERT(stereoModel.isValidForProjection());
231 else if(
ui_->comboBox_advanced->currentIndex() == 1)
234 cv::Mat K = cv::Mat::eye(3, 3, CV_64FC1);
235 K.at<
double>(0,0) =
ui_->doubleSpinBox_fx_r->value();
236 K.at<
double>(1,1) =
ui_->doubleSpinBox_fy_r->value();
237 K.at<
double>(0,2) =
ui_->doubleSpinBox_cx_r->value();
238 K.at<
double>(1,2) =
ui_->doubleSpinBox_cy_r->value();
239 cv::Mat R = cv::Mat::eye(3, 3, CV_64FC1);
240 cv::Mat P = cv::Mat::zeros(3, 4, CV_64FC1);
241 K.copyTo(cv::Mat(P, cv::Range(0,3), cv::Range(0,3)));
243 QStringList distorsionCoeffs =
ui_->lineEdit_D_r->text().remove(
'[').remove(
']').replace(
',',
' ').replace(
';',
' ').simplified().trimmed().split(
' ');
244 UASSERT(distorsionCoeffs.size() == 4 || distorsionCoeffs.size() == 5 || distorsionCoeffs.size() == 8);
245 cv::Mat D = cv::Mat::zeros(1, distorsionCoeffs.size(), CV_64FC1);
247 for(
int i=0; i<distorsionCoeffs.size(); ++i)
249 D.at<
double>(i) = distorsionCoeffs.at(i).toDouble(&ok);
252 QMessageBox::warning(
this, tr(
"Save"), tr(
"Error parsing right distortion coefficients \"%1\".").arg(
ui_->lineEdit_D_r->text()));
257 modelRight =
CameraModel(name.toStdString(), cv::Size(width,height), K, D, R, P);
261 stereoModel =
StereoCameraModel(name.toStdString(), modelLeft, modelRight,
Transform::fromString(
ui_->lineEdit_RT->text().remove(
'[').remove(
']').replace(
',',
' ').replace(
';',
' ').trimmed().toStdString()));
264 QMessageBox::warning(
this, tr(
"Save"), tr(
"Error parsing the extrinsics \"%1\", resulting baseline (%f) is negative!").arg(
ui_->lineEdit_RT->text()).arg(stereoModel.
baseline()));
270 std::string base = (dir+QDir::separator()+name).toStdString();
271 std::string leftPath = base+
"_left.yaml";
272 std::string rightPath = base+
"_right.yaml";
274 if(stereoModel.
save(dir.toStdString(),
ui_->comboBox_advanced->currentIndex() != 1))
276 if(
ui_->comboBox_advanced->currentIndex() == 0)
278 QMessageBox::information(
this, tr(
"Save"), tr(
"Calibration files saved:\n \"%1\"\n \"%2\".").
279 arg(leftPath.c_str()).arg(rightPath.c_str()));
283 std::string posePath = base+
"_pose.yaml";
284 QMessageBox::information(
this, tr(
"Save"), tr(
"Calibration files saved:\n \"%1\"\n \"%2\"\n \"%3\".").
285 arg(leftPath.c_str()).arg(rightPath.c_str()).arg(posePath.c_str()));
291 QMessageBox::warning(
this, tr(
"Save"), tr(
"Error saving \"%1\" and \"%2\"").arg(leftPath.c_str()).arg(rightPath.c_str()));
296 if(modelLeft.
save(dir.toStdString()))
298 QMessageBox::information(
this, tr(
"Save"), tr(
"Calibration file saved to \"%1\".").arg(filePath));
303 QMessageBox::warning(
this, tr(
"Save"), tr(
"Error saving \"%1\"").arg(filePath));
bool save(const std::string &directory) const
#define UASSERT(condition)
CreateSimpleCalibrationDialog(const QString &savingFolder=".", const QString &cameraName="", QWidget *parent=0)
bool isValidForRectification() const
bool save(const std::string &directory, bool ignoreStereoTransform=true) const
Ui_createSimpleCalibrationDialog * ui_
bool isValidForProjection() const
bool isValidForRectification() const
ULogger class and convenient macros.
virtual ~CreateSimpleCalibrationDialog()