mirror of
https://github.com/introlab/rtabmap.git
synced 2026-10-04 17:17:47 +08:00
Confirmed stereo calibration with fisheye works. Fix camera start/top progress dialog not drawn. Opencv >=4.7 using new opencv's ArucoDetector class.
This commit is contained in:
@@ -280,18 +280,23 @@ void CalibrationDialog::generateBoard()
|
||||
if(ui_->comboBox_board_type->currentIndex() >= 1 )
|
||||
{
|
||||
try {
|
||||
const int marginInPixels = squareSizeInPixels/4;
|
||||
cv::Size size(
|
||||
squareSizeInPixels*ui_->spinBox_boardWidth->value() + 2*marginInPixels,
|
||||
squareSizeInPixels*ui_->spinBox_boardHeight->value() + 2*marginInPixels);
|
||||
UINFO("Creating board image of %dx%d pixels (%dx%d squares)",
|
||||
size.width, size.height,
|
||||
ui_->spinBox_boardWidth->value(), ui_->spinBox_boardHeight->value());
|
||||
#if CV_MAJOR_VERSION > 4 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION >= 7)
|
||||
charucoBoard_->generateImage(
|
||||
cv::Size(squareSizeInPixels*ui_->spinBox_boardWidth->value(),
|
||||
squareSizeInPixels*ui_->spinBox_boardHeight->value()),
|
||||
size,
|
||||
image,
|
||||
squareSizeInPixels/4, 1);
|
||||
marginInPixels, 1);
|
||||
#else
|
||||
charucoBoard_->draw(
|
||||
cv::Size(squareSizeInPixels*ui_->spinBox_boardWidth->value(),
|
||||
squareSizeInPixels*ui_->spinBox_boardHeight->value()),
|
||||
size,
|
||||
image,
|
||||
squareSizeInPixels/4, 1);
|
||||
marginInPixels, 1);
|
||||
#endif
|
||||
|
||||
int arucoDict = ui_->comboBox_marker_dictionary->currentIndex();
|
||||
@@ -301,7 +306,7 @@ void CalibrationDialog::generateBoard()
|
||||
}
|
||||
catch(const cv::Exception & e)
|
||||
{
|
||||
UERROR("%f", e.what());
|
||||
UERROR("%s", e.what());
|
||||
QMessageBox::critical(this, tr("Generating Board"),
|
||||
tr("Cannot generate the board. Make sure the dictionary "
|
||||
"selected is big enough for the board size. Error:\"%1\"").arg(e.what()));
|
||||
@@ -1405,26 +1410,77 @@ void CalibrationDialog::calibrate()
|
||||
|
||||
if(fishEye)
|
||||
{
|
||||
try
|
||||
// cv::fisheye::calibrate() with CALIB_CHECK_COND throws as soon as a single
|
||||
// view is ill-conditioned (e.g. too few / poorly spread ChArUco corners),
|
||||
// aborting the whole calibration. Auto-prune the offending view (its index is
|
||||
// reported in the exception message) and retry until it succeeds, keeping the
|
||||
// CHECK_COND safety without discarding every good view.
|
||||
const int minFisheyeViews = COUNT_MIN/2;
|
||||
bool calibrated = false;
|
||||
while(!calibrated)
|
||||
{
|
||||
rms = cv::fisheye::calibrate(
|
||||
objectPoints_[id],
|
||||
imagePoints_[id],
|
||||
imageSize_[id],
|
||||
K,
|
||||
D,
|
||||
rvecs,
|
||||
tvecs,
|
||||
cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC |
|
||||
cv::fisheye::CALIB_CHECK_COND |
|
||||
cv::fisheye::CALIB_FIX_SKEW);
|
||||
}
|
||||
catch(const cv::Exception & e)
|
||||
{
|
||||
UERROR("Error: %s (try restarting the calibration)", e.what());
|
||||
QMessageBox::warning(this, tr("Calibration failed!"), tr("Error: %1 (try restarting the calibration)").arg(e.what()));
|
||||
processingData_ = false;
|
||||
return;
|
||||
try
|
||||
{
|
||||
rms = cv::fisheye::calibrate(
|
||||
objectPoints_[id],
|
||||
imagePoints_[id],
|
||||
imageSize_[id],
|
||||
K,
|
||||
D,
|
||||
rvecs,
|
||||
tvecs,
|
||||
cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC |
|
||||
cv::fisheye::CALIB_CHECK_COND |
|
||||
cv::fisheye::CALIB_FIX_SKEW);
|
||||
calibrated = true;
|
||||
}
|
||||
catch(const cv::Exception & e)
|
||||
{
|
||||
// Parse the ill-conditioned view index, e.g.
|
||||
// "CALIB_CHECK_COND - Ill-conditioned matrix for input array 43"
|
||||
int badIndex = -1;
|
||||
const QString token = "input array ";
|
||||
QString msg = e.what();
|
||||
int tokenPos = msg.indexOf(token);
|
||||
if(tokenPos >= 0)
|
||||
{
|
||||
bool ok = false;
|
||||
int v = msg.mid(tokenPos + token.length()).section(' ', 0, 0).toInt(&ok);
|
||||
if(ok)
|
||||
{
|
||||
badIndex = v;
|
||||
}
|
||||
}
|
||||
|
||||
if(badIndex >= 0 && badIndex < (int)objectPoints_[id].size() &&
|
||||
(int)objectPoints_[id].size() > minFisheyeViews)
|
||||
{
|
||||
int removedImageId = badIndex < (int)imageIds_[id].size() ? imageIds_[id][badIndex] : -1;
|
||||
UWARN("Fisheye calibration: view %d (image %d) is ill-conditioned, "
|
||||
"removing it and retrying (%d views left).",
|
||||
badIndex, removedImageId, (int)objectPoints_[id].size()-1);
|
||||
logStream << "Fisheye calibration: removed ill-conditioned view " << badIndex
|
||||
<< " (image " << removedImageId << "), "
|
||||
<< (int)objectPoints_[id].size()-1 << " views left" << ENDL;
|
||||
|
||||
// Keep objectPoints_/imagePoints_/imageIds_ aligned: the per-view
|
||||
// reprojection loop below indexes them together with rvecs/tvecs.
|
||||
objectPoints_[id].erase(objectPoints_[id].begin()+badIndex);
|
||||
imagePoints_[id].erase(imagePoints_[id].begin()+badIndex);
|
||||
if(badIndex < (int)imageIds_[id].size())
|
||||
{
|
||||
imageIds_[id].erase(imageIds_[id].begin()+badIndex);
|
||||
}
|
||||
// loop and retry with the pruned set
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("Error: %s (try restarting the calibration)", e.what());
|
||||
QMessageBox::warning(this, tr("Calibration failed!"), tr("Error: %1 (try restarting the calibration)").arg(e.what()));
|
||||
processingData_ = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1580,9 +1636,14 @@ void CalibrationDialog::calibrate()
|
||||
cv::Mat P = stereoModel_.right().P().clone();
|
||||
P.at<double>(0,3) = -P.at<double>(0,0)*ui_->doubleSpinBox_stereoBaseline->value();
|
||||
double scale = ui_->doubleSpinBox_stereoBaseline->value() / stereoModel_.baseline();
|
||||
UWARN("Scale %f (setting square size from %f to %f)", scale, ui_->doubleSpinBox_squareSize->value(), ui_->doubleSpinBox_squareSize->value()*scale);
|
||||
logStream << "Baseline rescaled from " << stereoModel_.baseline() << " to " << ui_->doubleSpinBox_stereoBaseline->value() << " scale=" << scale << ENDL;
|
||||
ui_->doubleSpinBox_squareSize->setValue(ui_->doubleSpinBox_squareSize->value()*scale);
|
||||
UWARN("Scale %f applied to stereo baseline (computed %f m -> expected %f m). "
|
||||
"If the mismatch is caused by the measured square size, it would be %f m instead of %f m.",
|
||||
scale, stereoModel_.baseline(), ui_->doubleSpinBox_stereoBaseline->value(),
|
||||
ui_->doubleSpinBox_squareSize->value()*scale, ui_->doubleSpinBox_squareSize->value());
|
||||
logStream << "Baseline rescaled from " << stereoModel_.baseline() << " to " << ui_->doubleSpinBox_stereoBaseline->value()
|
||||
<< " scale=" << scale << " (implied square size " << ui_->doubleSpinBox_squareSize->value()*scale
|
||||
<< " m instead of " << ui_->doubleSpinBox_squareSize->value() << " m)" << ENDL;
|
||||
UASSERT(!stereoModel_.T().empty());
|
||||
stereoModel_ = StereoCameraModel(
|
||||
stereoModel_.name(),
|
||||
stereoModel_.left().imageSize(),stereoModel_.left().K_raw(), stereoModel_.left().D_raw(), stereoModel_.left().R(), stereoModel_.left().P(),
|
||||
@@ -1712,26 +1773,58 @@ StereoCameraModel CalibrationDialog::stereoCalibration(const CameraModel & left,
|
||||
cv::Vec4d D_right(right.D_raw().at<double>(0,0), right.D_raw().at<double>(0,1), right.D_raw().at<double>(0,4), right.D_raw().at<double>(0,5));
|
||||
|
||||
UASSERT(stereoImagePoints_[0].size() == stereoImagePoints_[1].size());
|
||||
UASSERT(stereoObjectPoints_.size() == stereoImagePoints_[0].size());
|
||||
// cv::fisheye::stereoCalibrate() reads the number of points from the first view and
|
||||
// lays out its Jacobian assuming EVERY view has that same count (fisheye.cpp
|
||||
// "reshape(1, n_points*2)"). ChArUco detects a variable number of corners per view,
|
||||
// so we make the counts uniform by evenly subsampling every view down to the common
|
||||
// minimum count (kept spatially spread, not just the first N).
|
||||
size_t minPoints = stereoImagePoints_[0][0].size();
|
||||
for(unsigned int i =0; i<stereoImagePoints_[0].size(); ++i)
|
||||
{
|
||||
minPoints = std::min(minPoints, stereoImagePoints_[0][i].size());
|
||||
}
|
||||
std::vector<std::vector<cv::Point3d> > objectPoints(stereoObjectPoints_.size());
|
||||
std::vector<std::vector<cv::Point2d> > leftPoints(stereoImagePoints_[0].size());
|
||||
std::vector<std::vector<cv::Point2d> > rightPoints(stereoImagePoints_[1].size());
|
||||
bool subsampled = false;
|
||||
for(unsigned int i =0; i<stereoImagePoints_[0].size(); ++i)
|
||||
{
|
||||
UASSERT(stereoImagePoints_[0][i].size() == stereoImagePoints_[1][i].size());
|
||||
leftPoints[i].resize(stereoImagePoints_[0][i].size());
|
||||
rightPoints[i].resize(stereoImagePoints_[1][i].size());
|
||||
for(unsigned int j =0; j<stereoImagePoints_[0][i].size(); ++j)
|
||||
UASSERT(stereoObjectPoints_[i].size() == stereoImagePoints_[0][i].size());
|
||||
const size_t n = stereoImagePoints_[0][i].size();
|
||||
if(n != minPoints)
|
||||
{
|
||||
leftPoints[i][j].x = stereoImagePoints_[0][i][j].x;
|
||||
leftPoints[i][j].y = stereoImagePoints_[0][i][j].y;
|
||||
rightPoints[i][j].x = stereoImagePoints_[1][i][j].x;
|
||||
rightPoints[i][j].y = stereoImagePoints_[1][i][j].y;
|
||||
subsampled = true;
|
||||
}
|
||||
objectPoints[i].resize(minPoints);
|
||||
leftPoints[i].resize(minPoints);
|
||||
rightPoints[i].resize(minPoints);
|
||||
for(size_t k =0; k<minPoints; ++k)
|
||||
{
|
||||
// evenly spread the kept indices over [0, n-1]
|
||||
size_t j = minPoints>1 ? (size_t)((k*(n-1))/(minPoints-1)) : 0;
|
||||
objectPoints[i][k].x = stereoObjectPoints_[i][j].x;
|
||||
objectPoints[i][k].y = stereoObjectPoints_[i][j].y;
|
||||
objectPoints[i][k].z = stereoObjectPoints_[i][j].z;
|
||||
leftPoints[i][k].x = stereoImagePoints_[0][i][j].x;
|
||||
leftPoints[i][k].y = stereoImagePoints_[0][i][j].y;
|
||||
rightPoints[i][k].x = stereoImagePoints_[1][i][j].x;
|
||||
rightPoints[i][k].y = stereoImagePoints_[1][i][j].y;
|
||||
}
|
||||
}
|
||||
if(subsampled)
|
||||
{
|
||||
UWARN("Fisheye stereo calibration requires the same number of points in every "
|
||||
"view; sub-sampled all %d views to the common minimum of %d points.",
|
||||
(int)stereoImagePoints_[0].size(), (int)minPoints);
|
||||
if(logStream) (*logStream) << "Fisheye stereo: sub-sampled all views to " << (int)minPoints << " points" << ENDL;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
rms = cv::fisheye::stereoCalibrate(
|
||||
stereoObjectPoints_,
|
||||
objectPoints,
|
||||
leftPoints,
|
||||
rightPoints,
|
||||
left.K_raw(), D_left, right.K_raw(), D_right,
|
||||
@@ -1743,12 +1836,21 @@ StereoCameraModel CalibrationDialog::stereoCalibration(const CameraModel & left,
|
||||
catch(const cv::Exception & e)
|
||||
{
|
||||
UERROR("Error: %s (try restarting the calibration)", e.what());
|
||||
QMessageBox::warning(const_cast<CalibrationDialog*>(this), tr("Calibration failed!"), tr("Error: %1 (try restarting the calibration)").arg(e.what()));
|
||||
return output;
|
||||
}
|
||||
|
||||
std::cout << "R = " << R << std::endl;
|
||||
std::cout << "T = " << Tvec << std::endl;
|
||||
|
||||
// cv::fisheye::stereoCalibrate() returns the translation as a Vec3d (Tvec) and does
|
||||
// not fill the cv::Mat T; populate it here so the returned model always carries a
|
||||
// valid 3x1 extrinsic translation (used e.g. by the baseline rescaling below).
|
||||
T = cv::Mat(3, 1, CV_64FC1);
|
||||
T.at<double>(0,0) = Tvec[0];
|
||||
T.at<double>(1,0) = Tvec[1];
|
||||
T.at<double>(2,0) = Tvec[2];
|
||||
|
||||
if(imageSize_[0] == imageSize_[1] && !ignoreStereoRectification)
|
||||
{
|
||||
UINFO("Compute stereo rectification");
|
||||
@@ -1797,11 +1899,6 @@ StereoCameraModel CalibrationDialog::stereoCalibration(const CameraModel & left,
|
||||
std::cout << "P1n = " << P1 << std::endl;
|
||||
std::cout << "P2n = " << P2 << std::endl;
|
||||
|
||||
|
||||
cv::Mat T(3,1,CV_64FC1);
|
||||
T.at <double>(0,0) = Tvec[0];
|
||||
T.at <double>(1,0) = Tvec[1];
|
||||
T.at <double>(2,0) = Tvec[2];
|
||||
output = StereoCameraModel(
|
||||
cameraName_.toStdString(),
|
||||
imageSize_[0], left.K_raw(), left.D_raw(), R1, P1,
|
||||
|
||||
@@ -85,7 +85,7 @@ CameraViewer::CameraViewer(QWidget * parent, const ParametersMap & parameters) :
|
||||
showScanCheckbox_->setChecked(true);
|
||||
|
||||
markerCheckbox_ = new QCheckBox("Detect markers", this);
|
||||
#if defined(HAVE_OPENCV_ARUCO) || defined(RTABMAP_APRILTAG)
|
||||
#if ((CV_MAJOR_VERSION > 4 || (CV_MAJOR_VERSION==4 && CV_MINOR_VERSION >=7)) && defined(HAVE_OPENCV_OBJDETECT)) || defined(HAVE_OPENCV_ARUCO) || defined(RTABMAP_APRILTAG)
|
||||
markerCheckbox_->setEnabled(true);
|
||||
markerDetector_ = new MarkerDetector(parameters);
|
||||
#else
|
||||
@@ -175,7 +175,8 @@ void CameraViewer::showImage(const rtabmap::SensorData & data)
|
||||
if(!models.empty() && models[0].isValidForProjection())
|
||||
{
|
||||
cv::Mat imageWithDetections;
|
||||
detections = markerDetector_->detect(left, models, depthOrRight, _landmarksSize, &imageWithDetections);
|
||||
cv::Mat depth = (depthOrRight.type()==CV_16UC1 || depthOrRight.type()==CV_32FC1) ? depthOrRight : cv::Mat();
|
||||
detections = markerDetector_->detect(left, models, depth, _landmarksSize, &imageWithDetections);
|
||||
imageView_->setImage(uCvMat2QImage(imageWithDetections));
|
||||
for(std::map<int, MarkerInfo>::iterator iter=detections.begin(); iter!=detections.end(); ++iter)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef RTABMAP_GUILIB_SRC_GUIUTIL_H_
|
||||
#define RTABMAP_GUILIB_SRC_GUIUTIL_H_
|
||||
|
||||
#include <QWidget>
|
||||
#include <QApplication>
|
||||
#include <QEventLoop>
|
||||
#include <QElapsedTimer>
|
||||
#include <QtGui/QWindow>
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
// Show a widget and block until it is actually painted on screen. show() only
|
||||
// schedules window mapping + painting
|
||||
inline void showAndWaitExposed(QWidget * widget)
|
||||
{
|
||||
widget->show();
|
||||
if(widget->windowHandle())
|
||||
{
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
while(!widget->windowHandle()->isExposed() && timer.elapsed() < 2000)
|
||||
{
|
||||
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents, 50);
|
||||
}
|
||||
}
|
||||
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
widget->repaint(); // synchronous, unlike update()
|
||||
}
|
||||
|
||||
} // namespace rtabmap
|
||||
|
||||
#endif /* RTABMAP_GUILIB_SRC_GUIUTIL_H_ */
|
||||
@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "rtabmap/gui/MainWindow.h"
|
||||
|
||||
#include "ui_mainWindow.h"
|
||||
#include "GuiUtil.h"
|
||||
|
||||
#include "rtabmap/core/CameraRGB.h"
|
||||
#include "rtabmap/core/CameraStereo.h"
|
||||
@@ -129,10 +130,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <rtabmap/core/global_map/GridMap.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENCV_ARUCO
|
||||
#include <opencv2/aruco.hpp>
|
||||
#endif
|
||||
|
||||
#define LOG_FILE_NAME "LogRtabmap.txt"
|
||||
#define SHARE_SHOW_LOG_FILE "share/rtabmap/showlogs.m"
|
||||
#define SHARE_GET_PRECISION_RECALL_FILE "share/rtabmap/getPrecisionRecall.m"
|
||||
@@ -5963,9 +5960,7 @@ void MainWindow::startDetection()
|
||||
progress.setCancelButton(0);
|
||||
progress.setMinimumDuration(0);
|
||||
progress.setValue(0);
|
||||
progress.show();
|
||||
QApplication::processEvents();
|
||||
QApplication::processEvents(); // make sure it is drawn
|
||||
showAndWaitExposed(&progress);
|
||||
|
||||
if(_preferencesDialog->getLidarSourceDriver() != PreferencesDialog::kSrcUndef)
|
||||
{
|
||||
@@ -6279,9 +6274,7 @@ void MainWindow::stopDetection()
|
||||
progress.setCancelButton(0);
|
||||
progress.setMinimumDuration(0);
|
||||
progress.setValue(0);
|
||||
progress.show();
|
||||
QApplication::processEvents();
|
||||
QApplication::processEvents(); // make sure it is drawn
|
||||
showAndWaitExposed(&progress);
|
||||
}
|
||||
|
||||
// kill the processes
|
||||
|
||||
@@ -61,6 +61,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <QMainWindow>
|
||||
#include <QProgressDialog>
|
||||
#include <QApplication>
|
||||
#include <QEventLoop>
|
||||
#include <QElapsedTimer>
|
||||
#include <QtGui/QWindow>
|
||||
#include <QLabel>
|
||||
#include <functional>
|
||||
#include <QScrollBar>
|
||||
@@ -70,6 +73,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <QtGui/QCloseEvent>
|
||||
|
||||
#include "ui_preferencesDialog.h"
|
||||
#include "GuiUtil.h"
|
||||
|
||||
#include "rtabmap/core/Version.h"
|
||||
#include "rtabmap/core/Parameters.h"
|
||||
@@ -506,10 +510,10 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
_ui->checkBox_showOdomFrustums->setChecked(false);
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_OPENCV_ARUCO) && !defined(RTABMAP_APRILTAG)
|
||||
#if !((CV_MAJOR_VERSION > 4 || (CV_MAJOR_VERSION==4 && CV_MINOR_VERSION >=7)) && defined(HAVE_OPENCV_OBJDETECT)) && !defined(HAVE_OPENCV_ARUCO) && !defined(RTABMAP_APRILTAG)
|
||||
_ui->label_markerDetection->setText(_ui->label_markerDetection->text()+" This option works only if OpenCV has been built with \"aruco\" module and/or RTAB-Map has been built with AprilTag library support.");
|
||||
#endif
|
||||
#ifndef HAVE_OPENCV_ARUCO
|
||||
#if !(((CV_MAJOR_VERSION > 4 || (CV_MAJOR_VERSION==4 && CV_MINOR_VERSION >=7)) && defined(HAVE_OPENCV_OBJDETECT)) || defined(HAVE_OPENCV_ARUCO))
|
||||
_ui->MarkerStrategy->setItemData(0, 0, Qt::UserRole - 1);
|
||||
#endif
|
||||
#ifndef RTABMAP_APRILTAG
|
||||
@@ -7846,9 +7850,7 @@ void PreferencesDialog::testOdometry()
|
||||
progress.setCancelButton(0);
|
||||
progress.setMinimumDuration(0);
|
||||
progress.setValue(0);
|
||||
progress.show();
|
||||
QApplication::processEvents();
|
||||
QApplication::processEvents(); // make sure it is drawn
|
||||
showAndWaitExposed(&progress);
|
||||
|
||||
Camera * camera = this->createCamera();
|
||||
progress.hide();
|
||||
@@ -7989,9 +7991,7 @@ void PreferencesDialog::testOdometry()
|
||||
// at function scope end (not in join()), so 'progress' stays visible across it. On Windows
|
||||
// the first 2-3 RealSense closes per launch stall ~20s in the Motion Module stop().
|
||||
progress.setLabelText(tr("Closing camera..."));
|
||||
progress.show();
|
||||
QApplication::processEvents();
|
||||
QApplication::processEvents(); // make sure it is drawn
|
||||
showAndWaitExposed(&progress);
|
||||
cameraThread.join(true);
|
||||
odomThread.join(true);
|
||||
|
||||
@@ -8033,9 +8033,7 @@ void PreferencesDialog::testCamera()
|
||||
progress.setCancelButton(0);
|
||||
progress.setMinimumDuration(0);
|
||||
progress.setValue(0);
|
||||
progress.show();
|
||||
QApplication::processEvents();
|
||||
QApplication::processEvents(); // make sure it is drawn
|
||||
showAndWaitExposed(&progress);
|
||||
|
||||
// createCamera() init()s the device on the GUI thread (required by ZED) and takes a few seconds.
|
||||
Camera * camera = this->createCamera();
|
||||
@@ -8092,9 +8090,7 @@ void PreferencesDialog::testCamera()
|
||||
// stays visible across it. On Windows the first 2-3 RealSense closes per launch stall
|
||||
// ~20s in the Motion Module stop() (librealsense warm-up); this keeps the user informed.
|
||||
progress.setLabelText(tr("Closing camera..."));
|
||||
progress.show();
|
||||
QApplication::processEvents();
|
||||
QApplication::processEvents(); // make sure it is drawn
|
||||
showAndWaitExposed(&progress);
|
||||
cameraThread.join(true); // cameraThread's destructor (scope end) closes the device
|
||||
// deleteLater() (not delete): defer destruction to the event loop so Qt finishes
|
||||
// tearing down the OpenGL widget's context and window-proc subclass and drains
|
||||
@@ -8582,9 +8578,7 @@ void PreferencesDialog::testLidar()
|
||||
progress.setCancelButton(0);
|
||||
progress.setMinimumDuration(0);
|
||||
progress.setValue(0);
|
||||
progress.show();
|
||||
QApplication::processEvents();
|
||||
QApplication::processEvents(); // make sure it is drawn
|
||||
showAndWaitExposed(&progress);
|
||||
|
||||
Lidar * lidar = this->createLidar();
|
||||
progress.hide();
|
||||
@@ -8613,9 +8607,7 @@ void PreferencesDialog::testLidar()
|
||||
// destructor at scope end (not in join()), so 'progress' - declared in the outer
|
||||
// scope - stays visible across it.
|
||||
progress.setLabelText(tr("Closing sensor..."));
|
||||
progress.show();
|
||||
QApplication::processEvents();
|
||||
QApplication::processEvents(); // make sure it is drawn
|
||||
showAndWaitExposed(&progress);
|
||||
lidarThread.join(true); // lidarThread's destructor (scope end) closes the device
|
||||
// deleteLater() (not delete): see testCamera() - avoids a dangling OpenGL platform
|
||||
// window that crashes in QWindowsWindow::alertWindow when Preferences later closes.
|
||||
|
||||
@@ -345,10 +345,10 @@
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
<string>Number of inner squares on the board</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Square Size</string>
|
||||
<string>Board Size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -385,10 +385,10 @@
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="toolTip">
|
||||
<string>Number of inner squares on the board</string>
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Board Size</string>
|
||||
<string>Square Size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
Reference in New Issue
Block a user