ImageView.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the name of the Universite de Sherbrooke nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 #include "rtabmap/gui/ImageView.h"
29 
30 #include <QtGui/QWheelEvent>
31 #include <QtCore/qmath.h>
32 #include <QMenu>
33 #include <QFileDialog>
34 #include <QtCore/QDir>
35 #include <QAction>
36 #include <QGraphicsEffect>
37 #include <QInputDialog>
38 #include <QVBoxLayout>
39 #include <QGraphicsRectItem>
41 #include "rtabmap/utilite/UCv2Qt.h"
43 #include "rtabmap/core/util2d.h"
44 
45 namespace rtabmap {
46 
47 //LineItem
48 class LineItem : public QGraphicsLineItem
49 {
50 public:
51  LineItem(float x1, float y1, float x2, float y2, const QString & text = QString(), QGraphicsItem * parent = 0) :
52  QGraphicsLineItem(x1, y1, x2, y2, parent),
53  _text(text),
54  _placeHolder(0)
55  {
56  this->setAcceptHoverEvents(true);
57  this->setFlag(QGraphicsItem::ItemIsFocusable, true);
58  _width = pen().width();
59  }
60  virtual ~LineItem()
61  {
62  delete _placeHolder;
63  }
64 
65  void setColor(const QColor & color);
66 
67 protected:
68  virtual void hoverEnterEvent ( QGraphicsSceneHoverEvent * event )
69  {
70  QGraphicsScene * scene = this->scene();
71  if(scene && scene->focusItem() == 0)
72  {
73  this->showDescription();
74  }
75  else
76  {
77  this->setPen(QPen(pen().color(), _width+2));
78  }
79  QGraphicsLineItem::hoverEnterEvent(event);
80  }
81 
82  virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event )
83  {
84  if(!this->hasFocus())
85  {
86  this->hideDescription();
87  }
88  QGraphicsLineItem::hoverEnterEvent(event);
89  }
90 
91  virtual void focusInEvent ( QFocusEvent * event )
92  {
93  this->showDescription();
94  QGraphicsLineItem::focusInEvent(event);
95  }
96 
97  virtual void focusOutEvent ( QFocusEvent * event )
98  {
99  this->hideDescription();
100  QGraphicsLineItem::focusOutEvent(event);
101  }
102 
103 private:
105  {
106  if(!_text.isEmpty())
107  {
108  if(!_placeHolder)
109  {
110  _placeHolder = new QGraphicsRectItem (this);
111  _placeHolder->setVisible(false);
112  if(qGray(pen().color().rgb() > 255/2))
113  {
114  _placeHolder->setBrush(QBrush(QColor ( 0,0,0, 170 )));
115  }
116  else
117  {
118  _placeHolder->setBrush(QBrush(QColor ( 255, 255, 255, 170 )));
119  }
120  QGraphicsTextItem * text = new QGraphicsTextItem(_placeHolder);
121  text->setDefaultTextColor(this->pen().color().rgb());
122  text->setPlainText(_text);
123  _placeHolder->setRect(text->boundingRect());
124  }
125 
126  if(_placeHolder->parentItem())
127  {
128  _placeHolder->setParentItem(0); // Make it a to level item
129  }
130  _placeHolder->setZValue(this->zValue()+1);
131  _placeHolder->setPos(this->mapFromScene(0,0));
132  _placeHolder->setVisible(true);
133  }
134  QPen pen = this->pen();
135  this->setPen(QPen(pen.color(), _width+2));
136  }
138  {
139  if(_placeHolder)
140  {
141  _placeHolder->setVisible(false);
142  }
143  this->setPen(QPen(pen().color(), _width));
144  }
145 
146 private:
147  QString _text;
148  QGraphicsRectItem * _placeHolder;
149  int _width;
150 };
151 
152 ImageView::ImageView(QWidget * parent) :
153  QWidget(parent),
154  _savedFileName((QDir::homePath()+ "/") + "picture" + ".png"),
155  _alpha(50),
156  _featuresSize(0.0f),
157  _defaultBgColor(Qt::black),
158  _imageItem(0),
159  _imageDepthItem(0)
160 {
161  _graphicsView = new QGraphicsView(this);
162  _graphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
163  _graphicsView->setScene(new QGraphicsScene(this));
164  _graphicsView->setVisible(false);
165 
166  this->setLayout(new QVBoxLayout(this));
167  this->layout()->addWidget(_graphicsView);
168  this->layout()->setContentsMargins(0,0,0,0);
169 
170  _menu = new QMenu(tr(""), this);
171  _showImage = _menu->addAction(tr("Show image"));
172  _showImage->setCheckable(true);
173  _showImage->setChecked(true);
174  _showImageDepth = _menu->addAction(tr("Show image depth"));
175  _showImageDepth->setCheckable(true);
176  _showImageDepth->setChecked(false);
177  _showFeatures = _menu->addAction(tr("Show features"));
178  _showFeatures->setCheckable(true);
179  _showFeatures->setChecked(true);
180  _setFeaturesSize = _menu->addAction(tr("Set features size..."));
181  _showLines = _menu->addAction(tr("Show lines"));
182  _showLines->setCheckable(true);
183  _showLines->setChecked(true);
184  _graphicsViewMode = _menu->addAction(tr("Graphics view"));
185  _graphicsViewMode->setCheckable(true);
186  _graphicsViewMode->setChecked(false);
187  _scaleMenu = _menu->addMenu("Scale image");
188  _scaleMenu->setEnabled(false);
189  _graphicsViewScaled = _scaleMenu->addAction(tr("Fit in view"));
190  _graphicsViewScaled->setCheckable(true);
191  _graphicsViewScaled->setChecked(true);
192  _graphicsViewScaledToHeight = _scaleMenu->addAction(tr("Fit height"));
193  _graphicsViewScaledToHeight->setCheckable(true);
194  _graphicsViewScaledToHeight->setChecked(false);
195  _graphicsViewNoScaling = _scaleMenu->addAction(tr("No scale"));
196  _graphicsViewNoScaling->setCheckable(true);
197  _graphicsViewNoScaling->setChecked(false);
198  QActionGroup * group = new QActionGroup(this);
199  group->addAction(_graphicsViewScaled);
200  group->addAction(_graphicsViewScaledToHeight);
201  group->addAction(_graphicsViewNoScaling);
202  QMenu * colorMap = _menu->addMenu("Depth color map");
203  _colorMapWhiteToBlack = colorMap->addAction(tr("White to black"));
204  _colorMapWhiteToBlack->setCheckable(true);
205  _colorMapWhiteToBlack->setChecked(true);
206  _colorMapBlackToWhite = colorMap->addAction(tr("Black to white"));
207  _colorMapBlackToWhite->setCheckable(true);
208  _colorMapBlackToWhite->setChecked(false);
209  _colorMapRedToBlue = colorMap->addAction(tr("Red to blue"));
210  _colorMapRedToBlue->setCheckable(true);
211  _colorMapRedToBlue->setChecked(false);
212  _colorMapBlueToRed = colorMap->addAction(tr("Blue to red"));
213  _colorMapBlueToRed->setCheckable(true);
214  _colorMapBlueToRed->setChecked(false);
215  group = new QActionGroup(this);
216  group->addAction(_colorMapWhiteToBlack);
217  group->addAction(_colorMapBlackToWhite);
218  group->addAction(_colorMapRedToBlue);
219  group->addAction(_colorMapBlueToRed);
220  _setAlpha = _menu->addAction(tr("Set transparency..."));
221  _saveImage = _menu->addAction(tr("Save picture..."));
222  _saveImage->setEnabled(false);
223 
224  connect(_graphicsView->scene(), SIGNAL(sceneRectChanged(const QRectF &)), this, SLOT(sceneRectChanged(const QRectF &)));
225 }
226 
228  clear();
229 }
230 
231 void ImageView::saveSettings(QSettings & settings, const QString & group) const
232 {
233  if(!group.isEmpty())
234  {
235  settings.beginGroup(group);
236  }
237  settings.setValue("image_shown", this->isImageShown());
238  settings.setValue("depth_shown", this->isImageDepthShown());
239  settings.setValue("features_shown", this->isFeaturesShown());
240  settings.setValue("features_size", this->getFeaturesSize());
241  settings.setValue("lines_shown", this->isLinesShown());
242  settings.setValue("alpha", this->getAlpha());
243  settings.setValue("bg_color", this->getDefaultBackgroundColor());
244  settings.setValue("graphics_view", this->isGraphicsViewMode());
245  settings.setValue("graphics_view_scale", this->isGraphicsViewScaled());
246  settings.setValue("graphics_view_scale_to_height", this->isGraphicsViewScaledToHeight());
247  settings.setValue("colormap", _colorMapWhiteToBlack->isChecked()?0:_colorMapBlackToWhite->isChecked()?1:_colorMapRedToBlue->isChecked()?2:3);
248  if(!group.isEmpty())
249  {
250  settings.endGroup();
251  }
252 }
253 
254 void ImageView::loadSettings(QSettings & settings, const QString & group)
255 {
256  if(!group.isEmpty())
257  {
258  settings.beginGroup(group);
259  }
260  this->setImageShown(settings.value("image_shown", this->isImageShown()).toBool());
261  this->setImageDepthShown(settings.value("depth_shown", this->isImageDepthShown()).toBool());
262  this->setFeaturesShown(settings.value("features_shown", this->isFeaturesShown()).toBool());
263  this->setFeaturesSize(settings.value("features_size", this->getFeaturesSize()).toInt());
264  this->setLinesShown(settings.value("lines_shown", this->isLinesShown()).toBool());
265  this->setAlpha(settings.value("alpha", this->getAlpha()).toInt());
266  this->setDefaultBackgroundColor(settings.value("bg_color", this->getDefaultBackgroundColor()).value<QColor>());
267  this->setGraphicsViewMode(settings.value("graphics_view", this->isGraphicsViewMode()).toBool());
268  this->setGraphicsViewScaled(settings.value("graphics_view_scale", this->isGraphicsViewScaled()).toBool());
269  this->setGraphicsViewScaledToHeight(settings.value("graphics_view_scale_to_height", this->isGraphicsViewScaledToHeight()).toBool());
270  int colorMap = settings.value("colormap", 0).toInt();
271  _colorMapWhiteToBlack->setChecked(colorMap==0);
272  _colorMapBlackToWhite->setChecked(colorMap==1);
273  _colorMapRedToBlue->setChecked(colorMap==2);
274  _colorMapBlueToRed->setChecked(colorMap==3);
275  if(!group.isEmpty())
276  {
277  settings.endGroup();
278  }
279 }
280 
281 QRectF ImageView::sceneRect() const
282 {
283  return _graphicsView->scene()->sceneRect();
284 }
285 
287 {
288  return _showImage->isChecked();
289 }
290 
292 {
293  return _showImageDepth->isChecked();
294 }
295 
297 {
298  return _showFeatures->isChecked();
299 }
300 
302 {
303  return _graphicsViewMode->isChecked();
304 }
305 
307 {
308  return _graphicsViewScaled->isChecked();
309 }
310 
312 {
313  return _graphicsViewScaledToHeight->isChecked();
314 }
315 
317 {
318  return _defaultBgColor;
319 }
320 
321 const QColor & ImageView::getBackgroundColor() const
322 {
323  return _graphicsView->backgroundBrush().color();
324 }
325 
326 
328 {
329  _showFeatures->setChecked(shown);
330  for(QMultiMap<int, KeypointItem*>::iterator iter=_features.begin(); iter!=_features.end(); ++iter)
331  {
332  iter.value()->setVisible(_showFeatures->isChecked());
333  }
334 
335  if(!_graphicsView->isVisible())
336  {
337  this->update();
338  }
339 }
340 
341 void ImageView::setImageShown(bool shown)
342 {
343  _showImage->setChecked(shown);
344  if(_imageItem)
345  {
346  _imageItem->setVisible(_showImage->isChecked());
347  this->updateOpacity();
348  }
349 
350  if(!_graphicsView->isVisible())
351  {
352  this->update();
353  }
354 }
355 
357 {
358  _showImageDepth->setChecked(shown);
359  if(_imageDepthItem)
360  {
361  _imageDepthItem->setVisible(_showImageDepth->isChecked());
362  this->updateOpacity();
363  }
364 
365  if(!_graphicsView->isVisible())
366  {
367  this->update();
368  }
369 }
370 
372 {
373  return _showLines->isChecked();
374 }
375 
376 void ImageView::setLinesShown(bool shown)
377 {
378  _showLines->setChecked(shown);
379  for(int i=0; i<_lines.size(); ++i)
380  {
381  _lines.at(i)->setVisible(_showLines->isChecked());
382  }
383 
384  if(!_graphicsView->isVisible())
385  {
386  this->update();
387  }
388 }
389 
390 float ImageView::viewScale() const
391 {
392  if(_graphicsView->isVisible())
393  {
394  return _graphicsView->transform().m11();
395  }
396  else
397  {
398  float scale, offsetX, offsetY;
399  computeScaleOffsets(this->rect(), scale, offsetX, offsetY);
400  return scale;
401  }
402 }
403 
405 {
406  _graphicsViewMode->setChecked(on);
407  _graphicsView->setVisible(on);
408  _scaleMenu->setEnabled(on);
409 
410  if(on)
411  {
412  for(QMultiMap<int, KeypointItem*>::iterator iter=_features.begin(); iter!=_features.end(); ++iter)
413  {
414  _graphicsView->scene()->addItem(iter.value());
415  }
416 
417  for(QList<QGraphicsLineItem*>::iterator iter=_lines.begin(); iter!=_lines.end(); ++iter)
418  {
419  _graphicsView->scene()->addItem(*iter);
420  }
421 
422  //update images
423  if(_imageItem)
424  {
425  _imageItem->setPixmap(_image);
426  }
427  else
428  {
429  _imageItem = _graphicsView->scene()->addPixmap(_image);
430  _imageItem->setVisible(_showImage->isChecked());
431  }
432 
433  if(_imageDepthItem)
434  {
435  _imageDepthItem->setPixmap(_imageDepth);
436  }
437  else
438  {
439  _imageDepthItem = _graphicsView->scene()->addPixmap(_imageDepth);
440  _imageDepthItem->setVisible(_showImageDepth->isChecked());
441  }
442  this->updateOpacity();
443 
444  if(_graphicsViewScaled->isChecked())
445  {
446  _graphicsView->fitInView(_graphicsView->sceneRect(), Qt::KeepAspectRatio);
447  }
448  else if(_graphicsViewScaledToHeight->isChecked())
449  {
450  QRectF rect = _graphicsView->sceneRect();
451  rect.setWidth(1);
452  _graphicsView->fitInView(rect, Qt::KeepAspectRatio);
453  }
454  else
455  {
456  _graphicsView->resetTransform();
457  }
458  }
459  else
460  {
461  this->update();
462  }
463 }
464 
466 {
467  _graphicsViewScaled->setChecked(scaled);
468 
469  if(scaled)
470  {
471  _graphicsView->fitInView(_graphicsView->sceneRect(), Qt::KeepAspectRatio);
472  }
473  else
474  {
475  _graphicsView->resetTransform();
476  }
477 
478  if(!_graphicsView->isVisible())
479  {
480  this->update();
481  }
482 }
483 
485 {
486  _graphicsViewScaledToHeight->setChecked(scaled);
487 
488  if(scaled)
489  {
490  QRectF rect = _graphicsView->sceneRect();
491  rect.setWidth(1);
492  _graphicsView->fitInView(rect, Qt::KeepAspectRatio);
493  }
494  else
495  {
496  _graphicsView->resetTransform();
497  }
498 
499  if(!_graphicsView->isVisible())
500  {
501  this->update();
502  }
503 }
504 
505 void ImageView::setDefaultBackgroundColor(const QColor & color)
506 {
507  _defaultBgColor = color;
508  setBackgroundColor(color);
509 }
510 
511 void ImageView::setBackgroundColor(const QColor & color)
512 {
513  _graphicsView->setBackgroundBrush(QBrush(color));
514 
515  if(!_graphicsView->isVisible())
516  {
517  this->update();
518  }
519 }
520 
521 void ImageView::computeScaleOffsets(const QRect & targetRect, float & scale, float & offsetX, float & offsetY) const
522 {
523  scale = 1.0f;
524  offsetX = 0.0f;
525  offsetY = 0.0f;
526 
527  if(!_graphicsView->scene()->sceneRect().isNull())
528  {
529  float w = _graphicsView->scene()->width();
530  float h = _graphicsView->scene()->height();
531  float widthRatio = float(targetRect.width()) / w;
532  float heightRatio = float(targetRect.height()) / h;
533 
534  //printf("w=%f, h=%f, wR=%f, hR=%f, sW=%d, sH=%d\n", w, h, widthRatio, heightRatio, this->rect().width(), this->rect().height());
535  if(widthRatio < heightRatio)
536  {
537  scale = widthRatio;
538  }
539  else
540  {
541  scale = heightRatio;
542  }
543 
544  //printf("ratio=%f\n",ratio);
545 
546  w *= scale;
547  h *= scale;
548 
549  if(w < targetRect.width())
550  {
551  offsetX = (targetRect.width() - w)/2.0f;
552  }
553  if(h < targetRect.height())
554  {
555  offsetY = (targetRect.height() - h)/2.0f;
556  }
557  //printf("offsetX=%f, offsetY=%f\n",offsetX, offsetY);
558  }
559 }
560 
561 void ImageView::sceneRectChanged(const QRectF & rect)
562 {
563  _saveImage->setEnabled(rect.isValid());
564 }
565 
566 void ImageView::paintEvent(QPaintEvent *event)
567 {
568  if(_graphicsViewMode->isChecked())
569  {
570  QWidget::paintEvent(event);
571  }
572  else
573  {
574  if(!_graphicsView->scene()->sceneRect().isNull())
575  {
576  //Scale
577  float ratio, offsetX, offsetY;
578  this->computeScaleOffsets(event->rect(), ratio, offsetX, offsetY);
579  QPainter painter(this);
580 
581  //Background
582  painter.save();
583  painter.setBrush(_graphicsView->backgroundBrush());
584  painter.drawRect(event->rect());
585  painter.restore();
586 
587  painter.translate(offsetX, offsetY);
588  painter.scale(ratio, ratio);
589 
590  painter.save();
591  if(_showImage->isChecked() && !_image.isNull() &&
592  _showImageDepth->isChecked() && !_imageDepth.isNull())
593  {
594  painter.setOpacity(0.5);
595  }
596 
597  if(_showImage->isChecked() && !_image.isNull())
598  {
599  painter.drawPixmap(QPoint(0,0), _image);
600  }
601 
602  if(_showImageDepth->isChecked() && !_imageDepth.isNull())
603  {
604  painter.drawPixmap(QPoint(0,0), _imageDepth);
605  }
606  painter.restore();
607 
608  if(_showFeatures->isChecked())
609  {
610  for(QMultiMap<int, rtabmap::KeypointItem *>::iterator iter = _features.begin(); iter != _features.end(); ++iter)
611  {
612  QColor color = iter.value()->pen().color();
613  painter.save();
614  painter.setPen(color);
615  painter.setBrush(color);
616  painter.drawEllipse(iter.value()->rect());
617  painter.restore();
618  }
619  }
620 
621  if(_showLines->isChecked())
622  {
623  for(QList<QGraphicsLineItem*>::iterator iter = _lines.begin(); iter != _lines.end(); ++iter)
624  {
625  QColor color = (*iter)->pen().color();
626  painter.save();
627  painter.setPen(color);
628  painter.drawLine((*iter)->line());
629  painter.restore();
630  }
631  }
632  }
633  }
634 }
635 
636 void ImageView::resizeEvent(QResizeEvent* event)
637 {
638  QWidget::resizeEvent(event);
639  if(_graphicsView->isVisible())
640  {
641  if(_graphicsViewScaled->isChecked())
642  {
643  _graphicsView->fitInView(_graphicsView->sceneRect(), Qt::KeepAspectRatio);
644  }
645  else if(_graphicsViewScaledToHeight->isChecked())
646  {
647  QRectF rect = _graphicsView->sceneRect();
648  rect.setWidth(1);
649  _graphicsView->fitInView(rect, Qt::KeepAspectRatio);
650  }
651  }
652 }
653 
654 void ImageView::contextMenuEvent(QContextMenuEvent * e)
655 {
656  QAction * action = _menu->exec(e->globalPos());
657  if(action == _saveImage)
658  {
659  if(!_graphicsView->scene()->sceneRect().isNull())
660  {
661  QString text;
662 #ifdef QT_SVG_LIB
663  text = QFileDialog::getSaveFileName(this, tr("Save figure to ..."), _savedFileName, "*.png *.xpm *.jpg *.pdf *.svg");
664 #else
665  text = QFileDialog::getSaveFileName(this, tr("Save figure to ..."), _savedFileName, "*.png *.xpm *.jpg *.pdf");
666 #endif
667  if(!text.isEmpty())
668  {
669  _savedFileName = text;
670  QImage img(_graphicsView->sceneRect().width(), _graphicsView->sceneRect().height(), QImage::Format_ARGB32_Premultiplied);
671  QPainter p(&img);
672  if(_graphicsView->isVisible())
673  {
674  _graphicsView->scene()->render(&p, _graphicsView->sceneRect(), _graphicsView->sceneRect());
675  }
676  else
677  {
678  this->render(&p, QPoint(), _graphicsView->sceneRect().toRect());
679  }
680  img.save(text);
681  }
682  }
683  }
684  else if(action == _showFeatures)
685  {
686  this->setFeaturesShown(_showFeatures->isChecked());
687  Q_EMIT configChanged();
688  }
689  else if(action == _showImage)
690  {
691  this->setImageShown(_showImage->isChecked());
692  Q_EMIT configChanged();
693  }
694  else if(action == _showImageDepth)
695  {
696  this->setImageDepthShown(_showImageDepth->isChecked());
697  Q_EMIT configChanged();
698  }
699  else if(action == _showLines)
700  {
701  this->setLinesShown(_showLines->isChecked());
702  Q_EMIT configChanged();
703  }
704  else if(action == _graphicsViewMode)
705  {
706  this->setGraphicsViewMode(_graphicsViewMode->isChecked());
707  Q_EMIT configChanged();
708  }
709  else if(action == _graphicsViewScaled)
710  {
711  this->setGraphicsViewScaled(_graphicsViewScaled->isChecked());
712  Q_EMIT configChanged();
713  }
714  else if(action == _graphicsViewScaledToHeight || action == _graphicsViewNoScaling)
715  {
717  Q_EMIT configChanged();
718  }
719  else if(action == _colorMapBlackToWhite || action == _colorMapWhiteToBlack || action == _colorMapRedToBlue || action == _colorMapBlueToRed)
720  {
721  if(!_imageDepthCv.empty())
723  Q_EMIT configChanged();
724  }
725  else if(action == _setAlpha)
726  {
727  bool ok = false;
728  int value = QInputDialog::getInt(this, tr("Set features and lines transparency"), tr("alpha (0-255)"), _alpha, 0, 255, 10, &ok);
729  if(ok)
730  {
731  this->setAlpha(value);
732  Q_EMIT configChanged();
733  }
734  }
735  else if(action == _setFeaturesSize)
736  {
737  bool ok = false;
738  int value = QInputDialog::getInt(this, tr("Set features size"), tr("Size (0 means actual keypoint size)"), _featuresSize, 0, 999, 1, &ok);
739  if(ok)
740  {
741  this->setFeaturesSize(value);
742  Q_EMIT configChanged();
743  }
744  }
745 
746  if(action == _showImage || action ==_showImageDepth)
747  {
748  this->updateOpacity();
749  Q_EMIT configChanged();
750  }
751 }
752 
754 {
756  {
757  if(_imageItem->isVisible() && _imageDepthItem->isVisible())
758  {
759  QGraphicsOpacityEffect * effect = new QGraphicsOpacityEffect();
760  effect->setOpacity(0.5);
761  _imageDepthItem->setGraphicsEffect(effect);
762  }
763  else
764  {
765  _imageDepthItem->setGraphicsEffect(0);
766  }
767  }
768  else if(_imageDepthItem)
769  {
770  _imageDepthItem->setGraphicsEffect(0);
771  }
772 }
773 
774 void ImageView::setFeatures(const std::multimap<int, cv::KeyPoint> & refWords, const cv::Mat & depth, const QColor & color)
775 {
776  clearFeatures();
777 
778  float xRatio = 0;
779  float yRatio = 0;
780  if (this->sceneRect().isValid() && !depth.empty() && int(this->sceneRect().height()) % depth.rows == 0 && int(this->sceneRect().width()) % depth.cols == 0)
781  {
782  UDEBUG("depth=%dx%d sceneRect=%fx%f", depth.cols, depth.rows, this->sceneRect().width(), this->sceneRect().height());
783  xRatio = float(depth.cols)/float(this->sceneRect().width());
784  yRatio = float(depth.rows)/float(this->sceneRect().height());
785  UDEBUG("xRatio=%f yRatio=%f", xRatio, yRatio);
786  }
787 
788  for(std::multimap<int, cv::KeyPoint>::const_iterator iter = refWords.begin(); iter != refWords.end(); ++iter )
789  {
790  if (xRatio > 0 && yRatio > 0)
791  {
792  addFeature(iter->first, iter->second, util2d::getDepth(depth, iter->second.pt.x*xRatio, iter->second.pt.y*yRatio, false), color);
793  }
794  else
795  {
796  addFeature(iter->first, iter->second, 0, color);
797  }
798  }
799 
800  if(!_graphicsView->isVisible())
801  {
802  this->update();
803  }
804 }
805 
806 void ImageView::setFeatures(const std::vector<cv::KeyPoint> & features, const cv::Mat & depth, const QColor & color)
807 {
808  clearFeatures();
809 
810  float xRatio = 0;
811  float yRatio = 0;
812  if (this->sceneRect().isValid() && !depth.empty() && int(this->sceneRect().height()) % depth.rows == 0 && int(this->sceneRect().width()) % depth.cols == 0)
813  {
814  UDEBUG("depth=%dx%d sceneRect=%fx%f", depth.cols, depth.rows, this->sceneRect().width(), this->sceneRect().height());
815  xRatio = float(depth.cols) / float(this->sceneRect().width());
816  yRatio = float(depth.rows) / float(this->sceneRect().height());
817  UDEBUG("xRatio=%f yRatio=%f", xRatio, yRatio);
818  }
819 
820  for(unsigned int i = 0; i< features.size(); ++i )
821  {
822  if(xRatio > 0 && yRatio > 0)
823  {
824  addFeature(i, features[i], util2d::getDepth(depth, features[i].pt.x*xRatio, features[i].pt.y*yRatio, false), color);
825  }
826  else
827  {
828  addFeature(i, features[i], 0, color);
829  }
830  }
831 
832  if(!_graphicsView->isVisible())
833  {
834  this->update();
835  }
836 }
837 
838 void ImageView::addFeature(int id, const cv::KeyPoint & kpt, float depth, QColor color)
839 {
840  color.setAlpha(this->getAlpha());
841  rtabmap::KeypointItem * item = new rtabmap::KeypointItem(id, kpt, depth, color);
842  if(_featuresSize>0.0f)
843  {
844  item->setRect(kpt.pt.x-_featuresSize/2.0f, kpt.pt.y-_featuresSize/2.0f, _featuresSize, _featuresSize);
845  }
846  _features.insert(id, item);
847  item->setVisible(isFeaturesShown());
848  item->setZValue(1);
849 
850  if(_graphicsView->isVisible())
851  {
852  _graphicsView->scene()->addItem(item);
853  }
854 }
855 
856 void ImageView::addLine(float x1, float y1, float x2, float y2, QColor color, const QString & text)
857 {
858  color.setAlpha(this->getAlpha());
859  LineItem * item = new LineItem(x1, y1, x2, y2, text);
860  item->setPen(QPen(color));
861  _lines.push_back(item);
862  item->setVisible(isLinesShown());
863  item->setZValue(1);
864 
865  if(_graphicsView->isVisible())
866  {
867  _graphicsView->scene()->addItem(item);
868  }
869 }
870 
871 void ImageView::setImage(const QImage & image)
872 {
873  _image = QPixmap::fromImage(image);
874  if(_graphicsView->isVisible())
875  {
876  if(_imageItem)
877  {
878  _imageItem->setPixmap(_image);
879  }
880  else
881  {
882  _imageItem = _graphicsView->scene()->addPixmap(_image);
883  _imageItem->setVisible(_showImage->isChecked());
884  this->updateOpacity();
885  }
886  }
887 
888  if(image.rect().isValid())
889  {
890  this->setSceneRect(image.rect());
891  }
892  else if(!_graphicsView->isVisible())
893  {
894  this->update();
895  }
896 }
897 
898 void ImageView::setImageDepth(const cv::Mat & imageDepth)
899 {
900  _imageDepthCv = imageDepth;
902  if(_colorMapBlackToWhite->isChecked())
903  {
904  colorMap = uCvQtDepthBlackToWhite;
905  }
906  else if(_colorMapRedToBlue->isChecked())
907  {
908  colorMap = uCvQtDepthRedToBlue;
909  }
910  else if(_colorMapBlueToRed->isChecked())
911  {
912  colorMap = uCvQtDepthBlueToRed;
913  }
914  setImageDepth(uCvMat2QImage(_imageDepthCv, true, colorMap));
915 }
916 
917 void ImageView::setImageDepth(const QImage & imageDepth)
918 {
919  _imageDepth = QPixmap::fromImage(imageDepth);
920 
921  UASSERT(_imageDepth.width() && _imageDepth.height());
922 
923  if( _image.width() > 0 &&
924  _image.width() > _imageDepth.width() &&
925  _image.height() > _imageDepth.height() &&
926  _image.width() % _imageDepth.width() == 0 &&
927  _image.height() % _imageDepth.height() == 0)
928  {
929  // scale depth to rgb
930  _imageDepth = _imageDepth.scaled(_image.size());
931  }
932 
933  if(_graphicsView->isVisible())
934  {
935  if(_imageDepthItem)
936  {
937  _imageDepthItem->setPixmap(_imageDepth);
938  }
939  else
940  {
941  _imageDepthItem = _graphicsView->scene()->addPixmap(_imageDepth);
942  _imageDepthItem->setVisible(_showImageDepth->isChecked());
943  this->updateOpacity();
944  }
945  }
946  else
947  {
948  if(_image.isNull())
949  {
950  this->setSceneRect(imageDepth.rect());
951  }
952  this->update();
953  }
954 }
955 
956 void ImageView::setFeatureColor(int id, QColor color)
957 {
958  color.setAlpha(getAlpha());
959  QList<KeypointItem*> items = _features.values(id);
960  if(items.size())
961  {
962  for(int i=0; i<items.size(); ++i)
963  {
964  items[i]->setColor(color);
965  }
966  }
967  else
968  {
969  UWARN("Not found feature %d", id);
970  }
971 
972  if(!_graphicsView->isVisible())
973  {
974  this->update();
975  }
976 }
977 
978 void ImageView::setFeaturesColor(QColor color)
979 {
980  color.setAlpha(getAlpha());
981  for(QMultiMap<int, KeypointItem*>::iterator iter=_features.begin(); iter!=_features.end(); ++iter)
982  {
983  iter.value()->setColor(color);
984  }
985 
986  if(!_graphicsView->isVisible())
987  {
988  this->update();
989  }
990 }
991 
992 void ImageView::setAlpha(int alpha)
993 {
994  UASSERT(alpha >=0 && alpha <= 255);
995  _alpha = alpha;
996  for(QMultiMap<int, KeypointItem*>::iterator iter=_features.begin(); iter!=_features.end(); ++iter)
997  {
998  QColor c = iter.value()->pen().color();
999  c.setAlpha(_alpha);
1000  iter.value()->setPen(QPen(c));
1001  iter.value()->setBrush(QBrush(c));
1002  }
1003 
1004  for(QList<QGraphicsLineItem*>::iterator iter=_lines.begin(); iter!=_lines.end(); ++iter)
1005  {
1006  QColor c = (*iter)->pen().color();
1007  c.setAlpha(_alpha);
1008  (*iter)->setPen(QPen(c));
1009  }
1010 
1011  if(!_graphicsView->isVisible())
1012  {
1013  this->update();
1014  }
1015 }
1016 
1018 {
1019  _featuresSize = size;
1020  for(QMultiMap<int, KeypointItem*>::iterator iter=_features.begin(); iter!=_features.end(); ++iter)
1021  {
1022  const cv::KeyPoint & kpt = iter.value()->keypoint();
1023  if(size <= 0.0f)
1024  {
1025  size = kpt.size==0?3:kpt.size;
1026  }
1027  float sizef = size;
1028  iter.value()->setRect(kpt.pt.x-sizef/2.0f, kpt.pt.y-sizef/2.0f, sizef, sizef);
1029  }
1030 
1031  if(!_graphicsView->isVisible())
1032  {
1033  this->update();
1034  }
1035 }
1036 
1037 void ImageView::setSceneRect(const QRectF & rect)
1038 {
1039  _graphicsView->scene()->setSceneRect(rect);
1040 
1041  if(_graphicsViewScaled->isChecked())
1042  {
1043  _graphicsView->fitInView(_graphicsView->sceneRect(), Qt::KeepAspectRatio);
1044  }
1045  else if(_graphicsViewScaledToHeight->isChecked())
1046  {
1047  QRectF rect = _graphicsView->sceneRect();
1048  rect.setWidth(1);
1049  _graphicsView->fitInView(rect, Qt::KeepAspectRatio);
1050  }
1051  else
1052  {
1053  _graphicsView->resetTransform();
1054  }
1055 
1056  if(!_graphicsView->isVisible())
1057  {
1058  this->update();
1059  }
1060 }
1061 
1063 {
1064  qDeleteAll(_lines);
1065  _lines.clear();
1066 
1067  if(!_graphicsView->isVisible())
1068  {
1069  this->update();
1070  }
1071 }
1072 
1074 {
1075  qDeleteAll(_features);
1076  _features.clear();
1077 
1078  if(!_graphicsView->isVisible())
1079  {
1080  this->update();
1081  }
1082 }
1083 
1085 {
1086  clearFeatures();
1087 
1088  qDeleteAll(_lines);
1089  _lines.clear();
1090 
1091  if(_imageItem)
1092  {
1093  _graphicsView->scene()->removeItem(_imageItem);
1094  delete _imageItem;
1095  _imageItem = 0;
1096  }
1097  _image = QPixmap();
1098 
1099  if(_imageDepthItem)
1100  {
1101  _graphicsView->scene()->removeItem(_imageDepthItem);
1102  delete _imageDepthItem;
1103  _imageDepthItem = 0;
1104  }
1105  _imageDepth = QPixmap();
1106 
1107  _graphicsView->scene()->setSceneRect(QRectF());
1108  _graphicsView->setScene(_graphicsView->scene());
1109 
1110  if(!_graphicsView->isVisible())
1111  {
1112  this->update();
1113  }
1114 }
1115 
1116 QSize ImageView::sizeHint() const
1117 {
1118  return _graphicsView->sizeHint();
1119 }
1120 
1121 }
void addLine(float x1, float y1, float x2, float y2, QColor color, const QString &text=QString())
Definition: ImageView.cpp:856
QMultiMap< int, rtabmap::KeypointItem * > _features
Definition: ImageView.h:144
bool isImageDepthShown() const
Definition: ImageView.cpp:291
QAction * _showImageDepth
Definition: ImageView.h:127
void setAlpha(int alpha)
Definition: ImageView.cpp:992
void showDescription()
Definition: ImageView.cpp:104
bool isLinesShown() const
Definition: ImageView.cpp:371
QAction * _showLines
Definition: ImageView.h:129
void setFeaturesColor(QColor color)
Definition: ImageView.cpp:978
f
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event)
Definition: ImageView.cpp:68
bool isImageShown() const
Definition: ImageView.cpp:286
bool isGraphicsViewScaledToHeight() const
Definition: ImageView.cpp:311
void setFeatureColor(int id, QColor color)
Definition: ImageView.cpp:956
QAction * _setFeaturesSize
Definition: ImageView.h:132
void setLinesShown(bool shown)
Definition: ImageView.cpp:376
void computeScaleOffsets(const QRect &targetRect, float &scale, float &offsetX, float &offsetY) const
Definition: ImageView.cpp:521
QList< QGraphicsLineItem * > _lines
Definition: ImageView.h:145
bool isGraphicsViewScaled() const
Definition: ImageView.cpp:306
GLM_FUNC_DECL genType e()
GLM_FUNC_DECL detail::tmat4x4< T, P > scale(detail::tmat4x4< T, P > const &m, detail::tvec3< T, P > const &v)
QColor _defaultBgColor
Definition: ImageView.h:123
void setFeaturesSize(int size)
Definition: ImageView.cpp:1017
QAction * _showImage
Definition: ImageView.h:126
QAction * _graphicsViewScaledToHeight
Definition: ImageView.h:135
void setImage(const QImage &image)
Definition: ImageView.cpp:871
LineItem(float x1, float y1, float x2, float y2, const QString &text=QString(), QGraphicsItem *parent=0)
Definition: ImageView.cpp:51
QAction * _colorMapRedToBlue
Definition: ImageView.h:139
const QColor & getDefaultBackgroundColor() const
Definition: ImageView.cpp:316
virtual ~ImageView()
Definition: ImageView.cpp:227
#define UASSERT(condition)
QGraphicsView * _graphicsView
Definition: ImageView.h:143
QAction * _graphicsViewMode
Definition: ImageView.h:133
void loadSettings(QSettings &settings, const QString &group="")
Definition: ImageView.cpp:254
void setSceneRect(const QRectF &rect)
Definition: ImageView.cpp:1037
void setImageShown(bool shown)
Definition: ImageView.cpp:341
void setBackgroundColor(const QColor &color)
Definition: ImageView.cpp:511
QGraphicsRectItem * _placeHolder
Definition: ImageView.cpp:148
QGraphicsPixmapItem * _imageItem
Definition: ImageView.h:146
QAction * _saveImage
Definition: ImageView.h:130
QImage uCvMat2QImage(const cv::Mat &image, bool isBgr=true, uCvQtDepthColorMap colorMap=uCvQtDepthWhiteToBlack)
Definition: UCv2Qt.h:44
void setGraphicsViewScaledToHeight(bool scaled)
Definition: ImageView.cpp:484
virtual ~LineItem()
Definition: ImageView.cpp:60
QAction * _colorMapWhiteToBlack
Definition: ImageView.h:137
void setImageDepth(const cv::Mat &imageDepth)
Definition: ImageView.cpp:898
void setFeaturesShown(bool shown)
Definition: ImageView.cpp:327
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
Definition: ImageView.cpp:82
QMenu * _scaleMenu
Definition: ImageView.h:141
virtual void focusOutEvent(QFocusEvent *event)
Definition: ImageView.cpp:97
virtual QSize sizeHint() const
Definition: ImageView.cpp:1116
ImageView(QWidget *parent=0)
Definition: ImageView.cpp:152
QRectF sceneRect() const
Definition: ImageView.cpp:281
void addFeature(int id, const cv::KeyPoint &kpt, float depth, QColor color)
Definition: ImageView.cpp:838
QPixmap _imageDepth
Definition: ImageView.h:149
bool isGraphicsViewMode() const
Definition: ImageView.cpp:301
void setGraphicsViewMode(bool on)
Definition: ImageView.cpp:404
QAction * _setAlpha
Definition: ImageView.h:131
void hideDescription()
Definition: ImageView.cpp:137
void setColor(const QColor &color)
const QColor & getBackgroundColor() const
Definition: ImageView.cpp:321
virtual void focusInEvent(QFocusEvent *event)
Definition: ImageView.cpp:91
void setGraphicsViewScaled(bool scaled)
Definition: ImageView.cpp:465
QAction * _colorMapBlueToRed
Definition: ImageView.h:140
virtual void resizeEvent(QResizeEvent *event)
Definition: ImageView.cpp:636
#define UDEBUG(...)
QAction * _showFeatures
Definition: ImageView.h:128
int getAlpha() const
Definition: ImageView.h:63
virtual void paintEvent(QPaintEvent *event)
Definition: ImageView.cpp:566
void sceneRectChanged(const QRectF &rect)
Definition: ImageView.cpp:561
ULogger class and convenient macros.
#define UWARN(...)
float viewScale() const
Definition: ImageView.cpp:390
QAction * _colorMapBlackToWhite
Definition: ImageView.h:138
bool isFeaturesShown() const
Definition: ImageView.cpp:296
uCvQtDepthColorMap
Definition: UCv2Qt.h:30
QString _savedFileName
Definition: ImageView.h:120
float RTABMAP_EXP getDepth(const cv::Mat &depthImage, float x, float y, bool smoothing, float depthErrorRatio=0.02f, bool estWithNeighborsIfNull=false)
Definition: util2d.cpp:942
virtual void contextMenuEvent(QContextMenuEvent *e)
Definition: ImageView.cpp:654
QAction * _graphicsViewNoScaling
Definition: ImageView.h:136
void setFeatures(const std::multimap< int, cv::KeyPoint > &refWords, const cv::Mat &depth=cv::Mat(), const QColor &color=Qt::yellow)
Definition: ImageView.cpp:774
int getFeaturesSize() const
Definition: ImageView.h:64
cv::Mat _imageDepthCv
Definition: ImageView.h:150
void setDefaultBackgroundColor(const QColor &color)
Definition: ImageView.cpp:505
void saveSettings(QSettings &settings, const QString &group="") const
Definition: ImageView.cpp:231
QAction * _graphicsViewScaled
Definition: ImageView.h:134
void setImageDepthShown(bool shown)
Definition: ImageView.cpp:356
QGraphicsPixmapItem * _imageDepthItem
Definition: ImageView.h:147


rtabmap
Author(s): Mathieu Labbe
autogenerated on Wed Jun 5 2019 22:41:31