8 #include <base-logging/Logging.hpp> 11 #include <QtOpenGL/QGLWidget> 17 #include <QGst/Pipeline> 18 #include <QGst/ElementFactory> 19 #include <QGst/Ui/VideoWidget> 20 #include <QGst/Ui/GraphicsVideoSurface> 21 #include <QGst/Ui/GraphicsVideoWidget> 26 bgColor(QColor(Qt::black)),
27 use_progress_indicator(true),
28 use_smooth_transformation(true),
29 progress_indicator_timeout(2500),
32 progress_indicator_timer(this),
34 rotate_image_clockwise_act(this),
36 save_image_overlay_act(this),
37 activate_progress_indicator_act(this),
38 rgb_swapped_act(this),
39 invert_color_act(this)
42 pipelineDescription(
"videotestsrc ! ximagesink"),
46 setWindowTitle(
"ImageView");
47 setMinimumSize(220,170);
48 setContentsMargins(0,0,0,0);
55 progress_indicator.resize(30,30);
56 progress_indicator.hide();
60 connect(&progress_indicator_timer, SIGNAL(timeout()),
this, SLOT(startProgressIndicator()));
65 QGst::PipelinePtr pipeline;
66 QGst::ElementPtr videoSrc;
71 pipeline = QGst::Pipeline::create(
"pipeline");
72 videoSrc = QGst::ElementFactory::make(
"videotestsrc");
76 imageScene =
new QGraphicsScene(
this);
78 imageScene->installEventFilter(
this);
80 imageView =
new QGraphicsView(imageScene);
81 imageView->setAlignment(Qt::AlignCenter);
82 imageView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
83 imageView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
84 imageView->setFocusPolicy(Qt::NoFocus);
85 imageView->setFrameStyle(QFrame::NoFrame);
86 imageView->setContentsMargins(0,0,0,0);
91 imageView->setViewport(
new QGLWidget);
94 QGst::Ui::GraphicsVideoSurface *surface = NULL;
95 QGst::Ui::GraphicsVideoWidget *widget = NULL;
97 surface =
new QGst::Ui::GraphicsVideoSurface(view);
98 widget =
new QGst::Ui::GraphicsVideoWidget;
99 widget->setSurface(surface);
101 scene->addItem(widget);
104 pipeline->add(videoSrc, surface->videoSink());
105 videoSrc->link(surface->videoSink());
107 LOG_INFO_S <<
"Video source name: " << surface->videoSink()->property(
"name").toString().toStdString();
110 if(!pipeline->setState(QGst::StatePlaying)) {
112 LOG_WARN(
"Could not play pipeline.");
115 imageItem =
new QGraphicsPixmapItem;
119 imageScene->addItem(imageItem);
126 fixedOverlayScene =
new QGraphicsScene(
this);
127 fixedOverlayScene->setBackgroundBrush(Qt::transparent);
129 fixedOverlayView =
new QGraphicsView(fixedOverlayScene,
this);
130 fixedOverlayView->setAlignment(Qt::AlignCenter);
131 fixedOverlayView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
132 fixedOverlayView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
133 fixedOverlayView->setFocusPolicy(Qt::NoFocus);
134 fixedOverlayView->setFrameStyle(QFrame::NoFrame);
135 fixedOverlayView->setContentsMargins(0,0,0,0);
138 overlay_grid =
new QGraphicsGridLayout;
143 QGraphicsWidget *label_mi = fixedOverlayScene->addWidget(
new QLabel);
144 QPalette label_mi_pal;
145 label_mi_pal.setColor(QPalette::Window, QColor(Qt::transparent));
147 label_mi->setPalette(label_mi_pal);
148 label_mi->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
149 overlay_grid->addItem(label_mi, 1, 1, Qt::AlignVCenter|Qt::AlignCenter);
152 connect(overlayWidget, SIGNAL(contextMenuRequest(QPoint)),
this, SLOT(displayContextMenu(QPoint)));
154 overlayWidget->setLayout(overlay_grid);
155 overlayWidget->setZValue(12);
156 fixedOverlayScene->addItem(overlayWidget);
159 imageViewProxy = fixedOverlayScene->addWidget(imageView);
161 progress_indicator.setParent(fixedOverlayView);
173 return QSize(500,500);
184 imageScene->setBackgroundBrush(bgColor);
196 progress_indicator.hide();
199 progress_indicator_timer.start();
205 progress_indicator_timer.stop();
219 imageItem->setTransformationMode(Qt::SmoothTransformation);
221 imageItem->setTransformationMode(Qt::FastTransformation);
232 progress_indicator_timer.setInterval(timeout);
236 const QString ImageView::getPipelineDescription()
const 238 return pipelineDescription;
241 void ImageView::setPipelineDescription(QString descr)
243 this->pipelineDescription = descr;
246 bool ImageView::getUseGl()
251 void ImageView::setUseGl(
bool use_gl)
253 this->use_gl = use_gl;
259 QGraphicsEllipseItem *circlePtr =
260 new QGraphicsEllipseItem(QRectF(center.x() - radius/2.0, center.y() - radius/2.0, radius, radius));
264 circlePtr->setPen(pen);
266 addDrawItem(imageScene, circlePtr, persistent);
271 QGraphicsLineItem *linePtr =
new QGraphicsLineItem(line);
275 linePtr->setPen(pen);
277 addDrawItem(imageScene, linePtr, persistent);
280 void ImageView::addPoints(
const QList<int> points_x,QList<int> points_y, QColor &color,
int width,
bool persistent)
282 QList<QPoint> points;
283 QList<int>::const_iterator iter1 = points_x.begin();
284 QList<int>::const_iterator iter2 = points_y.begin();
285 for(;iter1 != points_x.end() && iter2 != points_y.end();++iter1,++iter2)
287 points.push_back(QPoint(*iter1,*iter2));
296 addDrawItem(imageScene, pointsPtr, persistent);
301 LOG_DEBUG_S <<
"Received polygon. Polygon closed: " << polygon.isClosed();
302 LOG_DEBUG_S <<
"The polygon has a size of " << polygon.size() <<
".";
303 QGraphicsPolygonItem *polygonPtr =
new QGraphicsPolygonItem(polygon);
307 polygonPtr->setPen(pen);
309 addDrawItem(imageScene, polygonPtr, persistent);
317 Qt::Alignment alignment = Qt::AlignLeft;
323 alignment = Qt::AlignTop|Qt::AlignLeft;
328 alignment = Qt::AlignTop|Qt::AlignRight;
333 alignment = Qt::AlignBottom|Qt::AlignLeft;
338 alignment = Qt::AlignBottom|Qt::AlignRight;
341 LOG_WARN(
"Unsupported text location. Switching to TOPLEFT.");
346 QLabel *label = NULL;
347 QGraphicsWidget *textLabel = NULL;
356 if(overlayMap.contains(location)) {
358 label = overlayMap[location];
359 label->setText(text);
363 label =
new QLabel(text);
364 label->setVisible(
false);
365 label->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
367 overlayMap[location] = label;
369 textLabel = fixedOverlayScene->addWidget(label);
370 overlay_grid->addItem(textLabel, row, col, alignment);
371 textLabel->setVisible(
true);
375 QColor labelBgColor(Qt::white);
376 labelBgColor.setAlphaF(0.7);
377 palette.setColor(QPalette::Window, labelBgColor);
378 palette.setColor(QPalette::WindowText, color);
381 label->setPalette(palette);
382 label->setMargin(margin);
384 QFont font(
"Monospace");
385 font.setPointSize(12);
386 font.setStyleHint(QFont::TypeWriter);
387 label->setFont(font);
389 label->setMaximumSize(label->sizeHint());
396 overlay_grid->invalidate();
403 if(clear_persistent_items) {
404 Q_FOREACH(QGraphicsItem *item, persistentDrawItems) {
405 item->scene()->removeItem(item);
407 persistentDrawItems.clear();
410 Q_FOREACH(QGraphicsItem *item, volatileDrawItems) {
411 item->scene()->removeItem(item);
413 volatileDrawItems.clear();
418 imageView->rotate(deg);
419 imageView->fitInView(imageItem, Qt::KeepAspectRatio);
425 QImage
saveImage(imageScene->sceneRect().size().toSize(), image.format());
430 path = QFileDialog::getSaveFileName(
this,
"Save Image",
441 imageScene->render(&painter);
443 QSize oldSize = size();
444 QSize newSize = imageScene->sceneRect().size().toSize();
447 imageViewProxy->hide();
449 fixedOverlayScene->setSceneRect(imageScene->sceneRect());
450 overlayWidget->resize(newSize);
453 fixedOverlayScene->render(&painter);
455 imageViewProxy->show();
458 resize(oldSize.width(),oldSize.height()+1);
459 resize(oldSize.width(),oldSize.height()-1);
470 base::samples::frame::Frame bframe(frame.width,frame.height,16);
471 std::vector<uint16_t> v(frame.data.size());
472 for(
unsigned int i=0;i<v.size();i++){
473 v[i] = frame.data[i];
476 bframe.setImage((uint8_t*)&v[0],frame.data.size()*2);
477 if(1 == frame_converter.copyFrameToQImageRGB888(image,bframe)) {
478 LOG_WARN(
"Frame size changed while converting frame to QImage (says converter)");
486 if(1 == frame_converter.copyFrameToQImageRGB888(image,frame)) {
487 LOG_WARN(
"Frame size changed while converting frame to QImage (says converter)");
493 void ImageView::setRawImage(
const QString &mode,
int pixel_size,
int width,
int height,
const char* pbuffer,
const int size)
495 frame_converter.copyFrameToQImageRGB888(image,mode, pixel_size, width, height,pbuffer,size);
502 this->image = image.copy();
510 image.invertPixels();
512 image = image.rgbSwapped();
518 progress_indicator.hide();
519 progress_indicator_timer.start();
529 QSize oldSize = imageSize;
530 imageSize = image.size();
532 QPixmap pixmap = QPixmap::fromImage(image);
533 pixmap.scaled(size(), Qt::KeepAspectRatio);
537 imageItem->setPixmap(pixmap);
539 LOG_WARN(
"imageItem undefined!");
545 if(imageSize != oldSize) {
546 LOG_INFO(
"image size changed. resize.");
549 imageScene->setSceneRect(0, 0, imageSize.width(), imageSize.height());
557 setVisible(
false); setVisible(
true);
558 resize(width(),height()-1);
559 resize(width(),height()+1);
569 QWidget::resizeEvent(event);
572 QSize eventSize =
event->size();
573 fixedOverlayScene->setSceneRect(0, 0, eventSize.width(), eventSize.height());
574 imageView->resize(eventSize);
580 imageView->fitInView(imageItem, Qt::KeepAspectRatio);
583 fixedOverlayView->resize(eventSize);
584 overlayWidget->resize(eventSize);
586 LOG_DEBUG_S <<
"scene dimensions:\n" 587 <<
"fixedOverlayScene (w/h): (" << fixedOverlayScene->width() <<
"," << fixedOverlayScene->height() <<
")\n" 588 <<
"imageScene (w/h): (" << imageScene->width() <<
"," << imageScene->height() <<
")\n";
593 context_menu.exec(event->globalPos());
600 if (event->type() == QEvent::GraphicsSceneMousePress) {
601 QGraphicsSceneMouseEvent *mouseEvent =
static_cast<QGraphicsSceneMouseEvent *
>(event);
603 QPoint scenePos = mouseEvent->scenePos().toPoint();
606 if(imageScene->sceneRect().contains(scenePos)) {
607 LOG_INFO_S <<
"Clicked at image coordinate (w,h) (" << scenePos.x() <<
"," << scenePos.y() <<
")";
614 return QObject::eventFilter(obj, event);
621 void ImageView::displayContextMenu(QPoint screenPos)
623 LOG_DEBUG(
"Got context menu request signal");
624 context_menu.exec(screenPos);
627 void ImageView::rotate_clockwise()
632 void ImageView::save_image()
637 void ImageView::save_image_overlay()
642 void ImageView::startProgressIndicator()
644 progress_indicator.show();
651 void ImageView::addDrawItem(QGraphicsScene* scene, QGraphicsItem *item,
bool persistent)
656 persistentDrawItems.push_back(item);
658 volatileDrawItems.push_back(item);
661 LOG_DEBUG(
"Adding item to scene");
662 scene->addItem(item);
672 void ImageView::setItemPositions()
675 progress_indicator.move(imageView->width()/2 - progress_indicator.width()/2,
676 imageView->height()/2 - progress_indicator.height()/2);
681 return imageSize.height();
686 return imageSize.width();
694 image.invertPixels();
702 image = image.rgbSwapped();
706 void ImageView::setupContextMenu()
708 rgb_swapped_act.setText(
"RGB Swapped");
709 rgb_swapped_act.setCheckable(
true);
711 connect(&rgb_swapped_act,SIGNAL(triggered(
bool)),
this,SLOT(
setRgbSwapped(
bool)));
712 context_menu.addAction(&rgb_swapped_act);
714 invert_color_act.setText(
"Invert Color");
715 invert_color_act.setCheckable(
true);
717 connect(&invert_color_act,SIGNAL(triggered(
bool)),
this,SLOT(
setInvertColor(
bool)));
718 context_menu.addAction(&invert_color_act);
720 rotate_image_clockwise_act.setText(
"Rotate 90 deg");
721 connect(&rotate_image_clockwise_act,SIGNAL(triggered()),
this,SLOT(rotate_clockwise()));
722 context_menu.addAction(&rotate_image_clockwise_act);
724 save_image_act.setText(
"Save");
725 connect(&save_image_act,SIGNAL(triggered()),
this,SLOT(save_image()));
726 context_menu.addAction(&save_image_act);
728 save_image_overlay_act.setText(
"Save with Overlay");
729 connect(&save_image_overlay_act,SIGNAL(triggered()),
this,SLOT(save_image_overlay()));
730 context_menu.addAction(&save_image_overlay_act);
732 activate_progress_indicator_act.setText(
"Show Progress-Indicator");
733 activate_progress_indicator_act.setCheckable(
true);
736 context_menu.addAction(&activate_progress_indicator_act);
void setRawImage(const QString &mode, int pixel_size, int width, int height, const char *pbuffer, const int size)
void addText(QString text, int location, QColor color=QColor(Qt::black), bool persistent=0)
Draws text overlay.
void saveImage(QString path=QString(), bool overlay=0)
Saves current image to file.
void setRgbSwapped(bool swapped)
void addPoints(const QList< int > points_x, QList< int > points_y, QColor &color, int width, bool persistent=0)
Draws points overlay (2D point cloud).
const int getProgressIndicatorTimeout() const
void setUseProgressIndicator(bool use)
void setImage(const QImage &image)
void addCircle(QPointF ¢er, double radius, QColor &color, int width, bool persistent=0)
Draws circle overlay.
bool useProgressIndicator()
void setPen(const QPen &pen)
ImageView(QWidget *parent=0)
void setBackgroundColor(const QColor &color)
void addPolygon(QPolygonF &polygon, QColor &color, int width, bool persistent=0)
Draws polygon overlay.
const QColor & getBackgroundColor() const
bool useSmoothTransformation()
void clickedImage(const QPoint &point)
Mouse click coordinates in image.
bool eventFilter(QObject *obj, QEvent *event)
void setAnimationDelay(int delay)
bool use_progress_indicator
Display progress indicator widget if no frames have being received for a defined time.
void setInvertColor(bool invert)
void setFrame(const base::samples::DistanceImage &frame)
Frame input.
void setSmoothTransformation(bool smooth)
int getWidth() const
returns the real width of the underlaying widget
void update2()
Wrapper for QWidget::update(). This is due to some QtRuby limitations.
bool use_smooth_transformation
Usage of antialiasing techniques during image transformation.
void setProgressIndicatorTimeout(int timeout)
void setDisplayedWhenStopped(bool state)
void contextMenuEvent(QContextMenuEvent *event)
void rotate(int deg)
Rotates image display.
void clearOverlays(bool clear_persistent_items=0)
Removes overlays.
void resizeEvent(QResizeEvent *event)
void addLine(QLineF &line, QColor &color, int width, bool persistent=0)
Draws line overlay.
int progress_indicator_timeout
The time without frame update in ms after which the progress indicator gets started.
int getHeight() const
returns the real height of the underlaying widget