mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-13 23:10:20 +08:00
Updated ImageView with GraphicsView mode disabled by default. Updated DataRecorder.
This commit is contained in:
@@ -34,6 +34,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <rtabmap/core/SensorData.h>
|
#include <rtabmap/core/SensorData.h>
|
||||||
#include <rtabmap/utilite/UTimer.h>
|
#include <rtabmap/utilite/UTimer.h>
|
||||||
|
#include <rtabmap/utilite/UMutex.h>
|
||||||
|
|
||||||
|
class QLabel;
|
||||||
|
|
||||||
namespace rtabmap {
|
namespace rtabmap {
|
||||||
|
|
||||||
@@ -55,17 +58,21 @@ public:
|
|||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void addData(const rtabmap::SensorData & data);
|
void addData(const rtabmap::SensorData & data);
|
||||||
void showImage(const rtabmap::SensorData & data);
|
void showImage(const cv::Mat & image, const cv::Mat & depth);
|
||||||
protected:
|
protected:
|
||||||
virtual void closeEvent(QCloseEvent* event);
|
virtual void closeEvent(QCloseEvent* event);
|
||||||
void handleEvent(UEvent * event);
|
void handleEvent(UEvent * event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
UMutex memoryMutex_;
|
||||||
Memory * memory_;
|
Memory * memory_;
|
||||||
ImageView* imageView_;
|
ImageView* imageView_;
|
||||||
|
QLabel* label_;
|
||||||
UTimer timer_;
|
UTimer timer_;
|
||||||
int dataQueue_;
|
|
||||||
QString path_;
|
QString path_;
|
||||||
|
bool processingImages_;
|
||||||
|
int count_;
|
||||||
|
int totalSizeKB_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace rtabmap */
|
} /* namespace rtabmap */
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace rtabmap {
|
|||||||
|
|
||||||
class KeypointItem;
|
class KeypointItem;
|
||||||
|
|
||||||
class RTABMAPGUI_EXP ImageView : public QGraphicsView {
|
class RTABMAPGUI_EXP ImageView : public QWidget {
|
||||||
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@@ -55,48 +55,57 @@ public:
|
|||||||
void saveSettings(QSettings & settings, const QString & group = "") const;
|
void saveSettings(QSettings & settings, const QString & group = "") const;
|
||||||
void loadSettings(QSettings & settings, const QString & group = "");
|
void loadSettings(QSettings & settings, const QString & group = "");
|
||||||
|
|
||||||
void resetZoom();
|
|
||||||
|
|
||||||
bool isImageShown() const;
|
bool isImageShown() const;
|
||||||
bool isImageDepthShown() const;
|
bool isImageDepthShown() const;
|
||||||
bool isFeaturesShown() const;
|
bool isFeaturesShown() const;
|
||||||
bool isLinesShown() const;
|
bool isLinesShown() const;
|
||||||
int getAlpha() const {return _alpha;}
|
int getAlpha() const {return _alpha;}
|
||||||
|
bool isGraphicsViewMode() const;
|
||||||
|
bool isGraphicsViewScaled() const;
|
||||||
|
|
||||||
|
float viewScale() const;
|
||||||
|
|
||||||
void setFeaturesShown(bool shown);
|
void setFeaturesShown(bool shown);
|
||||||
void setImageShown(bool shown);
|
void setImageShown(bool shown);
|
||||||
void setImageDepthShown(bool shown);
|
void setImageDepthShown(bool shown);
|
||||||
void setLinesShown(bool shown);
|
void setLinesShown(bool shown);
|
||||||
|
void setGraphicsViewMode(bool on);
|
||||||
|
void setGraphicsViewScaled(bool scaled);
|
||||||
|
void setBackgroundColor(const QColor & color);
|
||||||
|
|
||||||
void setFeatures(const std::multimap<int, cv::KeyPoint> & refWords, const QColor & color = QColor(255, 255, 0, 70));
|
void setFeatures(const std::multimap<int, cv::KeyPoint> & refWords, const QColor & color = Qt::yellow);
|
||||||
void setFeatures(const std::vector<cv::KeyPoint> & features, const QColor & color = QColor(255, 255, 0, 70));
|
void setFeatures(const std::vector<cv::KeyPoint> & features, const QColor & color = Qt::yellow);
|
||||||
|
void addFeature(int id, const cv::KeyPoint & kpt, QColor color);
|
||||||
|
void addLine(float x1, float y1, float x2, float y2, QColor color);
|
||||||
void setImage(const QImage & image);
|
void setImage(const QImage & image);
|
||||||
void setImageDepth(const QImage & image);
|
void setImageDepth(const QImage & image);
|
||||||
void setFeatureColor(int id, const QColor & color);
|
void setFeatureColor(int id, QColor color);
|
||||||
void setFeaturesColor(const QColor & color);
|
void setFeaturesColor(QColor color);
|
||||||
void setAlpha(int alpha);
|
void setAlpha(int alpha);
|
||||||
|
void setSceneRect(const QRectF & rect);
|
||||||
|
|
||||||
const QMultiMap<int, rtabmap::KeypointItem *> & getFeatures() const {return _features;}
|
const QMultiMap<int, rtabmap::KeypointItem *> & getFeatures() const {return _features;}
|
||||||
|
|
||||||
void clearLines();
|
void clearLines();
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
virtual QSize sizeHint() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void configChanged();
|
void configChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual void paintEvent(QPaintEvent *event);
|
||||||
|
virtual void resizeEvent(QResizeEvent* event);
|
||||||
virtual void contextMenuEvent(QContextMenuEvent * e);
|
virtual void contextMenuEvent(QContextMenuEvent * e);
|
||||||
virtual void wheelEvent(QWheelEvent * e);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void updateZoom();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateOpacity();
|
void updateOpacity();
|
||||||
|
void computeScaleOffsets(float & scale, float & offsetX, float & offsetY) const;
|
||||||
|
void drawFeatures(QPainter * painter);
|
||||||
|
void drawLines(QPainter * painter);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _zoom;
|
|
||||||
int _minZoom;
|
|
||||||
QString _savedFileName;
|
QString _savedFileName;
|
||||||
int _alpha;
|
int _alpha;
|
||||||
|
|
||||||
@@ -107,10 +116,16 @@ private:
|
|||||||
QAction * _showLines;
|
QAction * _showLines;
|
||||||
QAction * _saveImage;
|
QAction * _saveImage;
|
||||||
QAction * _setAlpha;
|
QAction * _setAlpha;
|
||||||
|
QAction * _graphicsViewMode;
|
||||||
|
QAction * _graphicsViewScaled;
|
||||||
|
|
||||||
|
QGraphicsView * _graphicsView;
|
||||||
QMultiMap<int, rtabmap::KeypointItem *> _features;
|
QMultiMap<int, rtabmap::KeypointItem *> _features;
|
||||||
QGraphicsPixmapItem * _image;
|
QList<QGraphicsLineItem*> _lines;
|
||||||
QGraphicsPixmapItem * _imageDepth;
|
QGraphicsPixmapItem * _imageItem;
|
||||||
|
QGraphicsPixmapItem * _imageDepthItem;
|
||||||
|
QPixmap _image;
|
||||||
|
QPixmap _imageDepth;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,13 +34,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <QGraphicsTextItem>
|
#include <QGraphicsTextItem>
|
||||||
#include <QtGui/QPen>
|
#include <QtGui/QPen>
|
||||||
#include <QtGui/QBrush>
|
#include <QtGui/QBrush>
|
||||||
|
#include <opencv2/features2d/features2d.hpp>
|
||||||
|
|
||||||
namespace rtabmap {
|
namespace rtabmap {
|
||||||
|
|
||||||
class RTABMAPGUI_EXP KeypointItem : public QGraphicsEllipseItem
|
class RTABMAPGUI_EXP KeypointItem : public QGraphicsEllipseItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
KeypointItem(qreal x, qreal y, int r, const QString & info, const QColor & color = Qt::green, QGraphicsItem * parent = 0);
|
KeypointItem(int id, const cv::KeyPoint & kpt, const QColor & color = Qt::green, QGraphicsItem * parent = 0);
|
||||||
virtual ~KeypointItem();
|
virtual ~KeypointItem();
|
||||||
|
|
||||||
void setColor(const QColor & color);
|
void setColor(const QColor & color);
|
||||||
@@ -56,7 +57,8 @@ private:
|
|||||||
void hideDescription();
|
void hideDescription();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString _info;
|
int _id;
|
||||||
|
cv::KeyPoint _kpt;
|
||||||
QGraphicsRectItem * _placeHolder;
|
QGraphicsRectItem * _placeHolder;
|
||||||
int _width;
|
int _width;
|
||||||
};
|
};
|
||||||
|
|||||||
+46
-27
@@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <rtabmap/utilite/ULogger.h>
|
#include <rtabmap/utilite/ULogger.h>
|
||||||
#include <rtabmap/utilite/UTimer.h>
|
#include <rtabmap/utilite/UTimer.h>
|
||||||
#include <rtabmap/core/Memory.h>
|
#include <rtabmap/core/Memory.h>
|
||||||
|
#include <rtabmap/core/Signature.h>
|
||||||
#include <rtabmap/core/CameraEvent.h>
|
#include <rtabmap/core/CameraEvent.h>
|
||||||
#include <rtabmap/core/util3d.h>
|
#include <rtabmap/core/util3d.h>
|
||||||
#include <rtabmap/gui/ImageView.h>
|
#include <rtabmap/gui/ImageView.h>
|
||||||
@@ -37,7 +38,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <QtCore/QMetaType>
|
#include <QtCore/QMetaType>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QtGui/QCloseEvent>
|
#include <QtGui/QCloseEvent>
|
||||||
#include <QHBoxLayout>
|
#include <QLabel>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
namespace rtabmap {
|
namespace rtabmap {
|
||||||
|
|
||||||
@@ -46,18 +48,25 @@ DataRecorder::DataRecorder(QWidget * parent) :
|
|||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
memory_(0),
|
memory_(0),
|
||||||
imageView_(new ImageView(this)),
|
imageView_(new ImageView(this)),
|
||||||
dataQueue_(0)
|
label_(new QLabel(this)),
|
||||||
|
processingImages_(false),
|
||||||
|
count_(0),
|
||||||
|
totalSizeKB_(0)
|
||||||
{
|
{
|
||||||
qRegisterMetaType<rtabmap::SensorData>("rtabmap::SensorData");
|
qRegisterMetaType<cv::Mat>("cv::Mat");
|
||||||
|
|
||||||
imageView_->setImageDepthShown(true);
|
imageView_->setImageDepthShown(true);
|
||||||
QHBoxLayout * layout = new QHBoxLayout(this);
|
imageView_->setMinimumSize(320, 240);
|
||||||
|
QVBoxLayout * layout = new QVBoxLayout(this);
|
||||||
layout->setMargin(0);
|
layout->setMargin(0);
|
||||||
layout->addWidget(imageView_);
|
layout->addWidget(imageView_);
|
||||||
|
layout->addWidget(label_);
|
||||||
|
layout->setStretch(0,1);
|
||||||
this->setLayout(layout);
|
this->setLayout(layout);
|
||||||
}
|
}
|
||||||
bool DataRecorder::init(const QString & path, bool recordInRAM)
|
bool DataRecorder::init(const QString & path, bool recordInRAM)
|
||||||
{
|
{
|
||||||
|
UScopeMutex scope(memoryMutex_);
|
||||||
if(!memory_)
|
if(!memory_)
|
||||||
{
|
{
|
||||||
ParametersMap customParameters;
|
ParametersMap customParameters;
|
||||||
@@ -88,11 +97,16 @@ bool DataRecorder::init(const QString & path, bool recordInRAM)
|
|||||||
|
|
||||||
void DataRecorder::closeRecorder()
|
void DataRecorder::closeRecorder()
|
||||||
{
|
{
|
||||||
|
memoryMutex_.lock();
|
||||||
if(memory_)
|
if(memory_)
|
||||||
{
|
{
|
||||||
delete memory_;
|
delete memory_;
|
||||||
memory_ = 0;
|
memory_ = 0;
|
||||||
}
|
}
|
||||||
|
memoryMutex_.unlock();
|
||||||
|
processingImages_ = false;
|
||||||
|
count_ = 0;
|
||||||
|
totalSizeKB_ = 0;
|
||||||
UINFO("Data recorded to \"%s\".", this->path().toStdString().c_str());
|
UINFO("Data recorded to \"%s\".", this->path().toStdString().c_str());
|
||||||
if(this->isVisible())
|
if(this->isVisible())
|
||||||
{
|
{
|
||||||
@@ -102,36 +116,39 @@ void DataRecorder::closeRecorder()
|
|||||||
|
|
||||||
DataRecorder::~DataRecorder()
|
DataRecorder::~DataRecorder()
|
||||||
{
|
{
|
||||||
|
this->unregisterFromEventsManager();
|
||||||
this->closeRecorder();
|
this->closeRecorder();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataRecorder::addData(const rtabmap::SensorData & data)
|
void DataRecorder::addData(const rtabmap::SensorData & data)
|
||||||
{
|
{
|
||||||
|
memoryMutex_.lock();
|
||||||
if(memory_)
|
if(memory_)
|
||||||
{
|
{
|
||||||
//save to database
|
//save to database
|
||||||
UTimer time;
|
UTimer time;
|
||||||
memory_->update(data);
|
memory_->update(data);
|
||||||
|
const Signature * s = memory_->getLastWorkingSignature();
|
||||||
|
totalSizeKB_ += s->getImageCompressed().total()/1000;
|
||||||
|
totalSizeKB_ += s->getDepthCompressed().total()/1000;
|
||||||
memory_->cleanup();
|
memory_->cleanup();
|
||||||
|
|
||||||
if(data.id() % 30)
|
if(++count_ % 30)
|
||||||
{
|
{
|
||||||
memory_->emptyTrash();
|
memory_->emptyTrash();
|
||||||
}
|
}
|
||||||
|
|
||||||
UDEBUG("Time to process a message = %f s", time.ticks());
|
UDEBUG("Time to process a message = %f s", time.ticks());
|
||||||
}
|
}
|
||||||
--dataQueue_;
|
memoryMutex_.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataRecorder::showImage(const rtabmap::SensorData & data)
|
void DataRecorder::showImage(const cv::Mat & image, const cv::Mat & depth)
|
||||||
{
|
{
|
||||||
if(this->isVisible() && data.isValid())
|
processingImages_ = true;
|
||||||
{
|
imageView_->setImage(uCvMat2QImage(image));
|
||||||
imageView_->setImage(uCvMat2QImage(data.image()));
|
imageView_->setImageDepth(uCvMat2QImage(depth));
|
||||||
imageView_->setImageDepth(uCvMat2QImage(data.depth()));
|
label_->setText(tr("Images=%1 (~%2 MB)").arg(count_).arg(totalSizeKB_/1000));
|
||||||
imageView_->fitInView(imageView_->sceneRect(), Qt::KeepAspectRatio);
|
processingImages_ = false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataRecorder::closeEvent(QCloseEvent* event)
|
void DataRecorder::closeEvent(QCloseEvent* event)
|
||||||
@@ -142,24 +159,26 @@ void DataRecorder::closeEvent(QCloseEvent* event)
|
|||||||
|
|
||||||
void DataRecorder::handleEvent(UEvent * event)
|
void DataRecorder::handleEvent(UEvent * event)
|
||||||
{
|
{
|
||||||
if(event->getClassName().compare("CameraEvent") == 0)
|
if(memory_)
|
||||||
{
|
{
|
||||||
CameraEvent * camEvent = (CameraEvent*)event;
|
if(event->getClassName().compare("CameraEvent") == 0)
|
||||||
if(camEvent->getCode() == CameraEvent::kCodeImageDepth ||
|
|
||||||
camEvent->getCode() == CameraEvent::kCodeImage)
|
|
||||||
{
|
{
|
||||||
if(camEvent->data().isValid())
|
CameraEvent * camEvent = (CameraEvent*)event;
|
||||||
|
if(camEvent->getCode() == CameraEvent::kCodeImageDepth ||
|
||||||
|
camEvent->getCode() == CameraEvent::kCodeImage)
|
||||||
{
|
{
|
||||||
UINFO("Receiving rate = %f Hz", 1.0f/timer_.ticks());
|
if(camEvent->data().isValid())
|
||||||
if(memory_)
|
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(this, "addData", Q_ARG(rtabmap::SensorData, camEvent->data()));
|
UINFO("Receiving rate = %f Hz", 1.0f/timer_.ticks());
|
||||||
++dataQueue_;
|
this->addData(camEvent->data());
|
||||||
}
|
|
||||||
|
|
||||||
if(dataQueue_ < 2 && this->isVisible())
|
if(!processingImages_ && this->isVisible() && camEvent->data().isValid())
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(this, "showImage", Q_ARG(rtabmap::SensorData, camEvent->data()));
|
processingImages_ = true;
|
||||||
|
QMetaObject::invokeMethod(this, "showImage",
|
||||||
|
Q_ARG(cv::Mat, camEvent->data().image()),
|
||||||
|
Q_ARG(cv::Mat, camEvent->data().depth()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -612,11 +612,6 @@ void DatabaseViewer::closeEvent(QCloseEvent* event)
|
|||||||
|
|
||||||
void DatabaseViewer::showEvent(QShowEvent* anEvent)
|
void DatabaseViewer::showEvent(QShowEvent* anEvent)
|
||||||
{
|
{
|
||||||
ui_->graphicsView_A->fitInView(ui_->graphicsView_A->sceneRect(), Qt::KeepAspectRatio);
|
|
||||||
ui_->graphicsView_B->fitInView(ui_->graphicsView_B->sceneRect(), Qt::KeepAspectRatio);
|
|
||||||
ui_->graphicsView_A->resetZoom();
|
|
||||||
ui_->graphicsView_B->resetZoom();
|
|
||||||
|
|
||||||
this->setWindowModified(false);
|
this->setWindowModified(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,10 +630,6 @@ void DatabaseViewer::moveEvent(QMoveEvent* anEvent)
|
|||||||
|
|
||||||
void DatabaseViewer::resizeEvent(QResizeEvent* anEvent)
|
void DatabaseViewer::resizeEvent(QResizeEvent* anEvent)
|
||||||
{
|
{
|
||||||
ui_->graphicsView_A->fitInView(ui_->graphicsView_A->sceneRect(), Qt::KeepAspectRatio);
|
|
||||||
ui_->graphicsView_B->fitInView(ui_->graphicsView_B->sceneRect(), Qt::KeepAspectRatio);
|
|
||||||
ui_->graphicsView_A->resetZoom();
|
|
||||||
ui_->graphicsView_B->resetZoom();
|
|
||||||
if(this->isVisible())
|
if(this->isVisible())
|
||||||
{
|
{
|
||||||
this->configModified();
|
this->configModified();
|
||||||
@@ -1362,7 +1353,6 @@ void DatabaseViewer::update(int value,
|
|||||||
if(value >= 0 && value < ids_.size())
|
if(value >= 0 && value < ids_.size())
|
||||||
{
|
{
|
||||||
view->clear();
|
view->clear();
|
||||||
view->resetTransform();
|
|
||||||
int id = ids_.at(value);
|
int id = ids_.at(value);
|
||||||
int mapId = -1;
|
int mapId = -1;
|
||||||
labelId->setText(QString::number(id));
|
labelId->setText(QString::number(id));
|
||||||
@@ -1557,11 +1547,6 @@ void DatabaseViewer::update(int value,
|
|||||||
{
|
{
|
||||||
view->setSceneRect(rect);
|
view->setSceneRect(rect);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
view->setSceneRect(view->scene()->itemsBoundingRect());
|
|
||||||
}
|
|
||||||
view->fitInView(view->sceneRect(), Qt::KeepAspectRatio);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseViewer::updateStereo(const Signature * data)
|
void DatabaseViewer::updateStereo(const Signature * data)
|
||||||
@@ -1680,20 +1665,13 @@ void DatabaseViewer::updateStereo(const Signature * data)
|
|||||||
|
|
||||||
//ui_->graphicsView_stereo->setImage(uCvMat2QImage(imageMatches));
|
//ui_->graphicsView_stereo->setImage(uCvMat2QImage(imageMatches));
|
||||||
|
|
||||||
ui_->graphicsView_stereo->scene()->clear();
|
ui_->graphicsView_stereo->clear();
|
||||||
ui_->graphicsView_stereo->setSceneRect(0,0,(float)leftMono.cols, (float)leftMono.rows);
|
|
||||||
ui_->graphicsView_stereo->setLinesShown(true);
|
ui_->graphicsView_stereo->setLinesShown(true);
|
||||||
ui_->graphicsView_stereo->setFeaturesShown(false);
|
ui_->graphicsView_stereo->setFeaturesShown(false);
|
||||||
|
ui_->graphicsView_stereo->setImageDepthShown(true);
|
||||||
|
|
||||||
QGraphicsPixmapItem * item1 = ui_->graphicsView_stereo->scene()->addPixmap(QPixmap::fromImage(uCvMat2QImage(data->getImageRaw())));
|
ui_->graphicsView_stereo->setImage(uCvMat2QImage(data->getImageRaw()));
|
||||||
QGraphicsPixmapItem * item2 = ui_->graphicsView_stereo->scene()->addPixmap(QPixmap::fromImage(uCvMat2QImage(data->getDepthRaw())));
|
ui_->graphicsView_stereo->setImageDepth(uCvMat2QImage(data->getDepthRaw()));
|
||||||
|
|
||||||
QGraphicsOpacityEffect * effect1 = new QGraphicsOpacityEffect();
|
|
||||||
QGraphicsOpacityEffect * effect2 = new QGraphicsOpacityEffect();
|
|
||||||
effect1->setOpacity(0.5);
|
|
||||||
effect2->setOpacity(0.5);
|
|
||||||
item1->setGraphicsEffect(effect1);
|
|
||||||
item2->setGraphicsEffect(effect2);
|
|
||||||
|
|
||||||
// Draw lines between corresponding features...
|
// Draw lines between corresponding features...
|
||||||
for(unsigned int i=0; i<kpts.size(); ++i)
|
for(unsigned int i=0; i<kpts.size(); ++i)
|
||||||
@@ -1715,14 +1693,14 @@ void DatabaseViewer::updateStereo(const Signature * data)
|
|||||||
{
|
{
|
||||||
c = Qt::magenta;
|
c = Qt::magenta;
|
||||||
}
|
}
|
||||||
QGraphicsLineItem * item = ui_->graphicsView_stereo->scene()->addLine(
|
ui_->graphicsView_stereo->addLine(
|
||||||
kpts[i].pt.x,
|
kpts[i].pt.x,
|
||||||
kpts[i].pt.y,
|
kpts[i].pt.y,
|
||||||
rightKpts[i].pt.x,
|
rightKpts[i].pt.x,
|
||||||
rightKpts[i].pt.y,
|
rightKpts[i].pt.y,
|
||||||
QPen(c));
|
c);
|
||||||
item->setZValue(1);
|
|
||||||
}
|
}
|
||||||
|
ui_->graphicsView_stereo->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1748,35 +1726,34 @@ void DatabaseViewer::updateWordsMatching()
|
|||||||
if(wordsA.count(ids[i]) == 1 && wordsB.count(ids[i]) == 1)
|
if(wordsA.count(ids[i]) == 1 && wordsB.count(ids[i]) == 1)
|
||||||
{
|
{
|
||||||
// PINK features
|
// PINK features
|
||||||
ui_->graphicsView_A->setFeatureColor(ids[i], QColor(255, 0, 255, alpha));
|
ui_->graphicsView_A->setFeatureColor(ids[i], Qt::magenta);
|
||||||
ui_->graphicsView_B->setFeatureColor(ids[i], QColor(255, 0, 255, alpha));
|
ui_->graphicsView_B->setFeatureColor(ids[i], Qt::magenta);
|
||||||
|
|
||||||
// Add lines
|
// Add lines
|
||||||
// Draw lines between corresponding features...
|
// Draw lines between corresponding features...
|
||||||
float deltaX = ui_->graphicsView_A->sceneRect().width();
|
float scaleX = ui_->graphicsView_A->viewScale();
|
||||||
|
float deltaX = ui_->graphicsView_A->width()/scaleX;
|
||||||
float deltaY = 0;
|
float deltaY = 0;
|
||||||
|
|
||||||
const KeypointItem * kptA = wordsA.value(ids[i]);
|
const KeypointItem * kptA = wordsA.value(ids[i]);
|
||||||
const KeypointItem * kptB = wordsB.value(ids[i]);
|
const KeypointItem * kptB = wordsB.value(ids[i]);
|
||||||
QGraphicsLineItem * item = ui_->graphicsView_A->scene()->addLine(
|
ui_->graphicsView_A->addLine(
|
||||||
kptA->rect().x()+kptA->rect().width()/2,
|
kptA->rect().x()+kptA->rect().width()/2,
|
||||||
kptA->rect().y()+kptA->rect().height()/2,
|
kptA->rect().y()+kptA->rect().height()/2,
|
||||||
kptB->rect().x()+kptB->rect().width()/2+deltaX,
|
kptB->rect().x()+kptB->rect().width()/2+deltaX,
|
||||||
kptB->rect().y()+kptB->rect().height()/2+deltaY,
|
kptB->rect().y()+kptB->rect().height()/2+deltaY,
|
||||||
QPen(QColor(0, 255, 255, alpha)));
|
Qt::cyan);
|
||||||
item->setVisible(ui_->graphicsView_A->isLinesShown());
|
|
||||||
item->setZValue(1);
|
|
||||||
|
|
||||||
item = ui_->graphicsView_B->scene()->addLine(
|
ui_->graphicsView_B->addLine(
|
||||||
kptA->rect().x()+kptA->rect().width()/2-deltaX,
|
kptA->rect().x()+kptA->rect().width()/2-deltaX,
|
||||||
kptA->rect().y()+kptA->rect().height()/2-deltaY,
|
kptA->rect().y()+kptA->rect().height()/2-deltaY,
|
||||||
kptB->rect().x()+kptB->rect().width()/2,
|
kptB->rect().x()+kptB->rect().width()/2,
|
||||||
kptB->rect().y()+kptB->rect().height()/2,
|
kptB->rect().y()+kptB->rect().height()/2,
|
||||||
QPen(QColor(0, 255, 255, alpha)));
|
Qt::cyan);
|
||||||
item->setVisible(ui_->graphicsView_B->isLinesShown());
|
|
||||||
item->setZValue(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ui_->graphicsView_A->update();
|
||||||
|
ui_->graphicsView_B->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+440
-141
@@ -35,23 +35,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QGraphicsEffect>
|
#include <QGraphicsEffect>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
|
#include <QVBoxLayout>
|
||||||
#include "rtabmap/utilite/ULogger.h"
|
#include "rtabmap/utilite/ULogger.h"
|
||||||
#include "rtabmap/gui/KeypointItem.h"
|
#include "rtabmap/gui/KeypointItem.h"
|
||||||
|
|
||||||
namespace rtabmap {
|
namespace rtabmap {
|
||||||
|
|
||||||
ImageView::ImageView(QWidget * parent) :
|
ImageView::ImageView(QWidget * parent) :
|
||||||
QGraphicsView(parent),
|
QWidget(parent),
|
||||||
_zoom(250),
|
|
||||||
_minZoom(250),
|
|
||||||
_savedFileName((QDir::homePath()+ "/") + "picture" + ".png"),
|
_savedFileName((QDir::homePath()+ "/") + "picture" + ".png"),
|
||||||
_alpha(100),
|
_alpha(100),
|
||||||
_image(0),
|
_imageItem(0),
|
||||||
_imageDepth(0)
|
_imageDepthItem(0)
|
||||||
{
|
{
|
||||||
this->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
|
_graphicsView = new QGraphicsView(this);
|
||||||
this->setScene(new QGraphicsScene(this));
|
_graphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
|
||||||
connect(this->scene(), SIGNAL(sceneRectChanged(const QRectF &)), this, SLOT(updateZoom()));
|
_graphicsView->setScene(new QGraphicsScene(this));
|
||||||
|
_graphicsView->setVisible(false);
|
||||||
|
|
||||||
|
this->setLayout(new QVBoxLayout(this));
|
||||||
|
this->layout()->addWidget(_graphicsView);
|
||||||
|
this->layout()->setContentsMargins(0,0,0,0);
|
||||||
|
|
||||||
_menu = new QMenu(tr(""), this);
|
_menu = new QMenu(tr(""), this);
|
||||||
_showImage = _menu->addAction(tr("Show image"));
|
_showImage = _menu->addAction(tr("Show image"));
|
||||||
@@ -66,6 +70,13 @@ ImageView::ImageView(QWidget * parent) :
|
|||||||
_showLines = _menu->addAction(tr("Show lines"));
|
_showLines = _menu->addAction(tr("Show lines"));
|
||||||
_showLines->setCheckable(true);
|
_showLines->setCheckable(true);
|
||||||
_showLines->setChecked(true);
|
_showLines->setChecked(true);
|
||||||
|
_graphicsViewMode = _menu->addAction(tr("Graphics view"));
|
||||||
|
_graphicsViewMode->setCheckable(true);
|
||||||
|
_graphicsViewMode->setChecked(false);
|
||||||
|
_graphicsViewScaled = _menu->addAction(tr("Scale image"));
|
||||||
|
_graphicsViewScaled->setCheckable(true);
|
||||||
|
_graphicsViewScaled->setChecked(true);
|
||||||
|
_graphicsViewScaled->setEnabled(false);
|
||||||
_setAlpha = _menu->addAction(tr("Set alpha..."));
|
_setAlpha = _menu->addAction(tr("Set alpha..."));
|
||||||
_saveImage = _menu->addAction(tr("Save picture..."));
|
_saveImage = _menu->addAction(tr("Save picture..."));
|
||||||
}
|
}
|
||||||
@@ -85,6 +96,8 @@ void ImageView::saveSettings(QSettings & settings, const QString & group) const
|
|||||||
settings.setValue("features_shown", this->isFeaturesShown());
|
settings.setValue("features_shown", this->isFeaturesShown());
|
||||||
settings.setValue("lines_shown", this->isLinesShown());
|
settings.setValue("lines_shown", this->isLinesShown());
|
||||||
settings.setValue("alpha", this->getAlpha());
|
settings.setValue("alpha", this->getAlpha());
|
||||||
|
settings.setValue("graphics_view", this->isGraphicsViewMode());
|
||||||
|
settings.setValue("graphics_view_scale", this->isGraphicsViewScaled());
|
||||||
if(!group.isEmpty())
|
if(!group.isEmpty())
|
||||||
{
|
{
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
@@ -102,18 +115,14 @@ void ImageView::loadSettings(QSettings & settings, const QString & group)
|
|||||||
this->setFeaturesShown(settings.value("features_shown", this->isFeaturesShown()).toBool());
|
this->setFeaturesShown(settings.value("features_shown", this->isFeaturesShown()).toBool());
|
||||||
this->setLinesShown(settings.value("lines_shown", this->isLinesShown()).toBool());
|
this->setLinesShown(settings.value("lines_shown", this->isLinesShown()).toBool());
|
||||||
this->setAlpha(settings.value("alpha", this->getAlpha()).toInt());
|
this->setAlpha(settings.value("alpha", this->getAlpha()).toInt());
|
||||||
|
this->setGraphicsViewMode(settings.value("graphics_view", this->isGraphicsViewMode()).toBool());
|
||||||
|
this->setGraphicsViewScaled(settings.value("graphics_view_scale", this->isGraphicsViewScaled()).toBool());
|
||||||
if(!group.isEmpty())
|
if(!group.isEmpty())
|
||||||
{
|
{
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageView::resetZoom()
|
|
||||||
{
|
|
||||||
_zoom = _minZoom;
|
|
||||||
this->setDragMode(QGraphicsView::NoDrag);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ImageView::isImageShown() const
|
bool ImageView::isImageShown() const
|
||||||
{
|
{
|
||||||
return _showImage->isChecked();
|
return _showImage->isChecked();
|
||||||
@@ -129,6 +138,16 @@ bool ImageView::isFeaturesShown() const
|
|||||||
return _showFeatures->isChecked();
|
return _showFeatures->isChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ImageView::isGraphicsViewMode() const
|
||||||
|
{
|
||||||
|
return _graphicsViewMode->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImageView::isGraphicsViewScaled() const
|
||||||
|
{
|
||||||
|
return _graphicsViewScaled->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
void ImageView::setFeaturesShown(bool shown)
|
void ImageView::setFeaturesShown(bool shown)
|
||||||
{
|
{
|
||||||
_showFeatures->setChecked(shown);
|
_showFeatures->setChecked(shown);
|
||||||
@@ -136,26 +155,41 @@ void ImageView::setFeaturesShown(bool shown)
|
|||||||
{
|
{
|
||||||
iter.value()->setVisible(_showFeatures->isChecked());
|
iter.value()->setVisible(_showFeatures->isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!_graphicsView->isVisible())
|
||||||
|
{
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageView::setImageShown(bool shown)
|
void ImageView::setImageShown(bool shown)
|
||||||
{
|
{
|
||||||
_showImage->setChecked(shown);
|
_showImage->setChecked(shown);
|
||||||
if(_image)
|
if(_imageItem)
|
||||||
{
|
{
|
||||||
_image->setVisible(_showImage->isChecked());
|
_imageItem->setVisible(_showImage->isChecked());
|
||||||
this->updateOpacity();
|
this->updateOpacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!_graphicsView->isVisible())
|
||||||
|
{
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageView::setImageDepthShown(bool shown)
|
void ImageView::setImageDepthShown(bool shown)
|
||||||
{
|
{
|
||||||
_showImageDepth->setChecked(shown);
|
_showImageDepth->setChecked(shown);
|
||||||
if(_imageDepth)
|
if(_imageDepthItem)
|
||||||
{
|
{
|
||||||
_imageDepth->setVisible(_showImageDepth->isChecked());
|
_imageDepthItem->setVisible(_showImageDepth->isChecked());
|
||||||
this->updateOpacity();
|
this->updateOpacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!_graphicsView->isVisible())
|
||||||
|
{
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImageView::isLinesShown() const
|
bool ImageView::isLinesShown() const
|
||||||
@@ -166,13 +200,233 @@ bool ImageView::isLinesShown() const
|
|||||||
void ImageView::setLinesShown(bool shown)
|
void ImageView::setLinesShown(bool shown)
|
||||||
{
|
{
|
||||||
_showLines->setChecked(shown);
|
_showLines->setChecked(shown);
|
||||||
QList<QGraphicsItem*> items = this->scene()->items();
|
for(int i=0; i<_lines.size(); ++i)
|
||||||
for(int i=0; i<items.size(); ++i)
|
|
||||||
{
|
{
|
||||||
if( qgraphicsitem_cast<QGraphicsLineItem*>(items.at(i)))
|
_lines.at(i)->setVisible(_showLines->isChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!_graphicsView->isVisible())
|
||||||
|
{
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float ImageView::viewScale() const
|
||||||
|
{
|
||||||
|
if(_graphicsView->isVisible())
|
||||||
|
{
|
||||||
|
return _graphicsView->transform().m11();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float scale, offsetX, offsetY;
|
||||||
|
computeScaleOffsets(scale, offsetX, offsetY);
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageView::setGraphicsViewMode(bool on)
|
||||||
|
{
|
||||||
|
_graphicsViewMode->setChecked(on);
|
||||||
|
_graphicsView->setVisible(on);
|
||||||
|
_graphicsViewScaled->setEnabled(on);
|
||||||
|
|
||||||
|
if(on)
|
||||||
|
{
|
||||||
|
for(QMultiMap<int, KeypointItem*>::iterator iter=_features.begin(); iter!=_features.end(); ++iter)
|
||||||
{
|
{
|
||||||
items.at(i)->setVisible(_showLines->isChecked());
|
_graphicsView->scene()->addItem(iter.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(QList<QGraphicsLineItem*>::iterator iter=_lines.begin(); iter!=_lines.end(); ++iter)
|
||||||
|
{
|
||||||
|
_graphicsView->scene()->addItem(*iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
//update images
|
||||||
|
if(_imageItem)
|
||||||
|
{
|
||||||
|
_imageItem->setPixmap(_image);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_imageItem = _graphicsView->scene()->addPixmap(_image);
|
||||||
|
_imageItem->setVisible(_showImage->isChecked());
|
||||||
|
_showImage->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_imageDepthItem)
|
||||||
|
{
|
||||||
|
_imageDepthItem->setPixmap(_imageDepth);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_imageDepthItem = _graphicsView->scene()->addPixmap(_imageDepth);
|
||||||
|
_imageDepthItem->setVisible(_showImageDepth->isChecked());
|
||||||
|
_showImageDepth->setEnabled(true);
|
||||||
|
}
|
||||||
|
this->updateOpacity();
|
||||||
|
|
||||||
|
if(_graphicsViewScaled->isChecked())
|
||||||
|
{
|
||||||
|
_graphicsView->fitInView(_graphicsView->sceneRect(), Qt::KeepAspectRatio);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_graphicsView->resetTransform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageView::setGraphicsViewScaled(bool scaled)
|
||||||
|
{
|
||||||
|
_graphicsViewScaled->setChecked(scaled);
|
||||||
|
|
||||||
|
if(scaled)
|
||||||
|
{
|
||||||
|
_graphicsView->fitInView(_graphicsView->sceneRect(), Qt::KeepAspectRatio);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_graphicsView->resetTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!_graphicsView->isVisible())
|
||||||
|
{
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageView::setBackgroundColor(const QColor & color)
|
||||||
|
{
|
||||||
|
_graphicsView->setBackgroundBrush(QBrush(color));
|
||||||
|
|
||||||
|
if(!_graphicsView->isVisible())
|
||||||
|
{
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageView::computeScaleOffsets(float & scale, float & offsetX, float & offsetY) const
|
||||||
|
{
|
||||||
|
scale = 1.0f;
|
||||||
|
offsetX = 0.0f;
|
||||||
|
offsetY = 0.0f;
|
||||||
|
|
||||||
|
if(!_graphicsView->scene()->sceneRect().isNull())
|
||||||
|
{
|
||||||
|
float w = _graphicsView->scene()->width();
|
||||||
|
float h = _graphicsView->scene()->height();
|
||||||
|
float widthRatio = float(this->rect().width()) / w;
|
||||||
|
float heightRatio = float(this->rect().height()) / h;
|
||||||
|
|
||||||
|
//printf("w=%f, h=%f, wR=%f, hR=%f, sW=%d, sH=%d\n", w, h, widthRatio, heightRatio, this->rect().width(), this->rect().height());
|
||||||
|
if(widthRatio < heightRatio)
|
||||||
|
{
|
||||||
|
scale = widthRatio;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scale = heightRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("ratio=%f\n",ratio);
|
||||||
|
|
||||||
|
w *= scale;
|
||||||
|
h *= scale;
|
||||||
|
|
||||||
|
if(w < this->rect().width())
|
||||||
|
{
|
||||||
|
offsetX = (this->rect().width() - w)/2.0f;
|
||||||
|
}
|
||||||
|
if(h < this->rect().height())
|
||||||
|
{
|
||||||
|
offsetY = (this->rect().height() - h)/2.0f;
|
||||||
|
}
|
||||||
|
//printf("offsetX=%f, offsetY=%f\n",offsetX, offsetY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageView::paintEvent(QPaintEvent *event)
|
||||||
|
{
|
||||||
|
if(_graphicsViewMode->isChecked())
|
||||||
|
{
|
||||||
|
QWidget::paintEvent(event);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!_graphicsView->scene()->sceneRect().isNull())
|
||||||
|
{
|
||||||
|
//Scale
|
||||||
|
float ratio, offsetX, offsetY;
|
||||||
|
this->computeScaleOffsets(ratio, offsetX, offsetY);
|
||||||
|
QPainter painter(this);
|
||||||
|
|
||||||
|
//Background
|
||||||
|
painter.save();
|
||||||
|
painter.setBrush(_graphicsView->backgroundBrush());
|
||||||
|
painter.drawRect(this->rect());
|
||||||
|
painter.restore();
|
||||||
|
|
||||||
|
painter.translate(offsetX, offsetY);
|
||||||
|
painter.scale(ratio, ratio);
|
||||||
|
|
||||||
|
painter.save();
|
||||||
|
if(_showImage->isChecked() && !_image.isNull() &&
|
||||||
|
_showImageDepth->isChecked() && !_imageDepth.isNull())
|
||||||
|
{
|
||||||
|
painter.setOpacity(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_showImage->isChecked() && !_image.isNull())
|
||||||
|
{
|
||||||
|
painter.drawPixmap(QPoint(0,0), _image);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_showImageDepth->isChecked() && !_imageDepth.isNull())
|
||||||
|
{
|
||||||
|
painter.drawPixmap(QPoint(0,0), _imageDepth);
|
||||||
|
}
|
||||||
|
painter.restore();
|
||||||
|
|
||||||
|
if(_showFeatures->isChecked())
|
||||||
|
{
|
||||||
|
for(QMultiMap<int, rtabmap::KeypointItem *>::iterator iter = _features.begin(); iter != _features.end(); ++iter)
|
||||||
|
{
|
||||||
|
QColor color = iter.value()->pen().color();
|
||||||
|
painter.save();
|
||||||
|
painter.setPen(color);
|
||||||
|
painter.setBrush(color);
|
||||||
|
painter.drawEllipse(iter.value()->rect());
|
||||||
|
painter.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_showLines->isChecked())
|
||||||
|
{
|
||||||
|
for(QList<QGraphicsLineItem*>::iterator iter = _lines.begin(); iter != _lines.end(); ++iter)
|
||||||
|
{
|
||||||
|
QColor color = (*iter)->pen().color();
|
||||||
|
painter.save();
|
||||||
|
painter.setPen(color);
|
||||||
|
painter.drawLine((*iter)->line());
|
||||||
|
painter.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageView::resizeEvent(QResizeEvent* event)
|
||||||
|
{
|
||||||
|
QWidget::resizeEvent(event);
|
||||||
|
if(_graphicsView->isVisible() && _graphicsViewScaled->isChecked())
|
||||||
|
{
|
||||||
|
_graphicsView->fitInView(_graphicsView->sceneRect(), Qt::KeepAspectRatio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,9 +444,9 @@ void ImageView::contextMenuEvent(QContextMenuEvent * e)
|
|||||||
if(!text.isEmpty())
|
if(!text.isEmpty())
|
||||||
{
|
{
|
||||||
_savedFileName = text;
|
_savedFileName = text;
|
||||||
QImage img(this->sceneRect().width(), this->sceneRect().height(),QImage::Format_ARGB32_Premultiplied);
|
QImage img(_graphicsView->sceneRect().width(), _graphicsView->sceneRect().height(),QImage::Format_ARGB32_Premultiplied);
|
||||||
QPainter p(&img);
|
QPainter p(&img);
|
||||||
this->scene()->render(&p, this->sceneRect(), this->sceneRect());
|
_graphicsView->scene()->render(&p, _graphicsView->sceneRect(), _graphicsView->sceneRect());
|
||||||
img.save(text);
|
img.save(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,6 +470,16 @@ void ImageView::contextMenuEvent(QContextMenuEvent * e)
|
|||||||
this->setLinesShown(_showLines->isChecked());
|
this->setLinesShown(_showLines->isChecked());
|
||||||
emit configChanged();
|
emit configChanged();
|
||||||
}
|
}
|
||||||
|
else if(action == _graphicsViewMode)
|
||||||
|
{
|
||||||
|
this->setGraphicsViewMode(_graphicsViewMode->isChecked());
|
||||||
|
emit configChanged();
|
||||||
|
}
|
||||||
|
else if(action == _graphicsViewScaled)
|
||||||
|
{
|
||||||
|
this->setGraphicsViewScaled(_graphicsViewScaled->isChecked());
|
||||||
|
emit configChanged();
|
||||||
|
}
|
||||||
else if(action == _setAlpha)
|
else if(action == _setAlpha)
|
||||||
{
|
{
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
@@ -236,96 +500,46 @@ void ImageView::contextMenuEvent(QContextMenuEvent * e)
|
|||||||
|
|
||||||
void ImageView::updateOpacity()
|
void ImageView::updateOpacity()
|
||||||
{
|
{
|
||||||
if(_image && _imageDepth)
|
if(_imageItem && _imageDepthItem)
|
||||||
{
|
{
|
||||||
if(_image->isVisible() && _imageDepth->isVisible())
|
if(_imageItem->isVisible() && _imageDepthItem->isVisible())
|
||||||
{
|
{
|
||||||
QGraphicsOpacityEffect * effect = new QGraphicsOpacityEffect();
|
QGraphicsOpacityEffect * effect = new QGraphicsOpacityEffect();
|
||||||
QGraphicsOpacityEffect * effect2 = new QGraphicsOpacityEffect();
|
QGraphicsOpacityEffect * effect2 = new QGraphicsOpacityEffect();
|
||||||
effect->setOpacity(0.5);
|
effect->setOpacity(0.5);
|
||||||
effect2->setOpacity(0.5);
|
effect2->setOpacity(0.5);
|
||||||
_image->setGraphicsEffect(effect);
|
_imageItem->setGraphicsEffect(effect);
|
||||||
_imageDepth->setGraphicsEffect(effect2);
|
_imageDepthItem->setGraphicsEffect(effect2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_image->setGraphicsEffect(0);
|
_imageItem->setGraphicsEffect(0);
|
||||||
_imageDepth->setGraphicsEffect(0);
|
_imageDepthItem->setGraphicsEffect(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(_image)
|
else if(_imageItem)
|
||||||
{
|
{
|
||||||
_image->setGraphicsEffect(0);
|
_imageItem->setGraphicsEffect(0);
|
||||||
}
|
}
|
||||||
else if(_imageDepth)
|
else if(_imageDepthItem)
|
||||||
{
|
{
|
||||||
_imageDepth->setGraphicsEffect(0);
|
_imageDepthItem->setGraphicsEffect(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageView::updateZoom()
|
|
||||||
{
|
|
||||||
qreal scaleRatio = 1;
|
|
||||||
if(this->scene())
|
|
||||||
{
|
|
||||||
scaleRatio = this->geometry().width()/this->sceneRect().width();
|
|
||||||
}
|
|
||||||
_minZoom = log(scaleRatio)/log(2.0)*50+250;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageView::wheelEvent(QWheelEvent * e)
|
|
||||||
{
|
|
||||||
if(e->delta() > 0)
|
|
||||||
{
|
|
||||||
_zoom += 20;
|
|
||||||
this->setDragMode(QGraphicsView::ScrollHandDrag);
|
|
||||||
if(_zoom>=500)
|
|
||||||
{
|
|
||||||
_zoom = 500;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_zoom -= 20;
|
|
||||||
if(_zoom<=_minZoom)
|
|
||||||
{
|
|
||||||
this->setDragMode(QGraphicsView::NoDrag);
|
|
||||||
_zoom = _minZoom;
|
|
||||||
this->fitInView(this->sceneRect(), Qt::KeepAspectRatio);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal scale = qPow(qreal(2), (_zoom - 250) / qreal(50));
|
|
||||||
QMatrix matrix;
|
|
||||||
matrix.scale(scale, scale);
|
|
||||||
this->setMatrix(matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageView::setFeatures(const std::multimap<int, cv::KeyPoint> & refWords, const QColor & color)
|
void ImageView::setFeatures(const std::multimap<int, cv::KeyPoint> & refWords, const QColor & color)
|
||||||
{
|
{
|
||||||
qDeleteAll(_features);
|
qDeleteAll(_features);
|
||||||
_features.clear();
|
_features.clear();
|
||||||
|
|
||||||
rtabmap::KeypointItem * item = 0;
|
for(std::multimap<int, cv::KeyPoint>::const_iterator iter = refWords.begin(); iter != refWords.end(); ++iter )
|
||||||
for(std::multimap<int, cv::KeyPoint>::const_iterator i = refWords.begin(); i != refWords.end(); ++i )
|
|
||||||
{
|
{
|
||||||
const cv::KeyPoint & r = (*i).second;
|
addFeature(iter->first, iter->second, color);
|
||||||
int id = (*i).first;
|
}
|
||||||
QString info = QString( "WordRef = %1\n"
|
|
||||||
"Laplacian = %2\n"
|
|
||||||
"Dir = %3\n"
|
|
||||||
"Hessian = %4\n"
|
|
||||||
"X = %5\n"
|
|
||||||
"Y = %6\n"
|
|
||||||
"Size = %7").arg(id).arg(1).arg(r.angle).arg(r.response).arg(r.pt.x).arg(r.pt.y).arg(r.size);
|
|
||||||
float radius = r.size/2.0f;
|
|
||||||
item = new rtabmap::KeypointItem(r.pt.x-radius, r.pt.y-radius, radius*2, info, color);
|
|
||||||
|
|
||||||
scene()->addItem(item);
|
if(!_graphicsView->isVisible())
|
||||||
_features.insert(id, item);
|
{
|
||||||
item->setVisible(_showFeatures->isChecked());
|
this->update();
|
||||||
item->setZValue(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,60 +548,97 @@ void ImageView::setFeatures(const std::vector<cv::KeyPoint> & features, const QC
|
|||||||
qDeleteAll(_features);
|
qDeleteAll(_features);
|
||||||
_features.clear();
|
_features.clear();
|
||||||
|
|
||||||
rtabmap::KeypointItem * item = 0;
|
|
||||||
for(unsigned int i = 0; i< features.size(); ++i )
|
for(unsigned int i = 0; i< features.size(); ++i )
|
||||||
{
|
{
|
||||||
const cv::KeyPoint & r = features[i];
|
addFeature(i, features[i], color);
|
||||||
int id = i;
|
}
|
||||||
QString info = QString( "WordRef = %1\n"
|
|
||||||
"Laplacian = %2\n"
|
|
||||||
"Dir = %3\n"
|
|
||||||
"Hessian = %4\n"
|
|
||||||
"X = %5\n"
|
|
||||||
"Y = %6\n"
|
|
||||||
"Size = %7").arg(id).arg(1).arg(r.angle).arg(r.response).arg(r.pt.x).arg(r.pt.y).arg(r.size);
|
|
||||||
float radius = (r.size==0?3:r.size)/2.0f;
|
|
||||||
item = new rtabmap::KeypointItem(r.pt.x-radius, r.pt.y-radius, radius*2, info, color);
|
|
||||||
|
|
||||||
scene()->addItem(item);
|
if(!_graphicsView->isVisible())
|
||||||
_features.insert(id, item);
|
{
|
||||||
item->setVisible(_showFeatures->isChecked());
|
this->update();
|
||||||
item->setZValue(1);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageView::addFeature(int id, const cv::KeyPoint & kpt, QColor color)
|
||||||
|
{
|
||||||
|
color.setAlpha(this->getAlpha());
|
||||||
|
rtabmap::KeypointItem * item = new rtabmap::KeypointItem(id, kpt, color);
|
||||||
|
_features.insert(id, item);
|
||||||
|
item->setVisible(isFeaturesShown());
|
||||||
|
item->setZValue(1);
|
||||||
|
|
||||||
|
if(_graphicsView->isVisible())
|
||||||
|
{
|
||||||
|
_graphicsView->scene()->addItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageView::addLine(float x1, float y1, float x2, float y2, QColor color)
|
||||||
|
{
|
||||||
|
color.setAlpha(this->getAlpha());
|
||||||
|
QGraphicsLineItem * item = new QGraphicsLineItem(x1, y1, x2, y2);
|
||||||
|
item->setPen(QPen(color));
|
||||||
|
_lines.push_back(item);
|
||||||
|
item->setVisible(isLinesShown());
|
||||||
|
item->setZValue(1);
|
||||||
|
|
||||||
|
if(_graphicsView->isVisible())
|
||||||
|
{
|
||||||
|
_graphicsView->scene()->addItem(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageView::setImage(const QImage & image)
|
void ImageView::setImage(const QImage & image)
|
||||||
{
|
{
|
||||||
if(_image)
|
_image = QPixmap::fromImage(image);
|
||||||
|
if(_graphicsView->isVisible())
|
||||||
{
|
{
|
||||||
_image->setPixmap(QPixmap::fromImage(image));
|
if(_imageItem)
|
||||||
|
{
|
||||||
|
_imageItem->setPixmap(_image);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_imageItem = _graphicsView->scene()->addPixmap(_image);
|
||||||
|
_imageItem->setVisible(_showImage->isChecked());
|
||||||
|
_showImage->setEnabled(true);
|
||||||
|
this->updateOpacity();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_image = scene()->addPixmap(QPixmap::fromImage(image));
|
this->setSceneRect(image.rect());
|
||||||
_image->setVisible(_showImage->isChecked());
|
this->update();
|
||||||
_showImage->setEnabled(true);
|
|
||||||
this->updateOpacity();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageView::setImageDepth(const QImage & imageDepth)
|
void ImageView::setImageDepth(const QImage & imageDepth)
|
||||||
{
|
{
|
||||||
if(_imageDepth)
|
_imageDepth = QPixmap::fromImage(imageDepth);
|
||||||
|
if(_graphicsView->isVisible())
|
||||||
{
|
{
|
||||||
_imageDepth->setPixmap(QPixmap::fromImage(imageDepth));
|
if(_imageDepthItem)
|
||||||
|
{
|
||||||
|
_imageDepthItem->setPixmap(_imageDepth);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_imageDepthItem = _graphicsView->scene()->addPixmap(_imageDepth);
|
||||||
|
_imageDepthItem->setVisible(_showImageDepth->isChecked());
|
||||||
|
_showImageDepth->setEnabled(true);
|
||||||
|
this->updateOpacity();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_imageDepth = scene()->addPixmap(QPixmap::fromImage(imageDepth));
|
this->setSceneRect(imageDepth.rect());
|
||||||
_imageDepth->setVisible(_showImageDepth->isChecked());
|
this->update();
|
||||||
_showImageDepth->setEnabled(true);
|
|
||||||
this->updateOpacity();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageView::setFeatureColor(int id, const QColor & color)
|
void ImageView::setFeatureColor(int id, QColor color)
|
||||||
{
|
{
|
||||||
|
color.setAlpha(getAlpha());
|
||||||
QList<KeypointItem*> items = _features.values(id);
|
QList<KeypointItem*> items = _features.values(id);
|
||||||
if(items.size())
|
if(items.size())
|
||||||
{
|
{
|
||||||
@@ -400,14 +651,24 @@ void ImageView::setFeatureColor(int id, const QColor & color)
|
|||||||
{
|
{
|
||||||
UWARN("Not found feature %d", id);
|
UWARN("Not found feature %d", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!_graphicsView->isVisible())
|
||||||
|
{
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageView::setFeaturesColor(const QColor & color)
|
void ImageView::setFeaturesColor(QColor color)
|
||||||
{
|
{
|
||||||
|
color.setAlpha(getAlpha());
|
||||||
for(QMultiMap<int, KeypointItem*>::iterator iter=_features.begin(); iter!=_features.end(); ++iter)
|
for(QMultiMap<int, KeypointItem*>::iterator iter=_features.begin(); iter!=_features.end(); ++iter)
|
||||||
{
|
{
|
||||||
iter.value()->setPen(QPen(color));
|
iter.value()->setColor(color);
|
||||||
iter.value()->setBrush(QBrush(color));
|
}
|
||||||
|
|
||||||
|
if(!_graphicsView->isVisible())
|
||||||
|
{
|
||||||
|
this->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,21 +683,47 @@ void ImageView::setAlpha(int alpha)
|
|||||||
iter.value()->setPen(QPen(c));
|
iter.value()->setPen(QPen(c));
|
||||||
iter.value()->setBrush(QBrush(c));
|
iter.value()->setBrush(QBrush(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(QList<QGraphicsLineItem*>::iterator iter=_lines.begin(); iter!=_lines.end(); ++iter)
|
||||||
|
{
|
||||||
|
QColor c = (*iter)->pen().color();
|
||||||
|
c.setAlpha(_alpha);
|
||||||
|
(*iter)->setPen(QPen(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!_graphicsView->isVisible())
|
||||||
|
{
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageView::setSceneRect(const QRectF & rect)
|
||||||
|
{
|
||||||
|
_graphicsView->scene()->setSceneRect(rect);
|
||||||
|
|
||||||
|
if(_graphicsViewScaled->isChecked())
|
||||||
|
{
|
||||||
|
_graphicsView->fitInView(_graphicsView->sceneRect(), Qt::KeepAspectRatio);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_graphicsView->resetTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!_graphicsView->isVisible())
|
||||||
|
{
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageView::clearLines()
|
void ImageView::clearLines()
|
||||||
{
|
{
|
||||||
if(this->scene())
|
qDeleteAll(_lines);
|
||||||
|
_lines.clear();
|
||||||
|
|
||||||
|
if(!_graphicsView->isVisible())
|
||||||
{
|
{
|
||||||
QList<QGraphicsItem*> items = this->scene()->items();
|
this->update();
|
||||||
for(int i=0; i<items.size(); ++i)
|
|
||||||
{
|
|
||||||
QGraphicsLineItem * line = qgraphicsitem_cast<QGraphicsLineItem*>(items[i]);
|
|
||||||
if(line)
|
|
||||||
{
|
|
||||||
delete line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,22 +732,34 @@ void ImageView::clear()
|
|||||||
qDeleteAll(_features);
|
qDeleteAll(_features);
|
||||||
_features.clear();
|
_features.clear();
|
||||||
|
|
||||||
if(_image)
|
qDeleteAll(_lines);
|
||||||
|
_lines.clear();
|
||||||
|
|
||||||
|
if(_imageItem)
|
||||||
{
|
{
|
||||||
scene()->removeItem(_image);
|
_graphicsView->scene()->removeItem(_imageItem);
|
||||||
delete _image;
|
delete _imageItem;
|
||||||
_image = 0;
|
_imageItem = 0;
|
||||||
_showImage->setEnabled(false);
|
_showImage->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_imageDepth)
|
if(_imageDepthItem)
|
||||||
{
|
{
|
||||||
scene()->removeItem(_imageDepth);
|
_graphicsView->scene()->removeItem(_imageDepthItem);
|
||||||
delete _imageDepth;
|
delete _imageDepthItem;
|
||||||
_imageDepth = 0;
|
_imageDepthItem = 0;
|
||||||
_showImageDepth->setEnabled(false);
|
_showImageDepth->setEnabled(false);
|
||||||
}
|
}
|
||||||
scene()->clear();
|
|
||||||
|
if(!_graphicsView->isVisible())
|
||||||
|
{
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize ImageView::sizeHint() const
|
||||||
|
{
|
||||||
|
return _graphicsView->sizeHint();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,9 +34,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
namespace rtabmap {
|
namespace rtabmap {
|
||||||
|
|
||||||
KeypointItem::KeypointItem(qreal x, qreal y, int r, const QString & info, const QColor & color, QGraphicsItem * parent) :
|
KeypointItem::KeypointItem(int id, const cv::KeyPoint & kpt, const QColor & color, QGraphicsItem * parent) :
|
||||||
QGraphicsEllipseItem(x, y, r, r, parent),
|
QGraphicsEllipseItem(kpt.pt.x-(kpt.size==0?3.0f:kpt.size)/2.0f, kpt.pt.y-(kpt.size==0?3.0f:kpt.size)/2.0f, kpt.size==0?3.0f:kpt.size, kpt.size==0?3.0f:kpt.size, parent),
|
||||||
_info(info),
|
_id(id),
|
||||||
|
_kpt(kpt),
|
||||||
_placeHolder(0)
|
_placeHolder(0)
|
||||||
{
|
{
|
||||||
this->setColor(color);
|
this->setColor(color);
|
||||||
@@ -68,7 +69,12 @@ void KeypointItem::showDescription()
|
|||||||
_placeHolder->setBrush(QBrush(QColor ( 0, 0, 0, 170 ))); // Black transparent background
|
_placeHolder->setBrush(QBrush(QColor ( 0, 0, 0, 170 ))); // Black transparent background
|
||||||
QGraphicsTextItem * text = new QGraphicsTextItem(_placeHolder);
|
QGraphicsTextItem * text = new QGraphicsTextItem(_placeHolder);
|
||||||
text->setDefaultTextColor(this->pen().color().rgb());
|
text->setDefaultTextColor(this->pen().color().rgb());
|
||||||
text->setPlainText(_info);
|
text->setPlainText(QString( "Id = %1\n"
|
||||||
|
"Dir = %3\n"
|
||||||
|
"Hessian = %4\n"
|
||||||
|
"X = %5\n"
|
||||||
|
"Y = %6\n"
|
||||||
|
"Size = %7").arg(_id).arg(_kpt.angle).arg(_kpt.response).arg(_kpt.pt.x).arg(_kpt.pt.y).arg(_kpt.size));
|
||||||
_placeHolder->setRect(text->boundingRect());
|
_placeHolder->setRect(text->boundingRect());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+83
-129
@@ -209,9 +209,9 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
|
|||||||
_logEventTime->start();
|
_logEventTime->start();
|
||||||
|
|
||||||
//Graphics scenes
|
//Graphics scenes
|
||||||
_ui->imageView_source->setBackgroundBrush(QBrush(Qt::black));
|
_ui->imageView_source->setBackgroundColor(Qt::black);
|
||||||
_ui->imageView_loopClosure->setBackgroundBrush(QBrush(Qt::black));
|
_ui->imageView_loopClosure->setBackgroundColor(Qt::black);
|
||||||
_ui->imageView_odometry->setBackgroundBrush(QBrush(Qt::black));
|
_ui->imageView_odometry->setBackgroundColor(Qt::black);
|
||||||
_ui->imageView_odometry->setAlpha(200);
|
_ui->imageView_odometry->setAlpha(200);
|
||||||
_preferencesDialog->loadWidgetState(_ui->imageView_source);
|
_preferencesDialog->loadWidgetState(_ui->imageView_source);
|
||||||
_preferencesDialog->loadWidgetState(_ui->imageView_loopClosure);
|
_preferencesDialog->loadWidgetState(_ui->imageView_loopClosure);
|
||||||
@@ -666,13 +666,13 @@ void MainWindow::processOdometry(const rtabmap::SensorData & data, const rtabmap
|
|||||||
Transform pose = data.pose();
|
Transform pose = data.pose();
|
||||||
bool lost = false;
|
bool lost = false;
|
||||||
bool lostStateChanged = false;
|
bool lostStateChanged = false;
|
||||||
_ui->imageView_odometry->resetTransform();
|
|
||||||
if(pose.isNull())
|
if(pose.isNull())
|
||||||
{
|
{
|
||||||
UDEBUG("odom lost"); // use last pose
|
UDEBUG("odom lost"); // use last pose
|
||||||
lostStateChanged = _ui->widget_cloudViewer->getBackgroundColor() != Qt::darkRed;
|
lostStateChanged = _ui->widget_cloudViewer->getBackgroundColor() != Qt::darkRed;
|
||||||
_ui->widget_cloudViewer->setBackgroundColor(Qt::darkRed);
|
_ui->widget_cloudViewer->setBackgroundColor(Qt::darkRed);
|
||||||
_ui->imageView_odometry->setBackgroundBrush(QBrush(Qt::darkRed));
|
_ui->imageView_odometry->setBackgroundColor(Qt::darkRed);
|
||||||
|
|
||||||
pose = _lastOdomPose;
|
pose = _lastOdomPose;
|
||||||
lost = true;
|
lost = true;
|
||||||
@@ -684,15 +684,16 @@ void MainWindow::processOdometry(const rtabmap::SensorData & data, const rtabmap
|
|||||||
UDEBUG("odom warn, quality(inliers)=%d thr=%d", info.inliers, _preferencesDialog->getOdomQualityWarnThr());
|
UDEBUG("odom warn, quality(inliers)=%d thr=%d", info.inliers, _preferencesDialog->getOdomQualityWarnThr());
|
||||||
lostStateChanged = _ui->widget_cloudViewer->getBackgroundColor() == Qt::darkRed;
|
lostStateChanged = _ui->widget_cloudViewer->getBackgroundColor() == Qt::darkRed;
|
||||||
_ui->widget_cloudViewer->setBackgroundColor(Qt::darkYellow);
|
_ui->widget_cloudViewer->setBackgroundColor(Qt::darkYellow);
|
||||||
_ui->imageView_odometry->setBackgroundBrush(QBrush(Qt::darkYellow));
|
_ui->imageView_odometry->setBackgroundColor(Qt::darkYellow);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UDEBUG("odom ok");
|
UDEBUG("odom ok");
|
||||||
lostStateChanged = _ui->widget_cloudViewer->getBackgroundColor() == Qt::darkRed;
|
lostStateChanged = _ui->widget_cloudViewer->getBackgroundColor() == Qt::darkRed;
|
||||||
_ui->widget_cloudViewer->setBackgroundColor(_ui->widget_cloudViewer->getDefaultBackgroundColor());
|
_ui->widget_cloudViewer->setBackgroundColor(_ui->widget_cloudViewer->getDefaultBackgroundColor());
|
||||||
_ui->imageView_odometry->setBackgroundBrush(QBrush(Qt::black));
|
_ui->imageView_odometry->setBackgroundColor(Qt::black);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(info.inliers >= 0)
|
if(info.inliers >= 0)
|
||||||
{
|
{
|
||||||
_ui->statsToolBox->updateStat("Odometry/Inliers/", (float)data.id(), (float)info.inliers);
|
_ui->statsToolBox->updateStat("Odometry/Inliers/", (float)data.id(), (float)info.inliers);
|
||||||
@@ -810,16 +811,16 @@ void MainWindow::processOdometry(const rtabmap::SensorData & data, const rtabmap
|
|||||||
{
|
{
|
||||||
if(_ui->imageView_odometry->isFeaturesShown())
|
if(_ui->imageView_odometry->isFeaturesShown())
|
||||||
{
|
{
|
||||||
int alpha = _ui->imageView_odometry->getAlpha();
|
|
||||||
if(info.type == 0)
|
if(info.type == 0)
|
||||||
{
|
{
|
||||||
_ui->imageView_odometry->setFeatures(info.words, QColor(255,255,0, alpha));
|
_ui->imageView_odometry->setFeatures(info.words, Qt::yellow);
|
||||||
}
|
}
|
||||||
else if(info.type == 1)
|
else if(info.type == 1)
|
||||||
{
|
{
|
||||||
_ui->imageView_odometry->setFeatures(info.refCorners, QColor(255,0,0, alpha));
|
_ui->imageView_odometry->setFeatures(info.refCorners, Qt::red);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ui->imageView_odometry->clearLines();
|
_ui->imageView_odometry->clearLines();
|
||||||
if(lost)
|
if(lost)
|
||||||
{
|
{
|
||||||
@@ -852,14 +853,13 @@ void MainWindow::processOdometry(const rtabmap::SensorData & data, const rtabmap
|
|||||||
{
|
{
|
||||||
if(_ui->imageView_odometry->isFeaturesShown())
|
if(_ui->imageView_odometry->isFeaturesShown())
|
||||||
{
|
{
|
||||||
int alpha = _ui->imageView_odometry->getAlpha();
|
|
||||||
for(unsigned int i=0; i<info.wordMatches.size(); ++i)
|
for(unsigned int i=0; i<info.wordMatches.size(); ++i)
|
||||||
{
|
{
|
||||||
_ui->imageView_odometry->setFeatureColor(info.wordMatches[i], QColor(255,0,0, alpha)); // outliers
|
_ui->imageView_odometry->setFeatureColor(info.wordMatches[i], Qt::red); // outliers
|
||||||
}
|
}
|
||||||
for(unsigned int i=0; i<info.wordInliers.size(); ++i)
|
for(unsigned int i=0; i<info.wordInliers.size(); ++i)
|
||||||
{
|
{
|
||||||
_ui->imageView_odometry->setFeatureColor(info.wordInliers[i], QColor(0,255,0, alpha)); // inliers
|
_ui->imageView_odometry->setFeatureColor(info.wordInliers[i], Qt::green); // inliers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -868,33 +868,32 @@ void MainWindow::processOdometry(const rtabmap::SensorData & data, const rtabmap
|
|||||||
if(_ui->imageView_odometry->isFeaturesShown() || _ui->imageView_odometry->isLinesShown())
|
if(_ui->imageView_odometry->isFeaturesShown() || _ui->imageView_odometry->isLinesShown())
|
||||||
{
|
{
|
||||||
//draw lines
|
//draw lines
|
||||||
int alpha = _ui->imageView_odometry->getAlpha();
|
|
||||||
UASSERT(info.refCorners.size() == info.newCorners.size());
|
UASSERT(info.refCorners.size() == info.newCorners.size());
|
||||||
for(unsigned int i=0; i<info.cornerInliers.size(); ++i)
|
for(unsigned int i=0; i<info.cornerInliers.size(); ++i)
|
||||||
{
|
{
|
||||||
if(_ui->imageView_odometry->isFeaturesShown())
|
if(_ui->imageView_odometry->isFeaturesShown())
|
||||||
{
|
{
|
||||||
_ui->imageView_odometry->setFeatureColor(info.cornerInliers[i], QColor(0,255,0, alpha)); // inliers
|
_ui->imageView_odometry->setFeatureColor(info.cornerInliers[i], Qt::green); // inliers
|
||||||
}
|
}
|
||||||
if(_ui->imageView_odometry->isLinesShown())
|
if(_ui->imageView_odometry->isLinesShown())
|
||||||
{
|
{
|
||||||
QGraphicsLineItem * item = _ui->imageView_odometry->scene()->addLine(
|
_ui->imageView_odometry->addLine(
|
||||||
info.refCorners[info.cornerInliers[i]].pt.x,
|
info.refCorners[info.cornerInliers[i]].pt.x,
|
||||||
info.refCorners[info.cornerInliers[i]].pt.y,
|
info.refCorners[info.cornerInliers[i]].pt.y,
|
||||||
info.newCorners[info.cornerInliers[i]].pt.x,
|
info.newCorners[info.cornerInliers[i]].pt.x,
|
||||||
info.newCorners[info.cornerInliers[i]].pt.y,
|
info.newCorners[info.cornerInliers[i]].pt.y,
|
||||||
QPen(QColor(0, 0, 255, alpha)));
|
Qt::blue);
|
||||||
item->setVisible(_ui->imageView_odometry->isLinesShown());
|
|
||||||
item->setZValue(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ui->imageView_odometry->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
_ui->imageView_odometry->resetZoom();
|
}
|
||||||
_ui->imageView_odometry->setSceneRect(_ui->imageView_odometry->scene()->itemsBoundingRect());
|
if(!data.image().empty())
|
||||||
_ui->imageView_odometry->fitInView(_ui->imageView_odometry->sceneRect(), Qt::KeepAspectRatio);
|
{
|
||||||
|
_ui->imageView_odometry->setSceneRect(QRectF(0,0,(float)data.image().cols, (float)data.image().rows));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_ui->actionAuto_screen_capture->isChecked() && _autoScreenCaptureOdomSync)
|
if(_ui->actionAuto_screen_capture->isChecked() && _autoScreenCaptureOdomSync)
|
||||||
@@ -937,10 +936,8 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
// Loop closure info
|
// Loop closure info
|
||||||
_ui->imageView_source->clear();
|
_ui->imageView_source->clear();
|
||||||
_ui->imageView_loopClosure->clear();
|
_ui->imageView_loopClosure->clear();
|
||||||
_ui->imageView_source->resetTransform();
|
_ui->imageView_source->setBackgroundColor(Qt::black);
|
||||||
_ui->imageView_loopClosure->resetTransform();
|
_ui->imageView_loopClosure->setBackgroundColor(Qt::black);
|
||||||
_ui->imageView_source->setBackgroundBrush(QBrush(Qt::black));
|
|
||||||
_ui->imageView_loopClosure->setBackgroundBrush(QBrush(Qt::black));
|
|
||||||
|
|
||||||
// update cache
|
// update cache
|
||||||
Signature signature = stat.getSignature();
|
Signature signature = stat.getSignature();
|
||||||
@@ -955,15 +952,15 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
|
|
||||||
if(rehearsed > 0)
|
if(rehearsed > 0)
|
||||||
{
|
{
|
||||||
_ui->imageView_source->setBackgroundBrush(QBrush(Qt::blue));
|
_ui->imageView_source->setBackgroundColor(Qt::blue);
|
||||||
}
|
}
|
||||||
else if(localTimeClosures > 0)
|
else if(localTimeClosures > 0)
|
||||||
{
|
{
|
||||||
_ui->imageView_source->setBackgroundBrush(QBrush(Qt::darkCyan));
|
_ui->imageView_source->setBackgroundColor(Qt::darkCyan);
|
||||||
}
|
}
|
||||||
else if(scanMatchingSuccess)
|
else if(scanMatchingSuccess)
|
||||||
{
|
{
|
||||||
_ui->imageView_source->setBackgroundBrush(QBrush(Qt::gray));
|
_ui->imageView_source->setBackgroundColor(Qt::gray);
|
||||||
}
|
}
|
||||||
|
|
||||||
UDEBUG("time= %d ms", time.restart());
|
UDEBUG("time= %d ms", time.restart());
|
||||||
@@ -978,7 +975,7 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
bool show = true;
|
bool show = true;
|
||||||
if(stat.loopClosureId() > 0)
|
if(stat.loopClosureId() > 0)
|
||||||
{
|
{
|
||||||
_ui->imageView_loopClosure->setBackgroundBrush(QBrush(Qt::green));
|
_ui->imageView_loopClosure->setBackgroundColor(Qt::green);
|
||||||
_ui->label_stats_loopClosuresDetected->setText(QString::number(_ui->label_stats_loopClosuresDetected->text().toInt() + 1));
|
_ui->label_stats_loopClosuresDetected->setText(QString::number(_ui->label_stats_loopClosuresDetected->text().toInt() + 1));
|
||||||
if(highestHypothesisIsSaved)
|
if(highestHypothesisIsSaved)
|
||||||
{
|
{
|
||||||
@@ -989,7 +986,7 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
}
|
}
|
||||||
else if(stat.localLoopClosureId())
|
else if(stat.localLoopClosureId())
|
||||||
{
|
{
|
||||||
_ui->imageView_loopClosure->setBackgroundBrush(QBrush(Qt::yellow));
|
_ui->imageView_loopClosure->setBackgroundColor(Qt::yellow);
|
||||||
_ui->label_matchId->setText(QString("Local match = %1 [%2]").arg(stat.localLoopClosureId()).arg(loopMapId));
|
_ui->label_matchId->setText(QString("Local match = %1 [%2]").arg(stat.localLoopClosureId()).arg(loopMapId));
|
||||||
matchId = stat.localLoopClosureId();
|
matchId = stat.localLoopClosureId();
|
||||||
}
|
}
|
||||||
@@ -998,7 +995,7 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
show = _preferencesDialog->imageRejectedShown() || _preferencesDialog->imageHighestHypShown();
|
show = _preferencesDialog->imageRejectedShown() || _preferencesDialog->imageHighestHypShown();
|
||||||
if(show)
|
if(show)
|
||||||
{
|
{
|
||||||
_ui->imageView_loopClosure->setBackgroundBrush(QBrush(Qt::red));
|
_ui->imageView_loopClosure->setBackgroundColor(Qt::red);
|
||||||
_ui->label_stats_loopClosuresRejected->setText(QString::number(_ui->label_stats_loopClosuresRejected->text().toInt() + 1));
|
_ui->label_stats_loopClosuresRejected->setText(QString::number(_ui->label_stats_loopClosuresRejected->text().toInt() + 1));
|
||||||
_ui->label_matchId->setText(QString("Loop hypothesis %1 rejected!").arg(highestHypothesisId));
|
_ui->label_matchId->setText(QString("Loop hypothesis %1 rejected!").arg(highestHypothesisId));
|
||||||
}
|
}
|
||||||
@@ -1062,24 +1059,16 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
{
|
{
|
||||||
_ui->imageView_loopClosure->setImageDepth(lcDepth);
|
_ui->imageView_loopClosure->setImageDepth(lcDepth);
|
||||||
}
|
}
|
||||||
QRectF sceneRect = img.rect();
|
if(img.rect().isValid())
|
||||||
_ui->imageView_source->setSceneRect(sceneRect);
|
{
|
||||||
_ui->imageView_loopClosure->setSceneRect(sceneRect);
|
QRectF sceneRect = img.rect();
|
||||||
|
_ui->imageView_source->setSceneRect(sceneRect);
|
||||||
|
_ui->imageView_loopClosure->setSceneRect(sceneRect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UDEBUG("time= %d ms", time.restart());
|
UDEBUG("time= %d ms", time.restart());
|
||||||
|
|
||||||
// We use the reference image to resize the 2 views
|
|
||||||
_ui->imageView_source->resetZoom();
|
|
||||||
_ui->imageView_loopClosure->resetZoom();
|
|
||||||
if(signature.getImageRaw().empty())
|
|
||||||
{
|
|
||||||
_ui->imageView_source->setSceneRect(_ui->imageView_source->scene()->itemsBoundingRect());
|
|
||||||
_ui->imageView_loopClosure->setSceneRect(_ui->imageView_source->scene()->itemsBoundingRect());
|
|
||||||
}
|
|
||||||
_ui->imageView_source->fitInView(_ui->imageView_source->sceneRect(), Qt::KeepAspectRatio);
|
|
||||||
_ui->imageView_loopClosure->fitInView(_ui->imageView_source->sceneRect(), Qt::KeepAspectRatio);
|
|
||||||
|
|
||||||
// do it after scaling
|
// do it after scaling
|
||||||
this->drawKeypoints(signature.getWords(), loopSignature.getWords());
|
this->drawKeypoints(signature.getWords(), loopSignature.getWords());
|
||||||
|
|
||||||
@@ -2059,101 +2048,78 @@ void MainWindow::drawKeypoints(const std::multimap<int, cv::KeyPoint> & refWords
|
|||||||
|
|
||||||
timer.start();
|
timer.start();
|
||||||
KeypointItem * item = 0;
|
KeypointItem * item = 0;
|
||||||
int alphaA = _ui->imageView_source->getAlpha();
|
|
||||||
ULOGGER_DEBUG("refWords.size() = %d", refWords.size());
|
ULOGGER_DEBUG("refWords.size() = %d", refWords.size());
|
||||||
QMap<int, KeypointItem*> addedKeypoints;
|
for(std::multimap<int, cv::KeyPoint>::const_iterator iter = refWords.begin(); iter != refWords.end(); ++iter )
|
||||||
for(std::multimap<int, cv::KeyPoint>::const_iterator i = refWords.begin(); i != refWords.end(); ++i )
|
|
||||||
{
|
{
|
||||||
const cv::KeyPoint & r = (*i).second;
|
int id = iter->first;
|
||||||
int id = (*i).first;
|
QColor color;
|
||||||
|
|
||||||
QString info = QString( "WordRef = %1\n"
|
|
||||||
"Laplacian = %2\n"
|
|
||||||
"Dir = %3\n"
|
|
||||||
"Hessian = %4\n"
|
|
||||||
"X = %5\n"
|
|
||||||
"Y = %6\n"
|
|
||||||
"Size = %7").arg(id).arg(1).arg(r.angle).arg(r.response).arg(r.pt.x).arg(r.pt.y).arg(r.size);
|
|
||||||
float radius = r.size/2.0f;
|
|
||||||
if(uContains(loopWords, id))
|
if(uContains(loopWords, id))
|
||||||
{
|
{
|
||||||
// PINK = FOUND IN LOOP SIGNATURE
|
// PINK = FOUND IN LOOP SIGNATURE
|
||||||
item = new KeypointItem(r.pt.x-radius, r.pt.y-radius, radius*2, info, QColor(255, 0, 255, alphaA));
|
color = Qt::magenta;
|
||||||
}
|
}
|
||||||
else if(_lastIds.contains(id))
|
else if(_lastIds.contains(id))
|
||||||
{
|
{
|
||||||
// BLUE = FOUND IN LAST SIGNATURE
|
// BLUE = FOUND IN LAST SIGNATURE
|
||||||
item = new KeypointItem(r.pt.x-radius, r.pt.y-radius, radius*2, info, QColor(0, 0, 255, alphaA));
|
color = Qt::blue;
|
||||||
}
|
}
|
||||||
else if(id<=_lastId)
|
else if(id<=_lastId)
|
||||||
{
|
{
|
||||||
// RED = ALREADY EXISTS
|
// RED = ALREADY EXISTS
|
||||||
item = new KeypointItem(r.pt.x-radius, r.pt.y-radius, radius*2, info, QColor(255, 0, 0, alphaA));
|
color = Qt::red;
|
||||||
}
|
}
|
||||||
else if(refWords.count(id) > 1)
|
else if(refWords.count(id) > 1)
|
||||||
{
|
{
|
||||||
// YELLOW = NEW and multiple times
|
// YELLOW = NEW and multiple times
|
||||||
item = new KeypointItem(r.pt.x-radius, r.pt.y-radius, radius*2, info, QColor(255, 255, 0, alphaA));
|
color = Qt::yellow;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// GREEN = NEW
|
// GREEN = NEW
|
||||||
item = new KeypointItem(r.pt.x-radius, r.pt.y-radius, radius*2, info, QColor(0, 255, 0, alphaA));
|
color = Qt::green;
|
||||||
}
|
}
|
||||||
item->setVisible(this->_ui->imageView_source->isFeaturesShown());
|
_ui->imageView_source->addFeature(iter->first, iter->second, color);
|
||||||
this->_ui->imageView_source->scene()->addItem(item);
|
|
||||||
item->setZValue(1);
|
|
||||||
addedKeypoints.insert(id, item);
|
|
||||||
}
|
}
|
||||||
ULOGGER_DEBUG("source time = %f s", timer.ticks());
|
ULOGGER_DEBUG("source time = %f s", timer.ticks());
|
||||||
|
|
||||||
timer.start();
|
timer.start();
|
||||||
item = 0;
|
item = 0;
|
||||||
int alphaB = _ui->imageView_loopClosure->getAlpha();
|
|
||||||
ULOGGER_DEBUG("loopWords.size() = %d", loopWords.size());
|
ULOGGER_DEBUG("loopWords.size() = %d", loopWords.size());
|
||||||
QList<QPair<KeypointItem*, KeypointItem*> > uniqueCorrespondences;
|
QList<QPair<cv::Point2f, cv::Point2f> > uniqueCorrespondences;
|
||||||
for(std::multimap<int, cv::KeyPoint>::const_iterator i = loopWords.begin(); i != loopWords.end(); ++i )
|
for(std::multimap<int, cv::KeyPoint>::const_iterator iter = loopWords.begin(); iter != loopWords.end(); ++iter )
|
||||||
{
|
{
|
||||||
const cv::KeyPoint & r = (*i).second;
|
int id = iter->first;
|
||||||
int id = (*i).first;
|
QColor color;
|
||||||
|
|
||||||
QString info = QString( "WordRef = %1\n"
|
|
||||||
"Laplacian = %2\n"
|
|
||||||
"Dir = %3\n"
|
|
||||||
"Hessian = %4\n"
|
|
||||||
"X = %5\n"
|
|
||||||
"Y = %6\n"
|
|
||||||
"Size = %7").arg(id).arg(1).arg(r.angle).arg(r.response).arg(r.pt.x).arg(r.pt.y).arg(r.size);
|
|
||||||
float radius = r.size/2.0f;
|
|
||||||
if(uContains(refWords, id))
|
if(uContains(refWords, id))
|
||||||
{
|
{
|
||||||
// PINK = FOUND IN LOOP SIGNATURE
|
// PINK = FOUND IN LOOP SIGNATURE
|
||||||
item = new KeypointItem(r.pt.x-radius, r.pt.y-radius, radius*2, info, QColor(255, 0, 255, alphaB));
|
color = Qt::magenta;
|
||||||
//To draw lines... get only unique correspondences
|
//To draw lines... get only unique correspondences
|
||||||
if(uValues(refWords, id).size() == 1 && uValues(loopWords, id).size() == 1)
|
if(uValues(refWords, id).size() == 1 && uValues(loopWords, id).size() == 1)
|
||||||
{
|
{
|
||||||
uniqueCorrespondences.push_back(QPair<KeypointItem*, KeypointItem*>(addedKeypoints.value(id), item));
|
const cv::KeyPoint & a = refWords.find(id)->second;
|
||||||
|
const cv::KeyPoint & b = iter->second;
|
||||||
|
uniqueCorrespondences.push_back(QPair<cv::Point2f, cv::Point2f>(a.pt, b.pt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(id<=_lastId)
|
else if(id<=_lastId)
|
||||||
{
|
{
|
||||||
// RED = ALREADY EXISTS
|
// RED = ALREADY EXISTS
|
||||||
item = new KeypointItem(r.pt.x-radius, r.pt.y-radius, radius*2, info, QColor(255, 0, 0, alphaB));
|
color = Qt::red;
|
||||||
}
|
}
|
||||||
else if(refWords.count(id) > 1)
|
else if(refWords.count(id) > 1)
|
||||||
{
|
{
|
||||||
// YELLOW = NEW and multiple times
|
// YELLOW = NEW and multiple times
|
||||||
item = new KeypointItem(r.pt.x-radius, r.pt.y-radius, radius*2, info, QColor(255, 255, 0, alphaB));
|
color = Qt::yellow;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// GREEN = NEW
|
// GREEN = NEW
|
||||||
item = new KeypointItem(r.pt.x-radius, r.pt.y-radius, radius*2, info, QColor(0, 255, 0, alphaB));
|
color = Qt::green;
|
||||||
}
|
}
|
||||||
item->setVisible(this->_ui->imageView_loopClosure->isFeaturesShown());
|
_ui->imageView_loopClosure->addFeature(iter->first, iter->second, color);
|
||||||
this->_ui->imageView_loopClosure->scene()->addItem(item);
|
|
||||||
item->setZValue(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ULOGGER_DEBUG("loop closure time = %f s", timer.ticks());
|
ULOGGER_DEBUG("loop closure time = %f s", timer.ticks());
|
||||||
|
|
||||||
if(refWords.size()>0)
|
if(refWords.size()>0)
|
||||||
@@ -2166,39 +2132,36 @@ void MainWindow::drawKeypoints(const std::multimap<int, cv::KeyPoint> & refWords
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw lines between corresponding features...
|
// Draw lines between corresponding features...
|
||||||
float scaleX = _ui->imageView_source->transform().m11();
|
float scale = _ui->imageView_source->viewScale();
|
||||||
float scaleY = _ui->imageView_source->transform().m22();
|
UDEBUG("scale=%f", scale);
|
||||||
UDEBUG("scaleX=%f scaleY=%f", scaleX, scaleY);
|
float deltaX = _ui->imageView_source->width()/scale;
|
||||||
int deltaX = _ui->imageView_source->width()/scaleX;
|
float deltaY = 0;
|
||||||
int deltaY = 0;
|
|
||||||
if(_preferencesDialog->isVerticalLayoutUsed())
|
if(_preferencesDialog->isVerticalLayoutUsed())
|
||||||
{
|
{
|
||||||
deltaX = 0;
|
deltaX = 0;
|
||||||
deltaY = _ui->imageView_source->height()/scaleY;
|
deltaY = _ui->imageView_source->height()/scale;
|
||||||
deltaY += _ui->label_matchId->height()/scaleY;
|
deltaY += _ui->label_matchId->height()/scale;
|
||||||
}
|
}
|
||||||
for(QList<QPair<KeypointItem*, KeypointItem*> >::iterator iter = uniqueCorrespondences.begin();
|
for(QList<QPair<cv::Point2f, cv::Point2f> >::iterator iter = uniqueCorrespondences.begin();
|
||||||
iter!=uniqueCorrespondences.end();
|
iter!=uniqueCorrespondences.end();
|
||||||
++iter)
|
++iter)
|
||||||
{
|
{
|
||||||
QGraphicsLineItem * item = _ui->imageView_source->scene()->addLine(
|
_ui->imageView_source->addLine(
|
||||||
iter->first->rect().x()+iter->first->rect().width()/2,
|
iter->first.x,
|
||||||
iter->first->rect().y()+iter->first->rect().height()/2,
|
iter->first.y,
|
||||||
iter->second->rect().x()+iter->second->rect().width()/2+deltaX,
|
iter->second.x+deltaX,
|
||||||
iter->second->rect().y()+iter->second->rect().height()/2+deltaY,
|
iter->second.y+deltaY,
|
||||||
QPen(QColor(0, 255, 255, alphaA)));
|
Qt::cyan);
|
||||||
item->setVisible(_ui->imageView_source->isLinesShown());
|
|
||||||
item->setZValue(1);
|
|
||||||
|
|
||||||
item = _ui->imageView_loopClosure->scene()->addLine(
|
_ui->imageView_loopClosure->addLine(
|
||||||
iter->first->rect().x()+iter->first->rect().width()/2-deltaX,
|
iter->first.x-deltaX,
|
||||||
iter->first->rect().y()+iter->first->rect().height()/2-deltaY,
|
iter->first.y-deltaY,
|
||||||
iter->second->rect().x()+iter->second->rect().width()/2,
|
iter->second.x,
|
||||||
iter->second->rect().y()+iter->second->rect().height()/2,
|
iter->second.y,
|
||||||
QPen(QColor(0, 255, 255, alphaB)));
|
Qt::cyan);
|
||||||
item->setVisible(_ui->imageView_loopClosure->isLinesShown());
|
|
||||||
item->setZValue(1);
|
|
||||||
}
|
}
|
||||||
|
_ui->imageView_source->update();
|
||||||
|
_ui->imageView_loopClosure->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::showEvent(QShowEvent* anEvent)
|
void MainWindow::showEvent(QShowEvent* anEvent)
|
||||||
@@ -2221,12 +2184,6 @@ void MainWindow::moveEvent(QMoveEvent* anEvent)
|
|||||||
|
|
||||||
void MainWindow::resizeEvent(QResizeEvent* anEvent)
|
void MainWindow::resizeEvent(QResizeEvent* anEvent)
|
||||||
{
|
{
|
||||||
_ui->imageView_source->fitInView(_ui->imageView_source->sceneRect(), Qt::KeepAspectRatio);
|
|
||||||
_ui->imageView_loopClosure->fitInView(_ui->imageView_source->sceneRect(), Qt::KeepAspectRatio);
|
|
||||||
_ui->imageView_odometry->fitInView(_ui->imageView_odometry->sceneRect(), Qt::KeepAspectRatio);
|
|
||||||
_ui->imageView_source->resetZoom();
|
|
||||||
_ui->imageView_loopClosure->resetZoom();
|
|
||||||
_ui->imageView_odometry->resetZoom();
|
|
||||||
if(this->isVisible())
|
if(this->isVisible())
|
||||||
{
|
{
|
||||||
this->configGUIModified();
|
this->configGUIModified();
|
||||||
@@ -2485,7 +2442,7 @@ void MainWindow::editDatabase()
|
|||||||
if(!path.isEmpty())
|
if(!path.isEmpty())
|
||||||
{
|
{
|
||||||
DatabaseViewer * viewer = new DatabaseViewer(this);
|
DatabaseViewer * viewer = new DatabaseViewer(this);
|
||||||
viewer->setWindowModality(Qt::WindowModal);
|
viewer->setWindowFlags(Qt::Dialog);
|
||||||
if(viewer->openDatabase(path))
|
if(viewer->openDatabase(path))
|
||||||
{
|
{
|
||||||
if(viewer->isSavedMaximized())
|
if(viewer->isSavedMaximized())
|
||||||
@@ -3774,12 +3731,9 @@ void MainWindow::clearTheCache()
|
|||||||
_ui->imageView_source->clear();
|
_ui->imageView_source->clear();
|
||||||
_ui->imageView_loopClosure->clear();
|
_ui->imageView_loopClosure->clear();
|
||||||
_ui->imageView_odometry->clear();
|
_ui->imageView_odometry->clear();
|
||||||
_ui->imageView_source->resetTransform();
|
_ui->imageView_source->setBackgroundColor(Qt::black);
|
||||||
_ui->imageView_loopClosure->resetTransform();
|
_ui->imageView_loopClosure->setBackgroundColor(Qt::black);
|
||||||
_ui->imageView_odometry->resetTransform();
|
_ui->imageView_odometry->setBackgroundColor(Qt::black);
|
||||||
_ui->imageView_source->setBackgroundBrush(QBrush(Qt::black));
|
|
||||||
_ui->imageView_loopClosure->setBackgroundBrush(QBrush(Qt::black));
|
|
||||||
_ui->imageView_odometry->setBackgroundBrush(QBrush(Qt::black));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateElapsedTime()
|
void MainWindow::updateElapsedTime()
|
||||||
|
|||||||
@@ -1261,6 +1261,27 @@ bool PreferencesDialog::readCoreSettings(const QString & filePath)
|
|||||||
QString value = settings.value(key, "").toString();
|
QString value = settings.value(key, "").toString();
|
||||||
if(!value.isEmpty())
|
if(!value.isEmpty())
|
||||||
{
|
{
|
||||||
|
if(key.toStdString().compare(Parameters::kRtabmapWorkingDirectory()) == 0)
|
||||||
|
{
|
||||||
|
// The directory should exist if not the default one
|
||||||
|
if(!QDir(value).exists() && value.compare(Parameters::defaultRtabmapWorkingDirectory().c_str()) != 0)
|
||||||
|
{
|
||||||
|
if(QDir(this->getWorkingDirectory().toStdString().c_str()).exists())
|
||||||
|
{
|
||||||
|
UWARN("Reading config: Not existing working directory \"%s\". Keeping old one (\"%s\").",
|
||||||
|
value.toStdString().c_str(),
|
||||||
|
this->getWorkingDirectory().toStdString().c_str());
|
||||||
|
value = this->getWorkingDirectory();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UWARN("Reading config: Not existing working directory \"%s\". Using default one (\"%s\").",
|
||||||
|
value.toStdString().c_str(),
|
||||||
|
(*iter).second.c_str());
|
||||||
|
value = (*iter).second.c_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
this->setParameter(key.toStdString(), value.toStdString());
|
this->setParameter(key.toStdString(), value.toStdString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1182</width>
|
<width>1182</width>
|
||||||
<height>804</height>
|
<height>821</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_7" stretch="2">
|
<layout class="QVBoxLayout" name="verticalLayout_7" stretch="2">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,1">
|
||||||
<property name="rightMargin">
|
<property name="rightMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="rtabmap::ImageView" name="graphicsView_A"/>
|
<widget class="rtabmap::ImageView" name="graphicsView_A" native="true"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QScrollArea" name="scrollArea_2">
|
<widget class="QScrollArea" name="scrollArea_2">
|
||||||
@@ -41,8 +41,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>136</width>
|
<width>153</width>
|
||||||
<height>127</height>
|
<height>136</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
|
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
|
||||||
@@ -122,7 +122,16 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<property name="margin">
|
<property name="leftMargin">
|
||||||
|
<number>12</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>12</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>12</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
<number>12</number>
|
<number>12</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
@@ -181,7 +190,7 @@
|
|||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="rtabmap::ImageView" name="graphicsView_B"/>
|
<widget class="rtabmap::ImageView" name="graphicsView_B" native="true"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QScrollArea" name="scrollArea">
|
<widget class="QScrollArea" name="scrollArea">
|
||||||
@@ -196,8 +205,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>137</width>
|
<width>152</width>
|
||||||
<height>127</height>
|
<height>136</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,1">
|
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,1">
|
||||||
@@ -277,7 +286,16 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<property name="margin">
|
<property name="leftMargin">
|
||||||
|
<number>12</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>12</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>12</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
<number>12</number>
|
<number>12</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
@@ -340,7 +358,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1182</width>
|
<width>1182</width>
|
||||||
<height>25</height>
|
<height>22</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="menuFile">
|
<widget class="QMenu" name="menuFile">
|
||||||
@@ -1124,9 +1142,9 @@
|
|||||||
<number>4</number>
|
<number>4</number>
|
||||||
</attribute>
|
</attribute>
|
||||||
<widget class="QWidget" name="dockWidgetContents_5">
|
<widget class="QWidget" name="dockWidgetContents_5">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
<layout class="QHBoxLayout" name="horizontalLayout_6" stretch="1,1">
|
||||||
<item>
|
<item>
|
||||||
<widget class="rtabmap::ImageView" name="graphicsView_stereo"/>
|
<widget class="rtabmap::ImageView" name="graphicsView_stereo" native="true"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="rtabmap::CloudViewer" name="stereoViewer" native="true"/>
|
<widget class="rtabmap::CloudViewer" name="stereoViewer" native="true"/>
|
||||||
@@ -1142,7 +1160,7 @@
|
|||||||
<number>4</number>
|
<number>4</number>
|
||||||
</attribute>
|
</attribute>
|
||||||
<widget class="QWidget" name="dockWidgetContents_6">
|
<widget class="QWidget" name="dockWidgetContents_6">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
<layout class="QHBoxLayout" name="horizontalLayout_8" stretch="1,1">
|
||||||
<item>
|
<item>
|
||||||
<widget class="rtabmap::CloudViewer" name="widget_cloudA" native="true"/>
|
<widget class="rtabmap::CloudViewer" name="widget_cloudA" native="true"/>
|
||||||
</item>
|
</item>
|
||||||
@@ -1679,7 +1697,7 @@
|
|||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>rtabmap::ImageView</class>
|
<class>rtabmap::ImageView</class>
|
||||||
<extends>QGraphicsView</extends>
|
<extends>QWidget</extends>
|
||||||
<header>rtabmap/gui/ImageView.h</header>
|
<header>rtabmap/gui/ImageView.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
|||||||
+11
-28
@@ -45,8 +45,6 @@
|
|||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionClose_database"/>
|
<addaction name="actionClose_database"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionEdit_database"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionExit"/>
|
<addaction name="actionExit"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuEdit">
|
<widget class="QMenu" name="menuEdit">
|
||||||
@@ -194,8 +192,11 @@
|
|||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Tools</string>
|
<string>Tools</string>
|
||||||
</property>
|
</property>
|
||||||
<addaction name="actionPost_processing"/>
|
<addaction name="actionEdit_database"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
<addaction name="actionData_recorder"/>
|
<addaction name="actionData_recorder"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionPost_processing"/>
|
||||||
</widget>
|
</widget>
|
||||||
<addaction name="menuFile"/>
|
<addaction name="menuFile"/>
|
||||||
<addaction name="menuEdit"/>
|
<addaction name="menuEdit"/>
|
||||||
@@ -735,7 +736,7 @@
|
|||||||
<number>1</number>
|
<number>1</number>
|
||||||
</attribute>
|
</attribute>
|
||||||
<widget class="QWidget" name="layout_imageview">
|
<widget class="QWidget" name="layout_imageview">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,1">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
@@ -752,7 +753,7 @@
|
|||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
@@ -773,19 +774,12 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="rtabmap::ImageView" name="imageView_source">
|
<widget class="rtabmap::ImageView" name="imageView_source" native="true"/>
|
||||||
<property name="verticalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="horizontalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
@@ -806,14 +800,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="rtabmap::ImageView" name="imageView_loopClosure">
|
<widget class="rtabmap::ImageView" name="imageView_loopClosure" native="true"/>
|
||||||
<property name="verticalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="horizontalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
@@ -845,7 +832,7 @@
|
|||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="rtabmap::ImageView" name="imageView_odometry"/>
|
<widget class="rtabmap::ImageView" name="imageView_odometry" native="true"/>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
@@ -1239,10 +1226,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionEdit_database">
|
<action name="actionEdit_database">
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="../GuiLib.qrc">
|
|
||||||
<normaloff>:/images/document-properties.png</normaloff>:/images/document-properties.png</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Edit database...</string>
|
<string>Edit database...</string>
|
||||||
</property>
|
</property>
|
||||||
@@ -1275,7 +1258,7 @@
|
|||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>rtabmap::ImageView</class>
|
<class>rtabmap::ImageView</class>
|
||||||
<extends>QGraphicsView</extends>
|
<extends>QWidget</extends>
|
||||||
<header>../include/rtabmap/gui/ImageView.h</header>
|
<header>../include/rtabmap/gui/ImageView.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ int main (int argc, char * argv[])
|
|||||||
recorder.registerToEventsManager();
|
recorder.registerToEventsManager();
|
||||||
if(show)
|
if(show)
|
||||||
{
|
{
|
||||||
recorder.setWindowTitle("Cloud viewer");
|
recorder.setWindowTitle("Data recorder");
|
||||||
recorder.setMinimumWidth(500);
|
recorder.setMinimumWidth(500);
|
||||||
recorder.setMinimumHeight(300);
|
recorder.setMinimumHeight(300);
|
||||||
recorder.showNormal();
|
recorder.showNormal();
|
||||||
|
|||||||
@@ -641,22 +641,13 @@ public:
|
|||||||
this->layout()->setSpacing(0);
|
this->layout()->setSpacing(0);
|
||||||
this->layout()->setContentsMargins(0,0,0,0);
|
this->layout()->setContentsMargins(0,0,0,0);
|
||||||
this->layout()->addWidget(view1_);
|
this->layout()->addWidget(view1_);
|
||||||
view1_->setSceneRect(0,0,(float)image1.cols, (float)image1.rows);
|
view1_->setSceneRect(QRectF(0,0,(float)image1.cols, (float)image1.rows));
|
||||||
view1_->setLinesShown(true);
|
view1_->setLinesShown(true);
|
||||||
view1_->setFeaturesShown(false);
|
view1_->setFeaturesShown(false);
|
||||||
|
view1_->setImageDepthShown(true);
|
||||||
|
|
||||||
QGraphicsPixmapItem * item1 = view1_->scene()->addPixmap(QPixmap::fromImage(uCvMat2QImage(image1)));
|
view1_->setImage(uCvMat2QImage(image1));
|
||||||
QGraphicsPixmapItem * item2 = view1_->scene()->addPixmap(QPixmap::fromImage(uCvMat2QImage(image2)));
|
view1_->setImageDepth(uCvMat2QImage(image2));
|
||||||
|
|
||||||
QGraphicsOpacityEffect * effect1 = new QGraphicsOpacityEffect();
|
|
||||||
QGraphicsOpacityEffect * effect2 = new QGraphicsOpacityEffect();
|
|
||||||
effect1->setOpacity(0.5);
|
|
||||||
effect2->setOpacity(0.5);
|
|
||||||
item1->setGraphicsEffect(effect1);
|
|
||||||
item2->setGraphicsEffect(effect2);
|
|
||||||
|
|
||||||
item1->setVisible(view1_->isImageShown());
|
|
||||||
item2->setVisible(view1_->isImageShown());
|
|
||||||
|
|
||||||
drawKeypoints(words1, words2, status);
|
drawKeypoints(words1, words2, status);
|
||||||
}
|
}
|
||||||
@@ -665,59 +656,41 @@ protected:
|
|||||||
{
|
{
|
||||||
resizeEvent(0);
|
resizeEvent(0);
|
||||||
}
|
}
|
||||||
virtual void resizeEvent(QResizeEvent* event)
|
|
||||||
{
|
|
||||||
view1_->fitInView(view1_->sceneRect(), Qt::KeepAspectRatio);
|
|
||||||
view1_->resetZoom();
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
void drawKeypoints(const std::multimap<int, cv::KeyPoint> & refWords, const std::multimap<int, cv::KeyPoint> & loopWords, const std::vector<uchar> & status)
|
void drawKeypoints(const std::multimap<int, cv::KeyPoint> & refWords, const std::multimap<int, cv::KeyPoint> & loopWords, const std::vector<uchar> & status)
|
||||||
{
|
{
|
||||||
UTimer timer;
|
UTimer timer;
|
||||||
|
|
||||||
timer.start();
|
timer.start();
|
||||||
KeypointItem * item = 0;
|
|
||||||
int alpha = 10*255/100;
|
|
||||||
QList<QPair<cv::Point2f, cv::Point2f> > uniqueCorrespondences;
|
QList<QPair<cv::Point2f, cv::Point2f> > uniqueCorrespondences;
|
||||||
QList<bool> inliers;
|
QList<bool> inliers;
|
||||||
int j=0;
|
int j=0;
|
||||||
for(std::multimap<int, cv::KeyPoint>::const_iterator i = refWords.begin(); i != refWords.end(); ++i )
|
for(std::multimap<int, cv::KeyPoint>::const_iterator i = refWords.begin(); i != refWords.end(); ++i )
|
||||||
{
|
{
|
||||||
const cv::KeyPoint & r = (*i).second;
|
|
||||||
int id = (*i).first;
|
int id = (*i).first;
|
||||||
|
QColor color;
|
||||||
QString info = QString( "WordRef = %1\n"
|
|
||||||
"Laplacian = %2\n"
|
|
||||||
"Dir = %3\n"
|
|
||||||
"Hessian = %4\n"
|
|
||||||
"X = %5\n"
|
|
||||||
"Y = %6\n"
|
|
||||||
"Size = %7").arg(id).arg(1).arg(r.angle).arg(r.response).arg(r.pt.x).arg(r.pt.y).arg(r.size);
|
|
||||||
float radius = r.size*1.2/9.*2;
|
|
||||||
if(uContains(loopWords, id))
|
if(uContains(loopWords, id))
|
||||||
{
|
{
|
||||||
// PINK = FOUND IN LOOP SIGNATURE
|
// PINK = FOUND IN LOOP SIGNATURE
|
||||||
item = new KeypointItem(r.pt.x-radius, r.pt.y-radius, radius*2, info, QColor(255, 0, 255, alpha));
|
color = Qt::magenta;
|
||||||
//To draw lines... get only unique correspondences
|
//To draw lines... get only unique correspondences
|
||||||
if(uValues(refWords, id).size() == 1 && uValues(loopWords, id).size() == 1)
|
if(uValues(refWords, id).size() == 1 && uValues(loopWords, id).size() == 1)
|
||||||
{
|
{
|
||||||
uniqueCorrespondences.push_back(QPair<cv::Point2f, cv::Point2f>(r.pt, uValues(loopWords, id).begin()->pt));
|
uniqueCorrespondences.push_back(QPair<cv::Point2f, cv::Point2f>(i->second.pt, uValues(loopWords, id).begin()->pt));
|
||||||
inliers.push_back(status[j++]);
|
inliers.push_back(status[j++]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(refWords.count(id) > 1)
|
else if(refWords.count(id) > 1)
|
||||||
{
|
{
|
||||||
// YELLOW = NEW and multiple times
|
// YELLOW = NEW and multiple times
|
||||||
item = new KeypointItem(r.pt.x-radius, r.pt.y-radius, radius*2, info, QColor(255, 255, 0, alpha));
|
color = Qt::yellow;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// GREEN = NEW
|
// GREEN = NEW
|
||||||
item = new KeypointItem(r.pt.x-radius, r.pt.y-radius, radius*2, info, QColor(0, 255, 0, alpha));
|
color = Qt::green;
|
||||||
}
|
}
|
||||||
item->setVisible(view1_->isFeaturesShown());
|
view1_->addFeature(id, i->second, color);
|
||||||
view1_->scene()->addItem(item);
|
|
||||||
item->setZValue(1);
|
|
||||||
}
|
}
|
||||||
ULOGGER_DEBUG("source time = %f s", timer.ticks());
|
ULOGGER_DEBUG("source time = %f s", timer.ticks());
|
||||||
|
|
||||||
@@ -728,16 +701,15 @@ private:
|
|||||||
iter!=uniqueCorrespondences.end();
|
iter!=uniqueCorrespondences.end();
|
||||||
++iter)
|
++iter)
|
||||||
{
|
{
|
||||||
QGraphicsLineItem * item = view1_->scene()->addLine(
|
view1_->addLine(
|
||||||
iter->first.x,
|
iter->first.x,
|
||||||
iter->first.y,
|
iter->first.y,
|
||||||
iter->second.x,
|
iter->second.x,
|
||||||
iter->second.y,
|
iter->second.y,
|
||||||
*jter?QPen(Qt::cyan):QPen(Qt::red));
|
*jter?Qt::cyan:Qt::red);
|
||||||
item->setVisible(view1_->isLinesShown());
|
|
||||||
item->setZValue(1);
|
|
||||||
++jter;
|
++jter;
|
||||||
}
|
}
|
||||||
|
view1_->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
Reference in New Issue
Block a user