Added some new features ("update objects" button and region selection) described in issue 2.
git-svn-id: http://find-object.googlecode.com/svn/trunk/find_object@74 620bd6b2-0a58-f614-fd9a-1bd335dccda9
This commit is contained in:
parent
a1c6ec7509
commit
27652b4f8f
@ -118,8 +118,8 @@ int main(int argc, char * argv[])
|
||||
// PROCESS NEAREST NEIGHBOR RESULTS
|
||||
////////////////////////////
|
||||
// Set gui data
|
||||
objWidget.setData(objectKeypoints, objectDescriptors, objectImg);
|
||||
sceneWidget.setData(sceneKeypoints, sceneDescriptors, sceneImg);
|
||||
objWidget.setData(objectKeypoints, objectDescriptors, objectImg, "SURF", "SURF");
|
||||
sceneWidget.setData(sceneKeypoints, sceneDescriptors, sceneImg, "SURF", "SURF");
|
||||
|
||||
// Find correspondences by NNDR (Nearest Neighbor Distance Ratio)
|
||||
float nndrRatio = 0.6;
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
#include <opencv2/imgproc/imgproc_c.h>
|
||||
#include <opencv2/highgui/highgui_c.h>
|
||||
|
||||
AddObjectDialog::AddObjectDialog(Camera * camera, QList<ObjWidget*> * objects, QWidget * parent, Qt::WindowFlags f) :
|
||||
AddObjectDialog::AddObjectDialog(Camera * camera, QList<ObjWidget*> * objects, bool mirrorView, QWidget * parent, Qt::WindowFlags f) :
|
||||
QDialog(parent, f),
|
||||
camera_(camera),
|
||||
objects_(objects),
|
||||
@ -32,8 +32,11 @@ AddObjectDialog::AddObjectDialog(Camera * camera, QList<ObjWidget*> * objects, Q
|
||||
connect(ui_->pushButton_back, SIGNAL(clicked()), this, SLOT(back()));
|
||||
connect(ui_->pushButton_next, SIGNAL(clicked()), this, SLOT(next()));
|
||||
connect(ui_->pushButton_takePicture, SIGNAL(clicked()), this, SLOT(takePicture()));
|
||||
connect(ui_->comboBox_selection, SIGNAL(currentIndexChanged(int)), this, SLOT(changeSelectionMode()));
|
||||
|
||||
connect(ui_->cameraView, SIGNAL(selectionChanged()), this, SLOT(updateNextButton()));
|
||||
connect(ui_->cameraView, SIGNAL(roiChanged(const QRect &)), this, SLOT(updateNextButton(const QRect &)));
|
||||
ui_->cameraView->setMirrorView(mirrorView);
|
||||
|
||||
this->setState(kTakePicture);
|
||||
}
|
||||
@ -72,19 +75,44 @@ void AddObjectDialog::takePicture()
|
||||
|
||||
void AddObjectDialog::updateNextButton()
|
||||
{
|
||||
updateNextButton(QRect());
|
||||
}
|
||||
|
||||
void AddObjectDialog::updateNextButton(const QRect & rect)
|
||||
{
|
||||
roi_ = rect;
|
||||
if(state_ == kSelectFeatures)
|
||||
{
|
||||
if(ui_->cameraView->selectedItems().size() > 0)
|
||||
if(ui_->comboBox_selection->currentIndex() == 1)
|
||||
{
|
||||
ui_->pushButton_next->setEnabled(true);
|
||||
if(ui_->cameraView->selectedItems().size() > 0)
|
||||
{
|
||||
ui_->pushButton_next->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_->pushButton_next->setEnabled(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_->pushButton_next->setEnabled(false);
|
||||
if(roi_.isNull())
|
||||
{
|
||||
ui_->pushButton_next->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_->pushButton_next->setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddObjectDialog::changeSelectionMode()
|
||||
{
|
||||
this->setState(kSelectFeatures);
|
||||
}
|
||||
|
||||
void AddObjectDialog::setState(int state)
|
||||
{
|
||||
state_ = state;
|
||||
@ -97,8 +125,10 @@ void AddObjectDialog::setState(int state)
|
||||
ui_->label_instruction->setText(tr("Place the object in front of the camera and click \"Take picture\"."));
|
||||
ui_->pushButton_next->setText(tr("Next"));
|
||||
ui_->cameraView->setVisible(true);
|
||||
ui_->cameraView->clearRoiSelection();
|
||||
ui_->objectView->setVisible(false);
|
||||
ui_->cameraView->setGraphicsViewMode(false);
|
||||
ui_->comboBox_selection->setVisible(false);
|
||||
if(!camera_ || !camera_->start())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Camera error"), tr("Camera is not started!"));
|
||||
@ -118,12 +148,23 @@ void AddObjectDialog::setState(int state)
|
||||
ui_->pushButton_back->setEnabled(true);
|
||||
ui_->pushButton_next->setEnabled(false);
|
||||
ui_->pushButton_takePicture->setEnabled(false);
|
||||
ui_->label_instruction->setText(tr("Select features representing the object."));
|
||||
ui_->pushButton_next->setText(tr("Next"));
|
||||
ui_->cameraView->setVisible(true);
|
||||
ui_->cameraView->clearRoiSelection();
|
||||
ui_->objectView->setVisible(false);
|
||||
ui_->cameraView->setGraphicsViewMode(true);
|
||||
updateNextButton();
|
||||
ui_->comboBox_selection->setVisible(true);
|
||||
|
||||
if(ui_->comboBox_selection->currentIndex() == 1)
|
||||
{
|
||||
ui_->label_instruction->setText(tr("Select features representing the object."));
|
||||
ui_->cameraView->setGraphicsViewMode(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_->label_instruction->setText(tr("Select region representing the object."));
|
||||
ui_->cameraView->setGraphicsViewMode(false);
|
||||
}
|
||||
updateNextButton(QRect());
|
||||
}
|
||||
else if(state == kVerifySelection)
|
||||
{
|
||||
@ -136,24 +177,59 @@ void AddObjectDialog::setState(int state)
|
||||
ui_->pushButton_next->setText(tr("End"));
|
||||
ui_->cameraView->setVisible(true);
|
||||
ui_->objectView->setVisible(true);
|
||||
ui_->cameraView->setGraphicsViewMode(true);
|
||||
ui_->objectView->setMirrorView(ui_->cameraView->isMirrorView());
|
||||
ui_->objectView->setSizedFeatures(ui_->cameraView->isSizedFeatures());
|
||||
ui_->comboBox_selection->setVisible(false);
|
||||
if(ui_->comboBox_selection->currentIndex() == 1)
|
||||
{
|
||||
ui_->cameraView->setGraphicsViewMode(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_->cameraView->setGraphicsViewMode(false);
|
||||
}
|
||||
|
||||
std::vector<cv::KeyPoint> selectedKeypoints = ui_->cameraView->selectedKeypoints();
|
||||
|
||||
// Select keypoints
|
||||
if(selectedKeypoints.size() && cvImage_)
|
||||
if(cvImage_ &&
|
||||
((ui_->comboBox_selection->currentIndex() == 1 && selectedKeypoints.size()) ||
|
||||
(ui_->comboBox_selection->currentIndex() == 0 && !roi_.isNull())))
|
||||
{
|
||||
CvRect roi = computeROI(selectedKeypoints);
|
||||
cvSetImageROI(cvImage_, roi);
|
||||
if(roi.x != 0 || roi.y != 0)
|
||||
CvRect roi;
|
||||
if(ui_->comboBox_selection->currentIndex() == 1)
|
||||
{
|
||||
for(unsigned int i=0; i<selectedKeypoints.size(); ++i)
|
||||
roi = computeROI(selectedKeypoints);
|
||||
}
|
||||
else
|
||||
{
|
||||
roi.x = roi_.x();
|
||||
roi.y = roi_.y();
|
||||
roi.width = roi_.width();
|
||||
roi.height = roi_.height();
|
||||
}
|
||||
cvSetImageROI(cvImage_, roi);
|
||||
|
||||
if(ui_->comboBox_selection->currentIndex() == 1)
|
||||
{
|
||||
if(roi.x != 0 || roi.y != 0)
|
||||
{
|
||||
selectedKeypoints.at(i).pt.x -= roi.x;
|
||||
selectedKeypoints.at(i).pt.y -= roi.y;
|
||||
for(unsigned int i=0; i<selectedKeypoints.size(); ++i)
|
||||
{
|
||||
selectedKeypoints.at(i).pt.x -= roi.x;
|
||||
selectedKeypoints.at(i).pt.y -= roi.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
ui_->objectView->setData(selectedKeypoints, cv::Mat(), cvImage_);
|
||||
else
|
||||
{
|
||||
// Extract keypoints
|
||||
selectedKeypoints.clear();
|
||||
cv::FeatureDetector * detector = Settings::createFeaturesDetector();
|
||||
detector->detect(cvImage_, selectedKeypoints);
|
||||
delete detector;
|
||||
}
|
||||
ui_->objectView->setData(selectedKeypoints, cv::Mat(), cvImage_, Settings::currentDetectorType(), "");
|
||||
ui_->objectView->setMinimumSize(roi.width, roi.height);
|
||||
ui_->objectView->update();
|
||||
cvResetImageROI(cvImage_);
|
||||
@ -168,33 +244,25 @@ void AddObjectDialog::setState(int state)
|
||||
}
|
||||
else if(state == kClosing)
|
||||
{
|
||||
std::vector<cv::KeyPoint> selectedKeypoints = ui_->cameraView->selectedKeypoints();
|
||||
if(selectedKeypoints.size())
|
||||
std::vector<cv::KeyPoint> keypoints = ui_->objectView->keypoints();
|
||||
if((ui_->comboBox_selection->currentIndex() == 1 && keypoints.size()) ||
|
||||
(ui_->comboBox_selection->currentIndex() == 0 && !roi_.isNull()))
|
||||
{
|
||||
// Extract descriptors
|
||||
cv::Mat descriptors;
|
||||
cv::DescriptorExtractor * extractor = Settings::createDescriptorsExtractor();
|
||||
extractor->compute(cvImage_, selectedKeypoints, descriptors);
|
||||
delete extractor;
|
||||
if(selectedKeypoints.size() != (unsigned int)descriptors.rows)
|
||||
if(keypoints.size())
|
||||
{
|
||||
printf("ERROR : keypoints=%d != descriptors=%d\n", (int)selectedKeypoints.size(), descriptors.rows);
|
||||
}
|
||||
// Extract descriptors
|
||||
cv::DescriptorExtractor * extractor = Settings::createDescriptorsExtractor();
|
||||
extractor->compute(ui_->objectView->iplImage(), keypoints, descriptors);
|
||||
delete extractor;
|
||||
|
||||
CvRect roi = computeROI(selectedKeypoints);
|
||||
cvSetImageROI(cvImage_, roi);
|
||||
if(roi.x != 0 || roi.y != 0)
|
||||
{
|
||||
for(unsigned int i=0; i<selectedKeypoints.size(); ++i)
|
||||
if(keypoints.size() != (unsigned int)descriptors.rows)
|
||||
{
|
||||
selectedKeypoints.at(i).pt.x -= roi.x;
|
||||
selectedKeypoints.at(i).pt.y -= roi.y;
|
||||
printf("ERROR : keypoints=%d != descriptors=%d\n", (int)keypoints.size(), descriptors.rows);
|
||||
}
|
||||
}
|
||||
objects_->append(new ObjWidget(0, selectedKeypoints, descriptors, cvImage_, Settings::currentDetectorType(), Settings::currentDescriptorType()));
|
||||
cvResetImageROI(cvImage_);
|
||||
|
||||
|
||||
objects_->append(new ObjWidget(0, keypoints, descriptors, ui_->objectView->iplImage(), Settings::currentDetectorType(), Settings::currentDescriptorType()));
|
||||
|
||||
this->accept();
|
||||
}
|
||||
@ -227,7 +295,7 @@ void AddObjectDialog::update(const cv::Mat & image)
|
||||
detector->detect(cvImage_, keypoints);
|
||||
delete detector;
|
||||
|
||||
ui_->cameraView->setData(keypoints, cv::Mat(), cvImage_);
|
||||
ui_->cameraView->setData(keypoints, cv::Mat(), cvImage_, Settings::currentDetectorType(), "");
|
||||
ui_->cameraView->update();
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ class AddObjectDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AddObjectDialog(Camera * camera, QList<ObjWidget*> * objects, QWidget * parent = 0, Qt::WindowFlags f = 0);
|
||||
AddObjectDialog(Camera * camera, QList<ObjWidget*> * objects, bool mirrorView, QWidget * parent = 0, Qt::WindowFlags f = 0);
|
||||
virtual ~AddObjectDialog();
|
||||
|
||||
private slots:
|
||||
@ -30,6 +30,8 @@ private slots:
|
||||
void cancel();
|
||||
void takePicture();
|
||||
void updateNextButton();
|
||||
void updateNextButton(const QRect &);
|
||||
void changeSelectionMode();
|
||||
|
||||
protected:
|
||||
virtual void closeEvent(QCloseEvent* event);
|
||||
@ -45,6 +47,7 @@ private:
|
||||
|
||||
enum State{kTakePicture, kSelectFeatures, kVerifySelection, kClosing};
|
||||
int state_;
|
||||
QRect roi_;
|
||||
};
|
||||
|
||||
#endif /* ADDOBJECTDIALOG_H_ */
|
||||
|
||||
@ -61,11 +61,14 @@ MainWindow::MainWindow(Camera * camera, QWidget * parent) :
|
||||
ui_->dockWidget_parameters->hide();
|
||||
ui_->menuView->addAction(ui_->dockWidget_parameters->toggleViewAction());
|
||||
ui_->menuView->addAction(ui_->dockWidget_objects->toggleViewAction());
|
||||
connect(ui_->toolBox, SIGNAL(parametersChanged()), this, SLOT(notifyParametersChanged()));
|
||||
|
||||
ui_->imageView_source->setGraphicsViewMode(false);
|
||||
|
||||
//reset button
|
||||
connect(ui_->pushButton_restoreDefaults, SIGNAL(clicked()), ui_->toolBox, SLOT(resetCurrentPage()));
|
||||
// udpate objects button
|
||||
connect(ui_->pushButton_updateObjects, SIGNAL(clicked()), this, SLOT(updateObjects()));
|
||||
|
||||
ui_->actionStop_camera->setEnabled(false);
|
||||
ui_->actionSave_objects->setEnabled(false);
|
||||
@ -185,7 +188,7 @@ void MainWindow::removeObject(ObjWidget * object)
|
||||
void MainWindow::addObject()
|
||||
{
|
||||
disconnect(camera_, SIGNAL(imageReceived(const cv::Mat &)), this, SLOT(update(const cv::Mat &)));
|
||||
AddObjectDialog dialog(camera_, &objects_, this);
|
||||
AddObjectDialog dialog(camera_, &objects_, ui_->imageView_source->isMirrorView(), this);
|
||||
if(dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
showObject(objects_.last());
|
||||
@ -198,6 +201,7 @@ void MainWindow::showObject(ObjWidget * obj)
|
||||
if(obj)
|
||||
{
|
||||
obj->setGraphicsViewMode(false);
|
||||
obj->setMirrorView(ui_->imageView_source->isMirrorView());
|
||||
QList<ObjWidget*> objs = ui_->objects_area->findChildren<ObjWidget*>();
|
||||
QVBoxLayout * vLayout = new QVBoxLayout();
|
||||
obj->setMinimumSize(obj->image().width(), obj->image().height());
|
||||
@ -214,8 +218,10 @@ void MainWindow::showObject(ObjWidget * obj)
|
||||
}
|
||||
|
||||
QLabel * title = new QLabel(QString("%1 (%2)").arg(obj->id()).arg(QString::number(obj->keypoints().size())), this);
|
||||
QLabel * detectedLabel = new QLabel(this);
|
||||
QLabel * detectorDescriptorType = new QLabel(QString("%1/%2").arg(obj->detectorType()).arg(obj->descriptorType()), this);
|
||||
QLabel * detectedLabel = new QLabel(this);
|
||||
title->setObjectName(QString("%1title").arg(obj->id()));
|
||||
detectorDescriptorType->setObjectName(QString("%1type").arg(obj->id()));
|
||||
detectedLabel->setObjectName(QString("%1detection").arg(obj->id()));
|
||||
QHBoxLayout * hLayout = new QHBoxLayout();
|
||||
hLayout->addWidget(title);
|
||||
@ -236,6 +242,46 @@ void MainWindow::showObject(ObjWidget * obj)
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::updateObjects()
|
||||
{
|
||||
if(objects_.size())
|
||||
{
|
||||
for(int i=0; i<objects_.size(); ++i)
|
||||
{
|
||||
IplImage * img = cvCloneImage(objects_.at(i)->iplImage());
|
||||
cv::FeatureDetector * detector = Settings::createFeaturesDetector();
|
||||
std::vector<cv::KeyPoint> keypoints;
|
||||
detector->detect(img, keypoints);
|
||||
delete detector;
|
||||
|
||||
cv::Mat descriptors;
|
||||
if(keypoints.size())
|
||||
{
|
||||
cv::DescriptorExtractor * extractor = Settings::createDescriptorsExtractor();
|
||||
extractor->compute(img, keypoints, descriptors);
|
||||
delete extractor;
|
||||
if((int)keypoints.size() != descriptors.rows)
|
||||
{
|
||||
printf("ERROR : kpt=%d != descriptors=%d\n", (int)keypoints.size(), descriptors.rows);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("WARNING: no features detected in object %d !?!\n", objects_.at(i)->id());
|
||||
}
|
||||
objects_.at(i)->setData(keypoints, descriptors, img, Settings::currentDetectorType(), Settings::currentDescriptorType());
|
||||
|
||||
//update object labels
|
||||
QLabel * title = qFindChild<QLabel*>(this, QString("%1title").arg(objects_.at(i)->id()));
|
||||
title->setText(QString("%1 (%2)").arg(objects_.at(i)->id()).arg(QString::number(objects_.at(i)->keypoints().size())));
|
||||
QLabel * detectorDescriptorType = qFindChild<QLabel*>(this, QString("%1type").arg(objects_.at(i)->id()));
|
||||
detectorDescriptorType->setText(QString("%1/%2").arg(objects_.at(i)->detectorType()).arg(objects_.at(i)->descriptorType()));
|
||||
}
|
||||
updateData();
|
||||
}
|
||||
this->statusBar()->clearMessage();
|
||||
}
|
||||
|
||||
void MainWindow::updateData()
|
||||
{
|
||||
if(objects_.size())
|
||||
@ -401,7 +447,7 @@ void MainWindow::update(const cv::Mat & image)
|
||||
// PROCESS RESULTS
|
||||
if(this->isVisible())
|
||||
{
|
||||
ui_->imageView_source->setData(keypoints, cv::Mat(), &iplImage);
|
||||
ui_->imageView_source->setData(keypoints, cv::Mat(), &iplImage, Settings::currentDetectorType(), Settings::currentDescriptorType());
|
||||
}
|
||||
int j=0;
|
||||
std::vector<cv::Point2f> mpts_1, mpts_2;
|
||||
@ -564,7 +610,7 @@ void MainWindow::update(const cv::Mat & image)
|
||||
}
|
||||
else if(this->isVisible())
|
||||
{
|
||||
ui_->imageView_source->setData(keypoints, cv::Mat(), &iplImage);
|
||||
ui_->imageView_source->setData(keypoints, cv::Mat(), &iplImage, Settings::currentDetectorType(), Settings::currentDescriptorType());
|
||||
}
|
||||
|
||||
if(this->isVisible())
|
||||
@ -602,3 +648,11 @@ void MainWindow::update(const cv::Mat & image)
|
||||
refreshStartTime_.start();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::notifyParametersChanged()
|
||||
{
|
||||
if(objects_.size())
|
||||
{
|
||||
this->statusBar()->showMessage(tr("A parameter has changed... \"Update objects\" may be required."));
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,6 +47,8 @@ private slots:
|
||||
void addObject();
|
||||
void removeObject(ObjWidget * object);
|
||||
void update(const cv::Mat & image);
|
||||
void updateObjects();
|
||||
void notifyParametersChanged();
|
||||
|
||||
signals:
|
||||
void objectsFound(const QMap<int, QPair<QRect, QTransform> > &);
|
||||
|
||||
@ -49,13 +49,13 @@ ObjWidget::ObjWidget(int id,
|
||||
iplImage_(0),
|
||||
graphicsView_(0),
|
||||
id_(id),
|
||||
detectorType_(detectorType),
|
||||
descriptorType_(descriptorType),
|
||||
detectorType_("NA"),
|
||||
descriptorType_("NA"),
|
||||
graphicsViewInitialized_(false),
|
||||
alpha_(50)
|
||||
{
|
||||
setupUi();
|
||||
this->setData(keypoints, descriptors, iplImage);
|
||||
this->setData(keypoints, descriptors, iplImage, detectorType, descriptorType);
|
||||
}
|
||||
ObjWidget::~ObjWidget()
|
||||
{
|
||||
@ -189,6 +189,20 @@ void ObjWidget::setSizedFeatures(bool on)
|
||||
}
|
||||
}
|
||||
|
||||
void ObjWidget::setMirrorView(bool on)
|
||||
{
|
||||
_mirrorView->setChecked(on);
|
||||
graphicsView_->setTransform(QTransform().scale(this->isMirrorView()?-1.0:1.0, 1.0));
|
||||
if(_graphicsViewMode->isChecked() && _autoScale->isChecked())
|
||||
{
|
||||
graphicsView_->fitInView(graphicsView_->sceneRect(), Qt::KeepAspectRatio);
|
||||
}
|
||||
else if(!_graphicsViewMode->isChecked())
|
||||
{
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void ObjWidget::setAlpha(int alpha)
|
||||
{
|
||||
if(alpha>=0 && alpha<=255)
|
||||
@ -218,7 +232,11 @@ void ObjWidget::setAlpha(int alpha)
|
||||
}
|
||||
}
|
||||
|
||||
void ObjWidget::setData(const std::vector<cv::KeyPoint> & keypoints, const cv::Mat & descriptors, const IplImage * image)
|
||||
void ObjWidget::setData(const std::vector<cv::KeyPoint> & keypoints,
|
||||
const cv::Mat & descriptors,
|
||||
const IplImage * image,
|
||||
const QString & detectorType,
|
||||
const QString & descriptorType)
|
||||
{
|
||||
keypoints_ = keypoints;
|
||||
descriptors_ = descriptors;
|
||||
@ -227,6 +245,8 @@ void ObjWidget::setData(const std::vector<cv::KeyPoint> & keypoints, const cv::M
|
||||
rectItems_.clear();
|
||||
graphicsView_->scene()->clear();
|
||||
graphicsViewInitialized_ = false;
|
||||
detectorType_ = detectorType;
|
||||
descriptorType_ = descriptorType;
|
||||
if(iplImage_)
|
||||
{
|
||||
cvReleaseImage(&iplImage_);
|
||||
@ -314,6 +334,11 @@ bool ObjWidget::isFeaturesShown() const
|
||||
return _showFeatures->isChecked();
|
||||
}
|
||||
|
||||
bool ObjWidget::isSizedFeatures() const
|
||||
{
|
||||
return _sizedFeatures->isChecked();
|
||||
}
|
||||
|
||||
bool ObjWidget::isMirrorView() const
|
||||
{
|
||||
return _mirrorView->isChecked();
|
||||
@ -354,7 +379,8 @@ void ObjWidget::load(QDataStream & streamPtr)
|
||||
cv::Mat descriptors;
|
||||
|
||||
int nKpts;
|
||||
streamPtr >> id_ >> detectorType_ >> descriptorType_ >> nKpts;
|
||||
QString detectorType, descriptorType;
|
||||
streamPtr >> id_ >> detectorType >> descriptorType >> nKpts;
|
||||
for(int i=0;i<nKpts;++i)
|
||||
{
|
||||
cv::KeyPoint kpt;
|
||||
@ -376,10 +402,50 @@ void ObjWidget::load(QDataStream & streamPtr)
|
||||
streamPtr >> data;
|
||||
descriptors = cv::Mat(rows, cols, type, data.data()).clone();
|
||||
streamPtr >> image_;
|
||||
this->setData(kpts, descriptors, 0);
|
||||
this->setData(kpts, descriptors, 0, detectorType, descriptorType);
|
||||
//this->setMinimumSize(image_.size());
|
||||
}
|
||||
|
||||
void ObjWidget::computeScaleOffsets(float & scale, float & offsetX, float & offsetY)
|
||||
{
|
||||
scale = 1.0f;
|
||||
offsetX = 0.0f;
|
||||
offsetY = 0.0f;
|
||||
|
||||
if(!image_.isNull())
|
||||
{
|
||||
float w = image_.width();
|
||||
float h = image_.height();
|
||||
float widthRatio = float(this->rect().width()) / w;
|
||||
float heightRatio = float(this->rect().height()) / h;
|
||||
|
||||
//printf("w=%f, h=%f, wR=%f, hR=%f, sW=%d, sH=%d\n", w, h, widthRatio, heightRatio, this->rect().width(), this->rect().height());
|
||||
if(widthRatio < heightRatio)
|
||||
{
|
||||
scale = widthRatio;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = heightRatio;
|
||||
}
|
||||
|
||||
//printf("ratio=%f\n",ratio);
|
||||
|
||||
w *= scale;
|
||||
h *= scale;
|
||||
|
||||
if(w < this->rect().width())
|
||||
{
|
||||
offsetX = (this->rect().width() - w)/2.0f;
|
||||
}
|
||||
if(h < this->rect().height())
|
||||
{
|
||||
offsetY = (this->rect().height() - h)/2.0f;
|
||||
}
|
||||
//printf("offsetX=%f, offsetY=%f\n",offsetX, offsetY);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjWidget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
if(_graphicsViewMode->isChecked())
|
||||
@ -391,42 +457,13 @@ void ObjWidget::paintEvent(QPaintEvent *event)
|
||||
if(!image_.isNull())
|
||||
{
|
||||
//Scale
|
||||
float w = image_.width();
|
||||
float h = image_.height();
|
||||
float widthRatio = float(this->rect().width()) / w;
|
||||
float heightRatio = float(this->rect().height()) / h;
|
||||
float ratio = 1.0f;
|
||||
//printf("w=%f, h=%f, wR=%f, hR=%f, sW=%d, sH=%d\n", w, h, widthRatio, heightRatio, this->rect().width(), this->rect().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;
|
||||
}
|
||||
float ratio, offsetX, offsetY;
|
||||
this->computeScaleOffsets(ratio, offsetX, offsetY);
|
||||
QPainter painter(this);
|
||||
|
||||
|
||||
if(_mirrorView->isChecked())
|
||||
{
|
||||
painter.translate(offsetX+w, offsetY);
|
||||
painter.translate(offsetX+image_.width()*ratio, offsetY);
|
||||
painter.scale(-ratio, ratio);
|
||||
}
|
||||
else
|
||||
@ -445,7 +482,6 @@ void ObjWidget::paintEvent(QPaintEvent *event)
|
||||
drawKeypoints(&painter);
|
||||
}
|
||||
|
||||
|
||||
for(int i=0; i<rectItems_.size(); ++i)
|
||||
{
|
||||
painter.save();
|
||||
@ -455,6 +491,28 @@ void ObjWidget::paintEvent(QPaintEvent *event)
|
||||
painter.restore();
|
||||
}
|
||||
|
||||
if(mouseCurrentPos_ != mousePressedPos_)
|
||||
{
|
||||
painter.save();
|
||||
int left, top, right, bottom;
|
||||
left = mousePressedPos_.x() < mouseCurrentPos_.x() ? mousePressedPos_.x():mouseCurrentPos_.x();
|
||||
top = mousePressedPos_.y() < mouseCurrentPos_.y() ? mousePressedPos_.y():mouseCurrentPos_.y();
|
||||
right = mousePressedPos_.x() > mouseCurrentPos_.x() ? mousePressedPos_.x():mouseCurrentPos_.x();
|
||||
bottom = mousePressedPos_.y() > mouseCurrentPos_.y() ? mousePressedPos_.y():mouseCurrentPos_.y();
|
||||
if(_mirrorView->isChecked())
|
||||
{
|
||||
int l = left;
|
||||
left = qAbs(right - image_.width());
|
||||
right = qAbs(l - image_.width());
|
||||
}
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(QBrush(QColor(0,0,0,100)));
|
||||
painter.drawRect(0, 0, image_.width(), top-1);
|
||||
painter.drawRect(0, top, left, bottom-top);
|
||||
painter.drawRect(right, top, image_.width()-right, bottom-top);
|
||||
painter.drawRect(0, bottom, image_.width(), image_.height()-bottom);
|
||||
painter.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -468,6 +526,50 @@ void ObjWidget::resizeEvent(QResizeEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
void ObjWidget::mousePressEvent(QMouseEvent * event)
|
||||
{
|
||||
float scale, offsetX, offsetY;
|
||||
this->computeScaleOffsets(scale, offsetX, offsetY);
|
||||
mousePressedPos_.setX((event->pos().x()-offsetX)/scale);
|
||||
mousePressedPos_.setY((event->pos().y()-offsetY)/scale);
|
||||
mouseCurrentPos_ = mousePressedPos_;
|
||||
this->update();
|
||||
QWidget::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void ObjWidget::mouseMoveEvent(QMouseEvent * event)
|
||||
{
|
||||
float scale, offsetX, offsetY;
|
||||
this->computeScaleOffsets(scale, offsetX, offsetY);
|
||||
mouseCurrentPos_.setX((event->pos().x()-offsetX)/scale);
|
||||
mouseCurrentPos_.setY((event->pos().y()-offsetY)/scale);
|
||||
this->update();
|
||||
QWidget::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void ObjWidget::mouseReleaseEvent(QMouseEvent * event)
|
||||
{
|
||||
if(!image_.isNull())
|
||||
{
|
||||
int left,top,bottom,right;
|
||||
|
||||
left = mousePressedPos_.x() < mouseCurrentPos_.x() ? mousePressedPos_.x():mouseCurrentPos_.x();
|
||||
top = mousePressedPos_.y() < mouseCurrentPos_.y() ? mousePressedPos_.y():mouseCurrentPos_.y();
|
||||
right = mousePressedPos_.x() > mouseCurrentPos_.x() ? mousePressedPos_.x():mouseCurrentPos_.x();
|
||||
bottom = mousePressedPos_.y() > mouseCurrentPos_.y() ? mousePressedPos_.y():mouseCurrentPos_.y();
|
||||
|
||||
if(_mirrorView->isChecked())
|
||||
{
|
||||
int l = left;
|
||||
left = qAbs(right - image_.width());
|
||||
right = qAbs(l - image_.width());
|
||||
}
|
||||
|
||||
emit roiChanged(QRect(left, top, right-left, bottom-top));
|
||||
}
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void ObjWidget::contextMenuEvent(QContextMenuEvent * event)
|
||||
{
|
||||
QAction * action = _menu->exec(event->globalPos());
|
||||
@ -502,15 +604,7 @@ void ObjWidget::contextMenuEvent(QContextMenuEvent * event)
|
||||
}
|
||||
else if(action == _mirrorView)
|
||||
{
|
||||
graphicsView_->setTransform(QTransform().scale(this->isMirrorView()?-1.0:1.0, 1.0));
|
||||
if(_graphicsViewMode->isChecked() && _autoScale->isChecked())
|
||||
{
|
||||
graphicsView_->fitInView(graphicsView_->sceneRect(), Qt::KeepAspectRatio);
|
||||
}
|
||||
else if(!_graphicsViewMode->isChecked())
|
||||
{
|
||||
this->update();
|
||||
}
|
||||
this->setMirrorView(_mirrorView->isChecked());
|
||||
}
|
||||
else if(action == _delete)
|
||||
{
|
||||
|
||||
@ -35,15 +35,19 @@ public:
|
||||
void setId(int id);
|
||||
void setData(const std::vector<cv::KeyPoint> & keypoints,
|
||||
const cv::Mat & descriptors,
|
||||
const IplImage * image);
|
||||
const IplImage * image,
|
||||
const QString & detectorType,
|
||||
const QString & descriptorType);
|
||||
void resetKptsColor();
|
||||
void setKptColor(int index, const QColor & color);
|
||||
void setGraphicsViewMode(bool on);
|
||||
void setAutoScale(bool autoScale);
|
||||
void setSizedFeatures(bool on);
|
||||
void setMirrorView(bool on);
|
||||
void setAlpha(int alpha);
|
||||
void setDeletable(bool deletable);
|
||||
void addRect(QGraphicsRectItem * rect);
|
||||
void clearRoiSelection() {mousePressedPos_ = mouseCurrentPos_ = QPoint();update();}
|
||||
|
||||
const std::vector<cv::KeyPoint> & keypoints() const {return keypoints_;}
|
||||
const cv::Mat & descriptors() const {return descriptors_;}
|
||||
@ -53,6 +57,7 @@ public:
|
||||
QColor defaultColor() const;
|
||||
bool isImageShown() const;
|
||||
bool isFeaturesShown() const;
|
||||
bool isSizedFeatures() const;
|
||||
bool isMirrorView() const;
|
||||
//QGraphicsScene * scene() const;
|
||||
std::vector<cv::KeyPoint> selectedKeypoints() const;
|
||||
@ -69,16 +74,21 @@ protected:
|
||||
virtual void paintEvent(QPaintEvent *event);
|
||||
virtual void contextMenuEvent(QContextMenuEvent * event);
|
||||
virtual void resizeEvent(QResizeEvent* event);
|
||||
virtual void mousePressEvent(QMouseEvent * event);
|
||||
virtual void mouseMoveEvent(QMouseEvent * event);
|
||||
virtual void mouseReleaseEvent(QMouseEvent * event);
|
||||
|
||||
signals:
|
||||
void removalTriggered(ObjWidget *);
|
||||
void selectionChanged();
|
||||
void roiChanged(const QRect &);
|
||||
|
||||
private:
|
||||
void setupGraphicsView();
|
||||
void drawKeypoints(QPainter * painter = 0);
|
||||
void setupUi();
|
||||
void updateItemsShown();
|
||||
void computeScaleOffsets(float & scale, float & offsetX, float & offsetY);
|
||||
|
||||
private:
|
||||
std::vector<cv::KeyPoint> keypoints_;
|
||||
@ -107,6 +117,10 @@ private:
|
||||
QAction * _autoScale;
|
||||
QAction * _sizedFeatures;
|
||||
QAction * _setAlpha;
|
||||
|
||||
// selection stuff
|
||||
QPoint mousePressedPos_;
|
||||
QPoint mouseCurrentPos_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -269,6 +269,7 @@ void ParametersToolBox::changeParameter()
|
||||
{
|
||||
Settings::setParameter(sender()->objectName(), spinBox->value());
|
||||
}
|
||||
emit parametersChanged();
|
||||
}
|
||||
}
|
||||
void ParametersToolBox::changeParameter(const int & value)
|
||||
@ -291,5 +292,6 @@ void ParametersToolBox::changeParameter(const int & value)
|
||||
{
|
||||
Settings::setParameter(sender()->objectName(), value==Qt::Checked?true:false);
|
||||
}
|
||||
emit parametersChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,6 +29,9 @@ private:
|
||||
void addParameter(QVBoxLayout * layout, const QString & key, const bool & value);
|
||||
void addParameter(QVBoxLayout * layout, const QString & name, QWidget * widget);
|
||||
|
||||
signals:
|
||||
void parametersChanged();
|
||||
|
||||
private slots:
|
||||
void changeParameter();
|
||||
void changeParameter(const QString & value);
|
||||
|
||||
@ -15,11 +15,29 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_instruction">
|
||||
<property name="text">
|
||||
<string>(Instructions)</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,0">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_instruction">
|
||||
<property name="text">
|
||||
<string>(Instructions)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_selection">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Select region</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Select keypoints</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
|
||||
@ -379,7 +379,7 @@
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>128</height>
|
||||
<height>162</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -407,7 +407,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>274</width>
|
||||
<height>459</height>
|
||||
<height>425</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_objects">
|
||||
@ -431,6 +431,13 @@
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_updateObjects">
|
||||
<property name="text">
|
||||
<string>Update objects</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user