/* * ImageHolder.cpp * * Created on: Oct 5, 2011 * Author: gapchich */ #include "ImageHolder.h" #include "functions.h" #include #include #include #include #include #include ImageHolder::ImageHolder(QWidget *aParent) : QLabel(aParent) { repaint_needed_ = 0; tool_ = NoTool; state_ = StandBy; keyboard_modifier_ = Qt::NoModifier; focused_selection_ = -1; focused_selection_type_ = NoFigure; hovered_point_.figure = NoFigure; hovered_point_.figureID = -1; hovered_point_.pointID = -1; list_bounding_box_ = 0; main_label_ = 0; //list_bounding_box_ = new QList< QRect >; scale_ = 1; point_radius_ = 6; setScaledContents(true); setMouseTracking(true); } ImageHolder::~ImageHolder() { //list_bounding_box_->clear(); //delete list_bounding_box_; } void ImageHolder::paintEvent(QPaintEvent *anEvent) { QLabel::paintEvent(anEvent); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); //painter.setRenderHint(QPainter::SmoothPixmapTransform); QPen pen; if (NoTool != tool_) { pen.setWidth(1); pen.setColor(QColor(Qt::black)); pen.setStyle(Qt::DashLine); painter.setPen(pen); if (BoundingBoxTool == tool_) { /* scaling */ QRect bbox = bounding_box_.rect; QPoint bboxTopLeft = bbox.topLeft() * scale_; QPoint bboxBottomRight = bbox.bottomRight() * scale_; bbox.setTopLeft(bboxTopLeft); bbox.setBottomRight(bboxBottomRight); painter.drawRect(bbox); } else if (PolygonTool == tool_) { /* scaling */ QPoint point; QPolygon poly = polygon_.poly; for (int i = 0; i < poly.size(); i++) { point.setX(poly.at(i).x()); point.setY(poly.at(i).y()); point *= scale_; poly.remove(i); poly.insert(i, point); } painter.drawPolygon(poly); } // switch(tool_) { // case BoundingBoxTool: // painter.drawRect(); // break; // case PolygonTool: // painter.drawPolygon(polygon_.poly); // break; // default: // break; // } } /* drawing bounding boxes */ drawBoundingBoxes(&painter, &pen); drawPolygons(&painter, &pen); } void ImageHolder::drawBoundingBoxes( QPainter *aPainter, QPen *aPen ) { /* FIXME: hardcoded colors */ if (0 == list_bounding_box_) { return; /* NOTREACHED */ } Qt::PenStyle penStyle = Qt::SolidLine; int width = 1; /* confirmed boxes */ for (int i = 0; i < list_bounding_box_->size(); i++) { int labelID = list_bounding_box_->at(i)->label_ID_; if (labelID < list_label_color_->count()) aPen->setColor(QColor(list_label_color_->at(labelID))); else aPen->setColor(QColor(Qt::white)); /* checking whether labeled area is of main object or not */ if (labelID == *main_label_) width = 3; else width = 1; if (RectFigure == focused_selection_type_ && focused_selection_ == i) { penStyle = Qt::DotLine; width = 2; } /* scaling */ QRect rect = list_bounding_box_->at(i)->rect.normalized(); QPoint topLeft = rect.topLeft() * scale_; QPoint bottomRight = rect.bottomRight() * scale_; rect.setTopLeft(topLeft); rect.setBottomRight(bottomRight); if (focused_selection_ == i && focused_selection_type_ == RectFigure) { QPen circPen; circPen.setWidth(2); circPen.setStyle(Qt::SolidLine); circPen.setColor(aPen->color()); aPainter->setPen(circPen); for (int j = 0; j < 4; j++) { QPoint point; if (!j) { point = rect.topLeft(); } else if (1 == j) { point = rect.topRight(); } else if (2 == j) { point = rect.bottomRight(); } else if (3 == j) { point = rect.bottomLeft(); } if (i == hovered_point_.figureID && j == hovered_point_.pointID && RectFigure == hovered_point_.figure) { QBrush brush; brush.setColor(aPen->color()); brush.setStyle(Qt::SolidPattern); aPainter->setBrush(brush); } aPainter->drawEllipse(point, point_radius_, point_radius_); aPainter->setBrush(Qt::NoBrush); } } aPen->setWidth(width); aPen->setStyle(penStyle); aPainter->setPen(*aPen); aPainter->drawRect(rect); /* drawing label ids of these boxes */ QString labelIDText = QString("%1").arg(labelID); aPainter->drawText( rect.left() + 5, rect.top() + 5, 20, 20, Qt::AlignLeft, labelIDText ); } } void ImageHolder::drawPolygons( QPainter *aPainter, QPen *aPen ) { /* FIXME: hardcoded colors */ if (0 == list_polygon_) { return; /* NOTREACHED */ } Qt::PenStyle penStyle = Qt::SolidLine; int width = 1; /* confirmed polygons */ for (int i = 0; i < list_polygon_->size(); i++) { penStyle = Qt::SolidLine; int labelID = list_polygon_->at(i)->label_ID_; if (labelID < list_label_color_->count()) aPen->setColor(QColor(list_label_color_->at(labelID))); else aPen->setColor(QColor(Qt::white)); /* checking whether labeled area is of main object or not */ if (labelID == *main_label_) width = 3; else width = 1; if (PolyFigure == focused_selection_type_ && focused_selection_ == i) { penStyle = Qt::DotLine; width = 2; } QPoint point; QPolygon poly = list_polygon_->at(i)->poly; for (int j = 0; j < poly.size(); j++) { point.setX(poly.at(j).x()); point.setY(poly.at(j).y()); point *= scale_; poly.remove(j); poly.insert(j, point); if (focused_selection_ == i && focused_selection_type_ == PolyFigure) { QPen circPen; circPen.setWidth(2); circPen.setStyle(Qt::SolidLine); circPen.setColor(aPen->color()); aPainter->setPen(circPen); if (j == hovered_point_.pointID && i == hovered_point_.figureID && PolyFigure == hovered_point_.figure) { QBrush brush; brush.setColor(aPen->color()); brush.setStyle(Qt::SolidPattern); aPainter->setBrush(brush); } aPainter->drawEllipse(point, point_radius_, point_radius_); aPainter->setBrush(Qt::NoBrush); } } aPen->setWidth(width); aPen->setStyle(penStyle); aPainter->setPen(*aPen); aPainter->drawPolygon(poly); /* drawing label ids of these polys */ QString labelIDText = QString("%1").arg(labelID); QRect rect = poly.boundingRect(); int x = rect.center().x(); int y = rect.center().y(); aPainter->drawText( x, y, 20, 20, Qt::AlignHCenter, labelIDText ); } } void ImageHolder::triggerBoundBox( const QPoint &aNewPos, const QPoint &anOldPos, QRect *aNewRect ) { aNewRect->setCoords( anOldPos.x(), anOldPos.y(), aNewPos.x(), aNewPos.y() ); state_ = NewSelection; repaint_needed_ = 1; } void ImageHolder::triggerPolygon( const QPoint &aPoint, QPolygon *aNewPoly ) { *aNewPoly << aPoint; repaint_needed_ = 1; } void ImageHolder::focusOnArea(QListWidgetItem *anItem) { QString text = anItem->text(); Tool tool = NoTool; if (-1 != text.indexOf("BBox")) tool = BoundingBoxTool; else if (-1 != text.indexOf("Poly")) tool = PolygonTool; /* looking for a number of selected area */ if (NoTool != tool) { bool ok = 0; focused_selection_ = getNumFromString(&text, "#", ";", &ok); if (!ok) { focused_selection_ = -1; focused_selection_type_ = NoFigure; return; /* NOTREACHED */ } switch (tool) { case BoundingBoxTool: focused_selection_type_ = RectFigure; break; case PolygonTool: focused_selection_type_ = PolyFigure; break; default: focused_selection_type_ = NoFigure; break; } } update(); } void ImageHolder::scaleImage( ZoomDirection aDirection, double scaleFactor ) { //QSize size = pixmap()->size(); QSize size = this->size(); /* zoomin */ if (ZoomIn == aDirection) { size *= scaleFactor; scale_ *= scaleFactor; } /* zoomout */ else if (ZoomOut == aDirection) { size /= scaleFactor; scale_ /= scaleFactor; } // setScaledContents(true); this->resize(size); // setPixmap( // image_->scaled( // size, // Qt::IgnoreAspectRatio, // Qt::SmoothTransformation // ) // ); // setScaledContents(false); //resize(scaleFactor * pixmap()->size()); //emit imageScaled(); } void ImageHolder::clearFocusOnArea() { focused_selection_ = -1; focused_selection_type_ = NoFigure; } void ImageHolder::clearEdition() { hovered_point_.figure = NoFigure; hovered_point_.figureID = -1; hovered_point_.pointID = -1; } void ImageHolder::setTool(Tool aTool) { switch(aTool) { case BoundingBoxTool: tool_ = BoundingBoxTool; break; case PolygonTool: tool_ = PolygonTool; break; case TaggingTool: tool_ = TaggingTool; break; default: tool_ = NoTool; break; } } void ImageHolder::setBoundingBoxList(QList< BoundingBox * > *aBBoxList) { if (0 == aBBoxList) { return; /* NOTREACHED */ } list_bounding_box_ = aBBoxList; } void ImageHolder::setPolygonList(QList< Polygon * > *aPolygonList) { if (0 == aPolygonList) { return; /* NOTREACHED */ } list_polygon_ = aPolygonList; } void ImageHolder::setLabelColorList(QList< uint > *aLabelColorList) { if (0 == aLabelColorList) { return; /* NOTREACHED */ } list_label_color_ = aLabelColorList; } void ImageHolder::setMainLabelNum(int *aNum) { if (0 == aNum) { return; /* NOTREACHED */ } main_label_ = aNum; } void ImageHolder::setImage(QPixmap *anImage) { if (0 == anImage) { return; /* NOTREACHED */ } image_ = anImage; } void ImageHolder::clearAll() { //list_bounding_box_->clear(); bounding_box_.rect.setRect(-1, -1, 0, 0); //list_polygon_->clear(); polygon_.poly.clear(); clearFocusOnArea(); state_ = StandBy; update(); } void ImageHolder::clearLast() { switch (tool_) { case BoundingBoxTool: bounding_box_.rect.setRect(-1, -1, 0, 0); break; case PolygonTool: polygon_.poly.clear(); break; case TaggingTool: break; default: break; } bounding_box_.rect.setRect(-1, -1, 0, 0); state_ = StandBy; update(); } void ImageHolder::confirmSelection() { if (NewSelection != state_ || NoTool == tool_) { return; /* NOTREACHED */ } if (BoundingBoxTool == tool_) { BoundingBox *bbox = new BoundingBox; *bbox = bounding_box_; list_bounding_box_->append(bbox); bounding_box_.rect.setRect(-1, -1, 0, 0); } else if (PolygonTool == tool_) { Polygon *poly = new Polygon; *poly = polygon_; list_polygon_->append(poly); polygon_.poly.clear(); } list_poly_history_.clear(); state_ = StandBy; update(); } ImageHolder::State ImageHolder::state() { return state_; } ImageHolder::Tool ImageHolder::tool() { return tool_; } int ImageHolder::focusedSelection() { return focused_selection_; } Figure ImageHolder::focusedSelectionType() { return focused_selection_type_; } void ImageHolder::undo() { if (PolygonTool == tool_ && NewSelection == state_ && !polygon_.poly.isEmpty()) { list_poly_history_.append(polygon_.poly.last()); polygon_.poly.pop_back(); repaint_needed_ = 1; } if (repaint_needed_) { update(); repaint_needed_ = 0; } } void ImageHolder::redo() { if (PolygonTool == tool_ && NewSelection == state_ && !list_poly_history_.isEmpty()) { polygon_.poly.append(list_poly_history_.last()); list_poly_history_.pop_back(); repaint_needed_ = 1; } if (repaint_needed_) { update(); repaint_needed_ = 0; } } void ImageHolder::checkForPoints(QPoint *aPos) { if ((!list_polygon_->count() && !list_bounding_box_->count()) || !aPos) { return; /* NOTREACHED */ } int newRadius = 0; int x = aPos->x(); int y = aPos->y(); /* center coordinates */ int xc = 0; int yc = 0; for (int i = 0; i < list_polygon_->count(); i++) { QPolygon poly = list_polygon_->at(i)->poly; for (int j = 0; j < poly.count(); j++) { xc = poly.at(j).x(); yc = poly.at(j).y(); newRadius = qSqrt(qPow(x - xc, 2) + qPow(y - yc, 2)); if (newRadius <= point_radius_) { hovered_point_.figure = PolyFigure; hovered_point_.figureID = i; hovered_point_.pointID = j; repaint_needed_ = 1; return; /* NOTREACHED */ } } } for (int i = 0; i < list_bounding_box_->count(); i++) { QRect rect = list_bounding_box_->at(i)->rect; for (int j = 0; j < 4; j++) { if (!j) { xc = rect.left(); yc = rect.top(); } else if (1 == j) { xc = rect.right(); yc = rect.top(); } else if (2 == j) { xc = rect.right(); yc = rect.bottom(); } else if (3 == j) { xc = rect.left(); yc = rect.bottom(); } newRadius = qSqrt(qPow(x - xc, 2) + qPow(y - yc, 2)); if (newRadius <= point_radius_) { hovered_point_.figure = RectFigure; hovered_point_.figureID = i; hovered_point_.pointID = j; repaint_needed_ = 1; return; /* NOTREACHED */ } } } hovered_point_.figure = NoFigure; hovered_point_.figureID = -1; hovered_point_.pointID = -1; repaint_needed_ = 1; } void ImageHolder::keyPressEvent(QKeyEvent *anEvent) { QLabel::keyPressEvent(anEvent); //keyboard_modifier_ = anEvent->modifiers(); if (repaint_needed_) { update(); repaint_needed_ = 0; } } void ImageHolder::mouseMoveEvent(QMouseEvent *anEvent) { QPoint pos = anEvent->pos() / scale_; if (anEvent->pos().x() < 0) pos.setX(0); if (width() < anEvent->pos().x()) pos.setX(width() - 1); if (anEvent->pos().y() < 0) pos.setY(0); if (height() < anEvent->pos().y()) pos.setY(height() - 1); if ((anEvent->buttons() & Qt::LeftButton) && BoundingBoxTool == tool_ && NewSelection == state_ && Qt::NoModifier == keyboard_modifier_) { triggerBoundBox(pos, prev_cursor_pos_, &(bounding_box_.rect)); } if (PolygonTool == tool_ && NewSelection == state_ && (anEvent->buttons() & Qt::LeftButton)) { polygon_.poly.setPoint(polygon_.poly.count() - 1, pos); //triggerPolygon(pos, &(polygon_.poly)); repaint_needed_ = 1; } if (-1 != focused_selection_ && !(anEvent->buttons() & Qt::LeftButton)) { checkForPoints(&pos); } /* editing polygons */ if (-1 != hovered_point_.figureID && !list_polygon_->isEmpty() && PolyFigure == hovered_point_.figure && (anEvent->buttons() & Qt::LeftButton)) { Polygon *poly = list_polygon_->at(hovered_point_.figureID); poly->poly.setPoint(hovered_point_.pointID, pos); repaint_needed_ = 1; } /* editing bounding boxes */ if (-1 != hovered_point_.figureID && !list_bounding_box_->isEmpty() && RectFigure == hovered_point_.figure && (anEvent->buttons() & Qt::LeftButton)) { BoundingBox *rect = list_bounding_box_->at(hovered_point_.figureID); if (0 == hovered_point_.pointID) rect->rect.setTopLeft(pos); else if (1 == hovered_point_.pointID) rect->rect.setTopRight(pos); else if (2 == hovered_point_.pointID) rect->rect.setBottomRight(pos); else if (3 == hovered_point_.pointID) rect->rect.setBottomLeft(pos); repaint_needed_ = 1; } if (repaint_needed_) { update(); repaint_needed_ = 0; } } void ImageHolder::mousePressEvent(QMouseEvent *anEvent) { /* remembering coordinates of the click */ if ((anEvent->buttons() & Qt::LeftButton) || (anEvent->buttons() & Qt::RightButton)) { prev_cursor_pos_ = anEvent->pos() / scale_; } QPoint pos = anEvent->pos() / scale_; if (anEvent->buttons() & Qt::LeftButton) { /* clearing the selected area if it is not confirmed */ if (NewSelection == state_ && BoundingBoxTool == tool_) { bounding_box_.rect.setRect(-1, -1, 0, 0); state_ = StandBy; } /* making new points for poly */ if (PolygonTool == tool_ && NewSelection == state_ && Qt::NoModifier == keyboard_modifier_) { triggerPolygon(pos, &(polygon_.poly)); } /* starting new selection by click */ if (StandBy == state_ && NoTool != tool_ && -1 == focused_selection_) { state_ = NewSelection; emit selectionStarted(); polygon_.poly.clear(); if (PolygonTool == tool_) { polygon_.poly << prev_cursor_pos_; } } } if (repaint_needed_) { update(); repaint_needed_ = 0; } } void ImageHolder::mouseReleaseEvent(QMouseEvent *anEvent) { Q_UNUSED(anEvent) if (-1 != hovered_point_.figureID) emit areaEdited(); if (RectFigure == hovered_point_.figure && -1 != hovered_point_.figureID && !list_bounding_box_-> at(hovered_point_.figureID)-> rect.isValid() ) { BoundingBox *rect = list_bounding_box_->at(hovered_point_.figureID); rect->rect = rect->rect.normalized(); } } /* * */