ImageView.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007     * Redistributions of source code must retain the above copyright
00008       notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright
00010       notice, this list of conditions and the following disclaimer in the
00011       documentation and/or other materials provided with the distribution.
00012     * Neither the name of the Universite de Sherbrooke nor the
00013       names of its contributors may be used to endorse or promote products
00014       derived from this software without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00017 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
00020 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00021 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00022 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00023 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00025 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 */
00027 
00028 #include "rtabmap/gui/ImageView.h"
00029 
00030 #include <QtGui/QWheelEvent>
00031 #include <QtCore/qmath.h>
00032 #include <QMenu>
00033 #include <QFileDialog>
00034 #include <QtCore/QDir>
00035 #include <QAction>
00036 #include <QGraphicsEffect>
00037 #include <QInputDialog>
00038 #include <QVBoxLayout>
00039 #include <QGraphicsRectItem>
00040 #include "rtabmap/utilite/ULogger.h"
00041 #include "rtabmap/utilite/UCv2Qt.h"
00042 #include "rtabmap/gui/KeypointItem.h"
00043 #include "rtabmap/core/util2d.h"
00044 
00045 namespace rtabmap {
00046 
00047 //LineItem
00048 class LineItem : public QGraphicsLineItem
00049 {
00050 public:
00051         LineItem(float x1, float y1, float x2, float y2, const QString & text = QString(), QGraphicsItem * parent = 0) :
00052                 QGraphicsLineItem(x1, y1, x2, y2, parent),
00053                 _text(text),
00054                 _placeHolder(0)
00055         {
00056                 this->setAcceptHoverEvents(true);
00057                 this->setFlag(QGraphicsItem::ItemIsFocusable, true);
00058                 _width = pen().width();
00059         }
00060         virtual ~LineItem()
00061         {
00062                 delete _placeHolder;
00063         }
00064 
00065         void setColor(const QColor & color);
00066 
00067 protected:
00068         virtual void hoverEnterEvent ( QGraphicsSceneHoverEvent * event )
00069         {
00070                 QGraphicsScene * scene = this->scene();
00071                 if(scene && scene->focusItem() == 0)
00072                 {
00073                         this->showDescription();
00074                 }
00075                 else
00076                 {
00077                         this->setPen(QPen(pen().color(), _width+2));
00078                 }
00079                 QGraphicsLineItem::hoverEnterEvent(event);
00080         }
00081 
00082         virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event )
00083         {
00084                 if(!this->hasFocus())
00085                 {
00086                         this->hideDescription();
00087                 }
00088                 QGraphicsLineItem::hoverEnterEvent(event);
00089         }
00090 
00091         virtual void focusInEvent ( QFocusEvent * event )
00092         {
00093                 this->showDescription();
00094                 QGraphicsLineItem::focusInEvent(event);
00095         }
00096 
00097         virtual void focusOutEvent ( QFocusEvent * event )
00098         {
00099                 this->hideDescription();
00100                 QGraphicsLineItem::focusOutEvent(event);
00101         }
00102 
00103 private:
00104         void showDescription()
00105         {
00106                 if(!_text.isEmpty())
00107                 {
00108                         if(!_placeHolder)
00109                         {
00110                                 _placeHolder = new QGraphicsRectItem (this);
00111                                 _placeHolder->setVisible(false);
00112                                 if(qGray(pen().color().rgb() > 255/2))
00113                                 {
00114                                         _placeHolder->setBrush(QBrush(QColor ( 0,0,0, 170 )));
00115                                 }
00116                                 else
00117                                 {
00118                                         _placeHolder->setBrush(QBrush(QColor ( 255, 255, 255, 170 )));
00119                                 }
00120                                 QGraphicsTextItem * text = new QGraphicsTextItem(_placeHolder);
00121                                 text->setDefaultTextColor(this->pen().color().rgb());
00122                                 text->setPlainText(_text);
00123                                 _placeHolder->setRect(text->boundingRect());
00124                         }
00125 
00126                         if(_placeHolder->parentItem())
00127                         {
00128                                 _placeHolder->setParentItem(0); // Make it a to level item
00129                         }
00130                         _placeHolder->setZValue(this->zValue()+1);
00131                         _placeHolder->setPos(this->mapFromScene(0,0));
00132                         _placeHolder->setVisible(true);
00133                 }
00134                 QPen pen = this->pen();
00135                 this->setPen(QPen(pen.color(), _width+2));
00136         }
00137         void hideDescription()
00138         {
00139                 if(_placeHolder)
00140                 {
00141                         _placeHolder->setVisible(false);
00142                 }
00143                 this->setPen(QPen(pen().color(), _width));
00144         }
00145 
00146 private:
00147         QString _text;
00148         QGraphicsRectItem * _placeHolder;
00149         int _width;
00150 };
00151 
00152 ImageView::ImageView(QWidget * parent) :
00153                 QWidget(parent),
00154                 _savedFileName((QDir::homePath()+ "/") + "picture" + ".png"),
00155                 _alpha(50),
00156                 _featuresSize(0.0f),
00157                 _defaultBgColor(Qt::black),
00158                 _imageItem(0),
00159                 _imageDepthItem(0)
00160 {
00161         _graphicsView = new QGraphicsView(this);
00162         _graphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
00163         _graphicsView->setScene(new QGraphicsScene(this));
00164         _graphicsView->setVisible(false);
00165 
00166         this->setLayout(new QVBoxLayout(this));
00167         this->layout()->addWidget(_graphicsView);
00168         this->layout()->setContentsMargins(0,0,0,0);
00169 
00170         _menu = new QMenu(tr(""), this);
00171         _showImage = _menu->addAction(tr("Show image"));
00172         _showImage->setCheckable(true);
00173         _showImage->setChecked(true);
00174         _showImageDepth = _menu->addAction(tr("Show image depth"));
00175         _showImageDepth->setCheckable(true);
00176         _showImageDepth->setChecked(false);
00177         _showFeatures = _menu->addAction(tr("Show features"));
00178         _showFeatures->setCheckable(true);
00179         _showFeatures->setChecked(true);
00180         _setFeaturesSize = _menu->addAction(tr("Set features size..."));
00181         _showLines = _menu->addAction(tr("Show lines"));
00182         _showLines->setCheckable(true);
00183         _showLines->setChecked(true);
00184         _graphicsViewMode = _menu->addAction(tr("Graphics view"));
00185         _graphicsViewMode->setCheckable(true);
00186         _graphicsViewMode->setChecked(false);
00187         _scaleMenu = _menu->addMenu("Scale image");
00188         _scaleMenu->setEnabled(false);
00189         _graphicsViewScaled = _scaleMenu->addAction(tr("Fit in view"));
00190         _graphicsViewScaled->setCheckable(true);
00191         _graphicsViewScaled->setChecked(true);
00192         _graphicsViewScaledToHeight = _scaleMenu->addAction(tr("Fit height"));
00193         _graphicsViewScaledToHeight->setCheckable(true);
00194         _graphicsViewScaledToHeight->setChecked(false);
00195         _graphicsViewNoScaling = _scaleMenu->addAction(tr("No scale"));
00196         _graphicsViewNoScaling->setCheckable(true);
00197         _graphicsViewNoScaling->setChecked(false);
00198         QActionGroup * group = new QActionGroup(this);
00199         group->addAction(_graphicsViewScaled);
00200         group->addAction(_graphicsViewScaledToHeight);
00201         group->addAction(_graphicsViewNoScaling);
00202         QMenu * colorMap = _menu->addMenu("Depth color map");
00203         _colorMapWhiteToBlack = colorMap->addAction(tr("White to black"));
00204         _colorMapWhiteToBlack->setCheckable(true);
00205         _colorMapWhiteToBlack->setChecked(true);
00206         _colorMapBlackToWhite = colorMap->addAction(tr("Black to white"));
00207         _colorMapBlackToWhite->setCheckable(true);
00208         _colorMapBlackToWhite->setChecked(false);
00209         _colorMapRedToBlue = colorMap->addAction(tr("Red to blue"));
00210         _colorMapRedToBlue->setCheckable(true);
00211         _colorMapRedToBlue->setChecked(false);
00212         _colorMapBlueToRed = colorMap->addAction(tr("Blue to red"));
00213         _colorMapBlueToRed->setCheckable(true);
00214         _colorMapBlueToRed->setChecked(false);
00215         group = new QActionGroup(this);
00216         group->addAction(_colorMapWhiteToBlack);
00217         group->addAction(_colorMapBlackToWhite);
00218         group->addAction(_colorMapRedToBlue);
00219         group->addAction(_colorMapBlueToRed);
00220         _setAlpha = _menu->addAction(tr("Set transparency..."));
00221         _saveImage = _menu->addAction(tr("Save picture..."));
00222         _saveImage->setEnabled(false);
00223 
00224         connect(_graphicsView->scene(), SIGNAL(sceneRectChanged(const QRectF &)), this, SLOT(sceneRectChanged(const QRectF &)));
00225 }
00226 
00227 ImageView::~ImageView() {
00228         clear();
00229 }
00230 
00231 void ImageView::saveSettings(QSettings & settings, const QString & group) const
00232 {
00233         if(!group.isEmpty())
00234         {
00235                 settings.beginGroup(group);
00236         }
00237         settings.setValue("image_shown", this->isImageShown());
00238         settings.setValue("depth_shown", this->isImageDepthShown());
00239         settings.setValue("features_shown", this->isFeaturesShown());
00240         settings.setValue("features_size", this->getFeaturesSize());
00241         settings.setValue("lines_shown", this->isLinesShown());
00242         settings.setValue("alpha", this->getAlpha());
00243         settings.setValue("bg_color", this->getDefaultBackgroundColor());
00244         settings.setValue("graphics_view", this->isGraphicsViewMode());
00245         settings.setValue("graphics_view_scale", this->isGraphicsViewScaled());
00246         settings.setValue("graphics_view_scale_to_height", this->isGraphicsViewScaledToHeight());
00247         settings.setValue("colormap", _colorMapWhiteToBlack->isChecked()?0:_colorMapBlackToWhite->isChecked()?1:_colorMapRedToBlue->isChecked()?2:3);
00248         if(!group.isEmpty())
00249         {
00250                 settings.endGroup();
00251         }
00252 }
00253 
00254 void ImageView::loadSettings(QSettings & settings, const QString & group)
00255 {
00256         if(!group.isEmpty())
00257         {
00258                 settings.beginGroup(group);
00259         }
00260         this->setImageShown(settings.value("image_shown", this->isImageShown()).toBool());
00261         this->setImageDepthShown(settings.value("depth_shown", this->isImageDepthShown()).toBool());
00262         this->setFeaturesShown(settings.value("features_shown", this->isFeaturesShown()).toBool());
00263         this->setFeaturesSize(settings.value("features_size", this->getFeaturesSize()).toInt());
00264         this->setLinesShown(settings.value("lines_shown", this->isLinesShown()).toBool());
00265         this->setAlpha(settings.value("alpha", this->getAlpha()).toInt());
00266         this->setDefaultBackgroundColor(settings.value("bg_color", this->getDefaultBackgroundColor()).value<QColor>());
00267         this->setGraphicsViewMode(settings.value("graphics_view", this->isGraphicsViewMode()).toBool());
00268         this->setGraphicsViewScaled(settings.value("graphics_view_scale", this->isGraphicsViewScaled()).toBool());
00269         this->setGraphicsViewScaledToHeight(settings.value("graphics_view_scale_to_height", this->isGraphicsViewScaledToHeight()).toBool());
00270         int colorMap = settings.value("colormap", 0).toInt();
00271         _colorMapWhiteToBlack->setChecked(colorMap==0);
00272         _colorMapBlackToWhite->setChecked(colorMap==1);
00273         _colorMapRedToBlue->setChecked(colorMap==2);
00274         _colorMapBlueToRed->setChecked(colorMap==3);
00275         if(!group.isEmpty())
00276         {
00277                 settings.endGroup();
00278         }
00279 }
00280 
00281 QRectF ImageView::sceneRect() const
00282 {
00283         return _graphicsView->scene()->sceneRect();
00284 }
00285 
00286 bool ImageView::isImageShown() const
00287 {
00288         return _showImage->isChecked();
00289 }
00290 
00291 bool ImageView::isImageDepthShown() const
00292 {
00293         return _showImageDepth->isChecked();
00294 }
00295 
00296 bool ImageView::isFeaturesShown() const
00297 {
00298         return _showFeatures->isChecked();
00299 }
00300 
00301 bool ImageView::isGraphicsViewMode() const
00302 {
00303         return _graphicsViewMode->isChecked();
00304 }
00305 
00306 bool ImageView::isGraphicsViewScaled() const
00307 {
00308         return _graphicsViewScaled->isChecked();
00309 }
00310 
00311 bool ImageView::isGraphicsViewScaledToHeight() const
00312 {
00313         return _graphicsViewScaledToHeight->isChecked();
00314 }
00315 
00316 const QColor & ImageView::getDefaultBackgroundColor() const
00317 {
00318         return _defaultBgColor;
00319 }
00320 
00321 const QColor & ImageView::getBackgroundColor() const
00322 {
00323         return _graphicsView->backgroundBrush().color();
00324 }
00325 
00326 
00327 void ImageView::setFeaturesShown(bool shown)
00328 {
00329         _showFeatures->setChecked(shown);
00330         for(QMultiMap<int, KeypointItem*>::iterator iter=_features.begin(); iter!=_features.end(); ++iter)
00331         {
00332                 iter.value()->setVisible(_showFeatures->isChecked());
00333         }
00334 
00335         if(!_graphicsView->isVisible())
00336         {
00337                 this->update();
00338         }
00339 }
00340 
00341 void ImageView::setImageShown(bool shown)
00342 {
00343         _showImage->setChecked(shown);
00344         if(_imageItem)
00345         {
00346                 _imageItem->setVisible(_showImage->isChecked());
00347                 this->updateOpacity();
00348         }
00349 
00350         if(!_graphicsView->isVisible())
00351         {
00352                 this->update();
00353         }
00354 }
00355 
00356 void ImageView::setImageDepthShown(bool shown)
00357 {
00358         _showImageDepth->setChecked(shown);
00359         if(_imageDepthItem)
00360         {
00361                 _imageDepthItem->setVisible(_showImageDepth->isChecked());
00362                 this->updateOpacity();
00363         }
00364 
00365         if(!_graphicsView->isVisible())
00366         {
00367                 this->update();
00368         }
00369 }
00370 
00371 bool ImageView::isLinesShown() const
00372 {
00373         return _showLines->isChecked();
00374 }
00375 
00376 void ImageView::setLinesShown(bool shown)
00377 {
00378         _showLines->setChecked(shown);
00379         for(int i=0; i<_lines.size(); ++i)
00380         {
00381                 _lines.at(i)->setVisible(_showLines->isChecked());
00382         }
00383 
00384         if(!_graphicsView->isVisible())
00385         {
00386                 this->update();
00387         }
00388 }
00389 
00390 float ImageView::viewScale() const
00391 {
00392         if(_graphicsView->isVisible())
00393         {
00394                 return _graphicsView->transform().m11();
00395         }
00396         else
00397         {
00398                 float scale, offsetX, offsetY;
00399                 computeScaleOffsets(this->rect(), scale, offsetX, offsetY);
00400                 return scale;
00401         }
00402 }
00403 
00404 void ImageView::setGraphicsViewMode(bool on)
00405 {
00406         _graphicsViewMode->setChecked(on);
00407         _graphicsView->setVisible(on);
00408         _scaleMenu->setEnabled(on);
00409 
00410         if(on)
00411         {
00412                 for(QMultiMap<int, KeypointItem*>::iterator iter=_features.begin(); iter!=_features.end(); ++iter)
00413                 {
00414                         _graphicsView->scene()->addItem(iter.value());
00415                 }
00416 
00417                 for(QList<QGraphicsLineItem*>::iterator iter=_lines.begin(); iter!=_lines.end(); ++iter)
00418                 {
00419                         _graphicsView->scene()->addItem(*iter);
00420                 }
00421 
00422                 //update images
00423                 if(_imageItem)
00424                 {
00425                         _imageItem->setPixmap(_image);
00426                 }
00427                 else
00428                 {
00429                         _imageItem = _graphicsView->scene()->addPixmap(_image);
00430                         _imageItem->setVisible(_showImage->isChecked());
00431                 }
00432 
00433                 if(_imageDepthItem)
00434                 {
00435                         _imageDepthItem->setPixmap(_imageDepth);
00436                 }
00437                 else
00438                 {
00439                         _imageDepthItem = _graphicsView->scene()->addPixmap(_imageDepth);
00440                         _imageDepthItem->setVisible(_showImageDepth->isChecked());
00441                 }
00442                 this->updateOpacity();
00443 
00444                 if(_graphicsViewScaled->isChecked())
00445                 {
00446                         _graphicsView->fitInView(_graphicsView->sceneRect(), Qt::KeepAspectRatio);
00447                 }
00448                 else if(_graphicsViewScaledToHeight->isChecked())
00449                 {
00450                         QRectF rect = _graphicsView->sceneRect();
00451                         rect.setWidth(1);
00452                         _graphicsView->fitInView(rect, Qt::KeepAspectRatio);
00453                 }
00454                 else
00455                 {
00456                         _graphicsView->resetTransform();
00457                 }
00458         }
00459         else
00460         {
00461                 this->update();
00462         }
00463 }
00464 
00465 void ImageView::setGraphicsViewScaled(bool scaled)
00466 {
00467         _graphicsViewScaled->setChecked(scaled);
00468 
00469         if(scaled)
00470         {
00471                 _graphicsView->fitInView(_graphicsView->sceneRect(), Qt::KeepAspectRatio);
00472         }
00473         else
00474         {
00475                 _graphicsView->resetTransform();
00476         }
00477 
00478         if(!_graphicsView->isVisible())
00479         {
00480                 this->update();
00481         }
00482 }
00483 
00484 void ImageView::setGraphicsViewScaledToHeight(bool scaled)
00485 {
00486         _graphicsViewScaledToHeight->setChecked(scaled);
00487 
00488         if(scaled)
00489         {
00490                 QRectF rect = _graphicsView->sceneRect();
00491                 rect.setWidth(1);
00492                 _graphicsView->fitInView(rect, Qt::KeepAspectRatio);
00493         }
00494         else
00495         {
00496                 _graphicsView->resetTransform();
00497         }
00498 
00499         if(!_graphicsView->isVisible())
00500         {
00501                 this->update();
00502         }
00503 }
00504 
00505 void ImageView::setDefaultBackgroundColor(const QColor & color)
00506 {
00507         _defaultBgColor = color;
00508         setBackgroundColor(color);
00509 }
00510 
00511 void ImageView::setBackgroundColor(const QColor & color)
00512 {
00513         _graphicsView->setBackgroundBrush(QBrush(color));
00514 
00515         if(!_graphicsView->isVisible())
00516         {
00517                 this->update();
00518         }
00519 }
00520 
00521 void ImageView::computeScaleOffsets(const QRect & targetRect, float & scale, float & offsetX, float & offsetY) const
00522 {
00523         scale = 1.0f;
00524         offsetX = 0.0f;
00525         offsetY = 0.0f;
00526 
00527         if(!_graphicsView->scene()->sceneRect().isNull())
00528         {
00529                 float w = _graphicsView->scene()->width();
00530                 float h = _graphicsView->scene()->height();
00531                 float widthRatio = float(targetRect.width()) / w;
00532                 float heightRatio = float(targetRect.height()) / h;
00533 
00534                 //printf("w=%f, h=%f, wR=%f, hR=%f, sW=%d, sH=%d\n", w, h, widthRatio, heightRatio, this->rect().width(), this->rect().height());
00535                 if(widthRatio < heightRatio)
00536                 {
00537                         scale = widthRatio;
00538                 }
00539                 else
00540                 {
00541                         scale = heightRatio;
00542                 }
00543 
00544                 //printf("ratio=%f\n",ratio);
00545 
00546                 w *= scale;
00547                 h *= scale;
00548 
00549                 if(w < targetRect.width())
00550                 {
00551                         offsetX = (targetRect.width() - w)/2.0f;
00552                 }
00553                 if(h < targetRect.height())
00554                 {
00555                         offsetY = (targetRect.height() - h)/2.0f;
00556                 }
00557                 //printf("offsetX=%f, offsetY=%f\n",offsetX, offsetY);
00558         }
00559 }
00560 
00561 void ImageView::sceneRectChanged(const QRectF & rect)
00562 {
00563         _saveImage->setEnabled(rect.isValid());
00564 }
00565 
00566 void ImageView::paintEvent(QPaintEvent *event)
00567 {
00568         if(_graphicsViewMode->isChecked())
00569         {
00570                 QWidget::paintEvent(event);
00571         }
00572         else
00573         {
00574                 if(!_graphicsView->scene()->sceneRect().isNull())
00575                 {
00576                         //Scale
00577                         float ratio, offsetX, offsetY;
00578                         this->computeScaleOffsets(event->rect(), ratio, offsetX, offsetY);
00579                         QPainter painter(this);
00580 
00581                         //Background
00582                         painter.save();
00583                         painter.setBrush(_graphicsView->backgroundBrush());
00584                         painter.drawRect(event->rect());
00585                         painter.restore();
00586 
00587                         painter.translate(offsetX, offsetY);
00588                         painter.scale(ratio, ratio);
00589 
00590                         painter.save();
00591                         if(_showImage->isChecked() && !_image.isNull() &&
00592                            _showImageDepth->isChecked() && !_imageDepth.isNull())
00593                         {
00594                                 painter.setOpacity(0.5);
00595                         }
00596 
00597                         if(_showImage->isChecked() && !_image.isNull())
00598                         {
00599                                 painter.drawPixmap(QPoint(0,0), _image);
00600                         }
00601 
00602                         if(_showImageDepth->isChecked() && !_imageDepth.isNull())
00603                         {
00604                                 painter.drawPixmap(QPoint(0,0), _imageDepth);
00605                         }
00606                         painter.restore();
00607 
00608                         if(_showFeatures->isChecked())
00609                         {
00610                                 for(QMultiMap<int, rtabmap::KeypointItem *>::iterator iter = _features.begin(); iter != _features.end(); ++iter)
00611                                 {
00612                                         QColor color = iter.value()->pen().color();
00613                                         painter.save();
00614                                         painter.setPen(color);
00615                                         painter.setBrush(color);
00616                                         painter.drawEllipse(iter.value()->rect());
00617                                         painter.restore();
00618                                 }
00619                         }
00620 
00621                         if(_showLines->isChecked())
00622                         {
00623                                 for(QList<QGraphicsLineItem*>::iterator iter = _lines.begin(); iter != _lines.end(); ++iter)
00624                                 {
00625                                         QColor color = (*iter)->pen().color();
00626                                         painter.save();
00627                                         painter.setPen(color);
00628                                         painter.drawLine((*iter)->line());
00629                                         painter.restore();
00630                                 }
00631                         }
00632                 }
00633         }
00634 }
00635 
00636 void ImageView::resizeEvent(QResizeEvent* event)
00637 {
00638         QWidget::resizeEvent(event);
00639         if(_graphicsView->isVisible())
00640         {
00641                 if(_graphicsViewScaled->isChecked())
00642                 {
00643                         _graphicsView->fitInView(_graphicsView->sceneRect(), Qt::KeepAspectRatio);
00644                 }
00645                 else if(_graphicsViewScaledToHeight->isChecked())
00646                 {
00647                         QRectF rect = _graphicsView->sceneRect();
00648                         rect.setWidth(1);
00649                         _graphicsView->fitInView(rect, Qt::KeepAspectRatio);
00650                 }
00651         }
00652 }
00653 
00654 void ImageView::contextMenuEvent(QContextMenuEvent * e)
00655 {
00656         QAction * action = _menu->exec(e->globalPos());
00657         if(action == _saveImage)
00658         {
00659                 if(!_graphicsView->scene()->sceneRect().isNull())
00660                 {
00661                         QString text;
00662 #ifdef QT_SVG_LIB
00663                         text = QFileDialog::getSaveFileName(this, tr("Save figure to ..."), _savedFileName, "*.png *.xpm *.jpg *.pdf *.svg");
00664 #else
00665                         text = QFileDialog::getSaveFileName(this, tr("Save figure to ..."), _savedFileName, "*.png *.xpm *.jpg *.pdf");
00666 #endif
00667                         if(!text.isEmpty())
00668                         {
00669                                 _savedFileName = text;
00670                                 QImage img(_graphicsView->sceneRect().width(), _graphicsView->sceneRect().height(), QImage::Format_ARGB32_Premultiplied);
00671                                 QPainter p(&img);
00672                                 if(_graphicsView->isVisible())
00673                                 {
00674                                         _graphicsView->scene()->render(&p, _graphicsView->sceneRect(), _graphicsView->sceneRect());
00675                                 }
00676                                 else
00677                                 {
00678                                         this->render(&p, QPoint(), _graphicsView->sceneRect().toRect());
00679                                 }
00680                                 img.save(text);
00681                         }
00682                 }
00683         }
00684         else if(action == _showFeatures)
00685         {
00686                 this->setFeaturesShown(_showFeatures->isChecked());
00687                 Q_EMIT configChanged();
00688         }
00689         else if(action == _showImage)
00690         {
00691                 this->setImageShown(_showImage->isChecked());
00692                 Q_EMIT configChanged();
00693         }
00694         else if(action == _showImageDepth)
00695         {
00696                 this->setImageDepthShown(_showImageDepth->isChecked());
00697                 Q_EMIT configChanged();
00698         }
00699         else if(action == _showLines)
00700         {
00701                 this->setLinesShown(_showLines->isChecked());
00702                 Q_EMIT configChanged();
00703         }
00704         else if(action == _graphicsViewMode)
00705         {
00706                 this->setGraphicsViewMode(_graphicsViewMode->isChecked());
00707                 Q_EMIT configChanged();
00708         }
00709         else if(action == _graphicsViewScaled)
00710         {
00711                 this->setGraphicsViewScaled(_graphicsViewScaled->isChecked());
00712                 Q_EMIT configChanged();
00713         }
00714         else if(action == _graphicsViewScaledToHeight || action == _graphicsViewNoScaling)
00715         {
00716                 this->setGraphicsViewScaledToHeight(_graphicsViewScaledToHeight->isChecked());
00717                 Q_EMIT configChanged();
00718         }
00719         else if(action == _colorMapBlackToWhite || action == _colorMapWhiteToBlack || action == _colorMapRedToBlue || action == _colorMapBlueToRed)
00720         {
00721                 if(!_imageDepthCv.empty())
00722                         this->setImageDepth(_imageDepthCv);
00723                 Q_EMIT configChanged();
00724         }
00725         else if(action == _setAlpha)
00726         {
00727                 bool ok = false;
00728                 int value = QInputDialog::getInt(this, tr("Set features and lines transparency"), tr("alpha (0-255)"), _alpha, 0, 255, 10, &ok);
00729                 if(ok)
00730                 {
00731                         this->setAlpha(value);
00732                         Q_EMIT configChanged();
00733                 }
00734         }
00735         else if(action == _setFeaturesSize)
00736         {
00737                 bool ok = false;
00738                 int value = QInputDialog::getInt(this, tr("Set features size"), tr("Size (0 means actual keypoint size)"), _featuresSize, 0, 999, 1, &ok);
00739                 if(ok)
00740                 {
00741                         this->setFeaturesSize(value);
00742                         Q_EMIT configChanged();
00743                 }
00744         }
00745 
00746         if(action == _showImage || action ==_showImageDepth)
00747         {
00748                 this->updateOpacity();
00749                 Q_EMIT configChanged();
00750         }
00751 }
00752 
00753 void ImageView::updateOpacity()
00754 {
00755         if(_imageItem && _imageDepthItem)
00756         {
00757                 if(_imageItem->isVisible() && _imageDepthItem->isVisible())
00758                 {
00759                         QGraphicsOpacityEffect * effect = new QGraphicsOpacityEffect();
00760                         effect->setOpacity(0.5);
00761                         _imageDepthItem->setGraphicsEffect(effect);
00762                 }
00763                 else
00764                 {
00765                         _imageDepthItem->setGraphicsEffect(0);
00766                 }
00767         }
00768         else if(_imageDepthItem)
00769         {
00770                 _imageDepthItem->setGraphicsEffect(0);
00771         }
00772 }
00773 
00774 void ImageView::setFeatures(const std::multimap<int, cv::KeyPoint> & refWords, const cv::Mat & depth, const QColor & color)
00775 {
00776         clearFeatures();
00777 
00778         float xRatio = 0;
00779         float yRatio = 0;
00780         if (this->sceneRect().isValid() && !depth.empty() && int(this->sceneRect().height()) % depth.rows == 0 && int(this->sceneRect().width()) % depth.cols == 0)
00781         {
00782                 UDEBUG("depth=%dx%d sceneRect=%fx%f", depth.cols, depth.rows, this->sceneRect().width(), this->sceneRect().height());
00783                 xRatio = float(depth.cols)/float(this->sceneRect().width());
00784                 yRatio = float(depth.rows)/float(this->sceneRect().height());
00785                 UDEBUG("xRatio=%f yRatio=%f", xRatio, yRatio);
00786         }
00787 
00788         for(std::multimap<int, cv::KeyPoint>::const_iterator iter = refWords.begin(); iter != refWords.end(); ++iter )
00789         {
00790                 if (xRatio > 0 && yRatio > 0)
00791                 {
00792                         addFeature(iter->first, iter->second, util2d::getDepth(depth, iter->second.pt.x*xRatio, iter->second.pt.y*yRatio, false), color);
00793                 }
00794                 else
00795                 {
00796                         addFeature(iter->first, iter->second, 0, color);
00797                 }
00798         }
00799 
00800         if(!_graphicsView->isVisible())
00801         {
00802                 this->update();
00803         }
00804 }
00805 
00806 void ImageView::setFeatures(const std::vector<cv::KeyPoint> & features, const cv::Mat & depth, const QColor & color)
00807 {
00808         clearFeatures();
00809 
00810         float xRatio = 0;
00811         float yRatio = 0;
00812         if (this->sceneRect().isValid() && !depth.empty() && int(this->sceneRect().height()) % depth.rows == 0 && int(this->sceneRect().width()) % depth.cols == 0)
00813         {
00814                 UDEBUG("depth=%dx%d sceneRect=%fx%f", depth.cols, depth.rows, this->sceneRect().width(), this->sceneRect().height());
00815                 xRatio = float(depth.cols) / float(this->sceneRect().width());
00816                 yRatio = float(depth.rows) / float(this->sceneRect().height());
00817                 UDEBUG("xRatio=%f yRatio=%f", xRatio, yRatio);
00818         }
00819 
00820         for(unsigned int i = 0; i< features.size(); ++i )
00821         {
00822                 if(xRatio > 0 && yRatio > 0)
00823                 {
00824                         addFeature(i, features[i], util2d::getDepth(depth, features[i].pt.x*xRatio, features[i].pt.y*yRatio, false), color);
00825                 }
00826                 else
00827                 {
00828                         addFeature(i, features[i], 0, color);
00829                 }
00830         }
00831 
00832         if(!_graphicsView->isVisible())
00833         {
00834                 this->update();
00835         }
00836 }
00837 
00838 void ImageView::addFeature(int id, const cv::KeyPoint & kpt, float depth, QColor color)
00839 {
00840         color.setAlpha(this->getAlpha());
00841         rtabmap::KeypointItem * item = new rtabmap::KeypointItem(id, kpt, depth, color);
00842         if(_featuresSize>0.0f)
00843         {
00844                 item->setRect(kpt.pt.x-_featuresSize/2.0f, kpt.pt.y-_featuresSize/2.0f, _featuresSize, _featuresSize);
00845         }
00846         _features.insert(id, item);
00847         item->setVisible(isFeaturesShown());
00848         item->setZValue(1);
00849 
00850         if(_graphicsView->isVisible())
00851         {
00852                 _graphicsView->scene()->addItem(item);
00853         }
00854 }
00855 
00856 void ImageView::addLine(float x1, float y1, float x2, float y2, QColor color, const QString & text)
00857 {
00858         color.setAlpha(this->getAlpha());
00859         LineItem * item  = new LineItem(x1, y1, x2, y2, text);
00860         item->setPen(QPen(color));
00861         _lines.push_back(item);
00862         item->setVisible(isLinesShown());
00863         item->setZValue(1);
00864 
00865         if(_graphicsView->isVisible())
00866         {
00867                 _graphicsView->scene()->addItem(item);
00868         }
00869 }
00870 
00871 void ImageView::setImage(const QImage & image)
00872 {
00873         _image = QPixmap::fromImage(image);
00874         if(_graphicsView->isVisible())
00875         {
00876                 if(_imageItem)
00877                 {
00878                         _imageItem->setPixmap(_image);
00879                 }
00880                 else
00881                 {
00882                         _imageItem = _graphicsView->scene()->addPixmap(_image);
00883                         _imageItem->setVisible(_showImage->isChecked());
00884                         this->updateOpacity();
00885                 }
00886         }
00887 
00888         if(image.rect().isValid())
00889         {
00890                 this->setSceneRect(image.rect());
00891         }
00892         else if(!_graphicsView->isVisible())
00893         {
00894                 this->update();
00895         }
00896 }
00897 
00898 void ImageView::setImageDepth(const cv::Mat & imageDepth)
00899 {
00900         _imageDepthCv = imageDepth;
00901         uCvQtDepthColorMap colorMap = uCvQtDepthWhiteToBlack;
00902         if(_colorMapBlackToWhite->isChecked())
00903         {
00904                 colorMap = uCvQtDepthBlackToWhite;
00905         }
00906         else if(_colorMapRedToBlue->isChecked())
00907         {
00908                 colorMap = uCvQtDepthRedToBlue;
00909         }
00910         else if(_colorMapBlueToRed->isChecked())
00911         {
00912                 colorMap = uCvQtDepthBlueToRed;
00913         }
00914         setImageDepth(uCvMat2QImage(_imageDepthCv, true, colorMap));
00915 }
00916 
00917 void ImageView::setImageDepth(const QImage & imageDepth)
00918 {
00919         _imageDepth = QPixmap::fromImage(imageDepth);
00920 
00921         UASSERT(_imageDepth.width() && _imageDepth.height());
00922 
00923         if( _image.width() > 0 &&
00924                 _image.width() > _imageDepth.width() &&
00925                 _image.height() > _imageDepth.height() &&
00926                 _image.width() % _imageDepth.width() == 0 &&
00927                 _image.height() % _imageDepth.height() == 0)
00928         {
00929                 // scale depth to rgb
00930                 _imageDepth = _imageDepth.scaled(_image.size());
00931         }
00932 
00933         if(_graphicsView->isVisible())
00934         {
00935                 if(_imageDepthItem)
00936                 {
00937                         _imageDepthItem->setPixmap(_imageDepth);
00938                 }
00939                 else
00940                 {
00941                         _imageDepthItem = _graphicsView->scene()->addPixmap(_imageDepth);
00942                         _imageDepthItem->setVisible(_showImageDepth->isChecked());
00943                         this->updateOpacity();
00944                 }
00945         }
00946         else
00947         {
00948                 if(_image.isNull())
00949                 {
00950                         this->setSceneRect(imageDepth.rect());
00951                 }
00952                 this->update();
00953         }
00954 }
00955 
00956 void ImageView::setFeatureColor(int id, QColor color)
00957 {
00958         color.setAlpha(getAlpha());
00959         QList<KeypointItem*> items = _features.values(id);
00960         if(items.size())
00961         {
00962                 for(int i=0; i<items.size(); ++i)
00963                 {
00964                         items[i]->setColor(color);
00965                 }
00966         }
00967         else
00968         {
00969                 UWARN("Not found feature %d", id);
00970         }
00971 
00972         if(!_graphicsView->isVisible())
00973         {
00974                 this->update();
00975         }
00976 }
00977 
00978 void ImageView::setFeaturesColor(QColor color)
00979 {
00980         color.setAlpha(getAlpha());
00981         for(QMultiMap<int, KeypointItem*>::iterator iter=_features.begin(); iter!=_features.end(); ++iter)
00982         {
00983                 iter.value()->setColor(color);
00984         }
00985 
00986         if(!_graphicsView->isVisible())
00987         {
00988                 this->update();
00989         }
00990 }
00991 
00992 void ImageView::setAlpha(int alpha)
00993 {
00994         UASSERT(alpha >=0 && alpha <= 255);
00995         _alpha = alpha;
00996         for(QMultiMap<int, KeypointItem*>::iterator iter=_features.begin(); iter!=_features.end(); ++iter)
00997         {
00998                 QColor c = iter.value()->pen().color();
00999                 c.setAlpha(_alpha);
01000                 iter.value()->setPen(QPen(c));
01001                 iter.value()->setBrush(QBrush(c));
01002         }
01003 
01004         for(QList<QGraphicsLineItem*>::iterator iter=_lines.begin(); iter!=_lines.end(); ++iter)
01005         {
01006                 QColor c = (*iter)->pen().color();
01007                 c.setAlpha(_alpha);
01008                 (*iter)->setPen(QPen(c));
01009         }
01010 
01011         if(!_graphicsView->isVisible())
01012         {
01013                 this->update();
01014         }
01015 }
01016 
01017 void ImageView::setFeaturesSize(int size)
01018 {
01019         _featuresSize = size;
01020         for(QMultiMap<int, KeypointItem*>::iterator iter=_features.begin(); iter!=_features.end(); ++iter)
01021         {
01022                 const cv::KeyPoint & kpt = iter.value()->keypoint();
01023                 if(size <= 0.0f)
01024                 {
01025                         size = kpt.size==0?3:kpt.size;
01026                 }
01027                 float sizef = size;
01028                 iter.value()->setRect(kpt.pt.x-sizef/2.0f, kpt.pt.y-sizef/2.0f, sizef, sizef);
01029         }
01030 
01031         if(!_graphicsView->isVisible())
01032         {
01033                 this->update();
01034         }
01035 }
01036 
01037 void ImageView::setSceneRect(const QRectF & rect)
01038 {
01039         _graphicsView->scene()->setSceneRect(rect);
01040 
01041         if(_graphicsViewScaled->isChecked())
01042         {
01043                 _graphicsView->fitInView(_graphicsView->sceneRect(), Qt::KeepAspectRatio);
01044         }
01045         else if(_graphicsViewScaledToHeight->isChecked())
01046         {
01047                 QRectF rect = _graphicsView->sceneRect();
01048                 rect.setWidth(1);
01049                 _graphicsView->fitInView(rect, Qt::KeepAspectRatio);
01050         }
01051         else
01052         {
01053                 _graphicsView->resetTransform();
01054         }
01055 
01056         if(!_graphicsView->isVisible())
01057         {
01058                 this->update();
01059         }
01060 }
01061 
01062 void ImageView::clearLines()
01063 {
01064         qDeleteAll(_lines);
01065         _lines.clear();
01066 
01067         if(!_graphicsView->isVisible())
01068         {
01069                 this->update();
01070         }
01071 }
01072 
01073 void ImageView::clearFeatures()
01074 {
01075         qDeleteAll(_features);
01076         _features.clear();
01077 
01078         if(!_graphicsView->isVisible())
01079         {
01080                 this->update();
01081         }
01082 }
01083 
01084 void ImageView::clear()
01085 {
01086         clearFeatures();
01087 
01088         qDeleteAll(_lines);
01089         _lines.clear();
01090 
01091         if(_imageItem)
01092         {
01093                 _graphicsView->scene()->removeItem(_imageItem);
01094                 delete _imageItem;
01095                 _imageItem = 0;
01096         }
01097         _image = QPixmap();
01098 
01099         if(_imageDepthItem)
01100         {
01101                 _graphicsView->scene()->removeItem(_imageDepthItem);
01102                 delete _imageDepthItem;
01103                 _imageDepthItem = 0;
01104         }
01105         _imageDepth = QPixmap();
01106 
01107         _graphicsView->scene()->setSceneRect(QRectF());
01108         _graphicsView->setScene(_graphicsView->scene());
01109 
01110         if(!_graphicsView->isVisible())
01111         {
01112                 this->update();
01113         }
01114 }
01115 
01116 QSize ImageView::sizeHint() const
01117 {
01118         return _graphicsView->sizeHint();
01119 }
01120 
01121 }


rtabmap
Author(s): Mathieu Labbe
autogenerated on Thu Jun 6 2019 21:59:20