/* * Object.cpp * * Created on: 2011-10-23 * Author: matlab */ /* * VisualObject.h * * Created on: 2011-10-21 * Author: matlab */ #include "Object.h" #include "KeypointItem.h" #include "qtipl.h" #include #include #include #include #include #include #include #include #include #include #include #include #include Object::Object(QWidget * parent) : QWidget(parent), iplImage_(0), graphicsView_(0), id_(0), graphicsViewMode_(true), detectorType_("NA"), descriptorType_("NA") { setupUi(); } Object::Object(int id, const std::vector & keypoints, const cv::Mat & descriptors, const IplImage * iplImage, const QString & detectorType, const QString & descriptorType, QWidget * parent) : QWidget(parent), iplImage_(0), graphicsView_(0), id_(id), graphicsViewMode_(true), detectorType_(detectorType), descriptorType_(descriptorType) { setupUi(); this->setData(keypoints, descriptors, iplImage); } Object::~Object() { if(iplImage_) { cvReleaseImage(&iplImage_); } } void Object::setupUi() { graphicsView_ = new QGraphicsView(this); graphicsView_->setVisible(true); graphicsView_->setTransformationAnchor(QGraphicsView::AnchorUnderMouse); graphicsView_->setScene(new QGraphicsScene(graphicsView_)); this->setLayout(new QVBoxLayout(graphicsView_)); this->layout()->addWidget(graphicsView_); this->layout()->setContentsMargins(0,0,0,0); _menu = new QMenu(tr(""), this); _showImage = _menu->addAction(tr("Show image")); _showImage->setCheckable(true); _showImage->setChecked(true); _showFeatures = _menu->addAction(tr("Show features")); _showFeatures->setCheckable(true); _showFeatures->setChecked(true); _mirrorView = _menu->addAction(tr("Mirror view")); _mirrorView->setCheckable(true); _mirrorView->setChecked(false); _plainView = _menu->addAction(tr("Plain view")); _plainView->setCheckable(true); _plainView->setChecked(!graphicsViewMode_); _menu->addSeparator(); _saveImage = _menu->addAction(tr("Save picture...")); _menu->addSeparator(); _delete = _menu->addAction(tr("Delete")); _delete->setEnabled(false); this->setId(id_); graphicsView_->setRubberBandSelectionMode(Qt::ContainsItemShape); graphicsView_->setDragMode(QGraphicsView::RubberBandDrag); connect(graphicsView_->scene(), SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged())); } void Object::setId(int id) { id_=id; if(id_) { _savedFileName = QString("object_%1.png").arg(id_); } } void Object::setGraphicsViewMode(bool on) { graphicsViewMode_ = on; graphicsView_->setVisible(on); //update items' color if(on) { if(keypointItems_.size() == 0) { this->setupGraphicsView(); } else { for(int i=0; isetColor(kptColors_.at(i)); } } } graphicsView_->fitInView(graphicsView_->sceneRect(), Qt::KeepAspectRatio); _plainView->setChecked(!on); this->update(); } void Object::setData(const std::vector & keypoints, const cv::Mat & descriptors, const IplImage * image) { keypoints_ = keypoints; descriptors_ = descriptors; kptColors_ = QVector(keypoints.size(), defaultColor()); keypointItems_.clear(); rectItems_.clear(); if(iplImage_) { cvReleaseImage(&iplImage_); iplImage_ = 0; } if(image) { /* create destination image Note that cvGetSize will return the width and the height of ROI */ iplImage_ = cvCreateImage(cvGetSize(image), image->depth, image->nChannels); /* copy subimage */ cvCopy(image, iplImage_, NULL); image_ = QPixmap::fromImage(Ipl2QImage(iplImage_)); this->setMinimumSize(image_.size()); } if(graphicsViewMode_) { this->setupGraphicsView(); } } void Object::resetKptsColor() { for(int i=0; isetColor(this->defaultColor()); } } rectItems_.clear(); } void Object::setKptColor(unsigned int index, const QColor & color) { if(index < kptColors_.size()) { kptColors_[index] = color; } if(graphicsViewMode_) { if(index < keypointItems_.size()) { keypointItems_.at(index)->setColor(color); } } } void Object::addRect(QGraphicsRectItem * rect) { graphicsView_->scene()->addItem(rect); rectItems_.append(rect); } QList Object::selectedItems() const { return graphicsView_->scene()->selectedItems(); } bool Object::isImageShown() const { return _showImage->isChecked(); } bool Object::isFeaturesShown() const { return _showFeatures->isChecked(); } bool Object::isMirrorView() const { return _mirrorView->isChecked(); } void Object::setDeletable(bool deletable) { _delete->setEnabled(deletable); } void Object::save(QDataStream & streamPtr) const { streamPtr << id_ << detectorType_ << descriptorType_; streamPtr << (int)keypoints_.size(); for(int j=0; j kpts; cv::Mat descriptors; int nKpts; streamPtr >> id_ >> detectorType_ >> descriptorType_ >> nKpts; for(int i=0;i> kpt.angle >> kpt.class_id >> kpt.octave >> kpt.pt.x >> kpt.pt.y >> kpt.response >> kpt.size; kpts.push_back(kpt); } int rows,cols,type; qint64 dataSize; streamPtr >> rows >> cols >> type >> dataSize; QByteArray data; streamPtr >> data; descriptors = cv::Mat(rows, cols, type, data.data()).clone(); streamPtr >> image_; this->setData(kpts, descriptors, 0); this->setMinimumSize(image_.size()); } void Object::paintEvent(QPaintEvent *event) { if(graphicsViewMode_) { QWidget::paintEvent(event); } else { if(!image_.isNull()) { //Scale float w = image_.width(); float h = image_.height(); float widthRatio = this->rect().width() / w; float heightRatio = this->rect().height() / h; float ratio = 1.0f; //printf("w=%f, h=%f, wR=%f, hR=%f, sW=%f, sH=%f\n", w, h, widthRatio, heightRatio, sceneRect.width(), sceneRect.height()); if(widthRatio < heightRatio) { ratio = widthRatio; } else { ratio = heightRatio; } //printf("ratio=%f\n",ratio); w *= ratio; h *= ratio; float offsetX = 0.0f; float offsetY = 0.0f; if(w < this->rect().width()) { offsetX = (this->rect().width() - w)/2.0f; } if(h < this->rect().height()) { offsetY = (this->rect().height() - h)/2.0f; } QPainter painter(this); if(_mirrorView->isChecked()) { painter.translate(offsetX+w, offsetY); painter.scale(-ratio, ratio); } else { painter.translate(offsetX, offsetY); painter.scale(ratio, ratio); } if(_showImage->isChecked()) { painter.drawPixmap(QPoint(0,0), image_); } if(_showFeatures->isChecked()) { drawKeypoints(&painter); } for(int i=0; itransform(), true); painter.setPen(rectItems_.at(i)->pen()); painter.drawRect(rectItems_.at(i)->rect()); painter.restore(); } } } } void Object::resizeEvent(QResizeEvent* event) { if(graphicsViewMode_) { graphicsView_->fitInView(graphicsView_->sceneRect(), Qt::KeepAspectRatio); } QWidget::resizeEvent(event); } void Object::contextMenuEvent(QContextMenuEvent * event) { QAction * action = _menu->exec(event->globalPos()); if(action == _saveImage) { QString text; if(_savedFileName.isEmpty()) { #ifndef WIN32 _savedFileName = QDir::homePath(); #endif _savedFileName+="/figure.png"; } text = QFileDialog::getSaveFileName(this, tr("Save figure to ..."), _savedFileName, "*.png *.xpm *.jpg *.pdf"); if(!text.isEmpty()) { if(!text.endsWith(".png") && !text.endsWith(".xpm") && !text.endsWith(".jpg") && !text.endsWith(".pdf")) { text.append(".png");//default } _savedFileName = text; getSceneAsPixmap().save(text); } } else if(action == _showFeatures || action == _showImage) { if(graphicsViewMode_) { this->updateItemsShown(); } else { this->update(); } } else if(action == _mirrorView) { graphicsView_->setTransform(QTransform().scale(this->isMirrorView()?-1.0:1.0, 1.0)); if(graphicsViewMode_) { graphicsView_->fitInView(graphicsView_->sceneRect(), Qt::KeepAspectRatio); } else { this->update(); } } else if(action == _delete) { emit removalTriggered(this); } else if(action == _plainView) { this->setGraphicsViewMode(!_plainView->isChecked()); } QWidget::contextMenuEvent(event); } QPixmap Object::getSceneAsPixmap() { if(graphicsViewMode_) { QPixmap img(graphicsView_->sceneRect().width(), graphicsView_->sceneRect().height()); QPainter p(&img); graphicsView_->scene()->render(&p, graphicsView_->sceneRect(), graphicsView_->sceneRect()); return img; } else { return QPixmap::grabWidget(this); } } void Object::updateItemsShown() { QList items = graphicsView_->scene()->items(); for(int i=0; i(items.at(i))) { items.at(i)->setVisible(_showFeatures->isChecked()); } else if(qgraphicsitem_cast(items.at(i))) { items.at(i)->setVisible(_showImage->isChecked()); } } } void Object::drawKeypoints(QPainter * painter) { QList items; KeypointItem * item = 0; int i = 0; for(std::vector::const_iterator iter = keypoints_.begin(); iter != keypoints_.end(); ++iter, ++i ) { const cv::KeyPoint & r = *iter; float radius = 14*1.2/9.*2;//r.size*1.2/9.*2; if(graphicsViewMode_) { QString info = QString( "ID = %1\n" "Response = %2\n" "Angle = %3\n" "X = %4\n" "Y = %5\n" "Size = %6").arg(i+1).arg(r.response).arg(r.angle).arg(r.pt.x).arg(r.pt.y).arg(r.size); // YELLOW = NEW and multiple times item = new KeypointItem(i+1, r.pt.x-radius, r.pt.y-radius, radius*2, info, kptColors_.at(i)); item->setVisible(this->isFeaturesShown()); item->setZValue(1); graphicsView_->scene()->addItem(item); keypointItems_.append(item); } if(painter) { painter->save(); painter->setPen(kptColors_.at(i)); painter->setBrush(kptColors_.at(i)); painter->drawEllipse(r.pt.x-radius, r.pt.y-radius, radius*2, radius*2); painter->restore(); } } } QColor Object::defaultColor() const { int alpha = 20*255/100; return QColor(255, 255, 0, alpha); } std::vector Object::selectedKeypoints() const { std::vector selected; if(graphicsViewMode_) { QList items = graphicsView_->scene()->selectedItems(); for(int i=0; i(items.at(i))) { selected.push_back(keypoints_.at(((KeypointItem*)items.at(i))->id()-1)); // ids start at 1 } } } return selected; } void Object::setupGraphicsView() { graphicsView_->scene()->clear(); graphicsView_->scene()->setSceneRect(image_.rect()); QList items; if(image_.width() > 0 && image_.height() > 0) { QRectF sceneRect = graphicsView_->sceneRect(); QGraphicsPixmapItem * pixmapItem = graphicsView_->scene()->addPixmap(image_); pixmapItem->setVisible(this->isImageShown()); this->drawKeypoints(); graphicsView_->fitInView(sceneRect, Qt::KeepAspectRatio); } }