Added wordID in shown keypoint info, improved fixed vocabulary behavior

This commit is contained in:
matlabbe
2015-06-24 18:07:52 -04:00
parent b4e97e450d
commit f1bba5b8fb
12 changed files with 288 additions and 148 deletions
+5 -3
View File
@@ -316,7 +316,8 @@ void AddObjectDialog::setState(int state)
selectedKeypoints.clear();
detector_->detect(imgRoi, selectedKeypoints);
}
ui_->objectView->setData(selectedKeypoints, cvtCvMat2QImage(imgRoi.clone()));
ui_->objectView->updateImage(cvtCvMat2QImage(imgRoi.clone()));
ui_->objectView->updateData(selectedKeypoints, QMultiMap<int,int>());
ui_->objectView->setMinimumSize(roi_.width, roi_.height);
ui_->objectView->update();
ui_->pushButton_next->setEnabled(true);
@@ -359,7 +360,7 @@ void AddObjectDialog::setState(int state)
}
objSignature_ = new ObjSignature(0, imgRoi.clone(), "");
objSignature_->setData(keypoints, descriptors);
objWidget_ = new ObjWidget(0, keypoints, cvtCvMat2QImage(imgRoi.clone()));
objWidget_ = new ObjWidget(0, keypoints, QMultiMap<int,int>(), cvtCvMat2QImage(imgRoi.clone()));
this->accept();
}
@@ -385,7 +386,8 @@ void AddObjectDialog::update(const cv::Mat & image)
std::vector<cv::KeyPoint> keypoints;
detector_->detect(cameraImage_, keypoints);
ui_->cameraView->setData(keypoints, cvtCvMat2QImage(cameraImage_));
ui_->cameraView->updateImage(cvtCvMat2QImage(cameraImage_));
ui_->cameraView->updateData(keypoints, QMultiMap<int,int>());
ui_->cameraView->update();
}
else
+135 -83
View File
@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "find_object/FindObject.h"
#include "find_object/Settings.h"
#include "find_object/utilite/ULogger.h"
#include "utilite/UConversion.h"
#include "ObjSignature.h"
#include "utilite/UDirectory.h"
@@ -144,12 +145,12 @@ bool FindObject::saveSession(const QString & path)
int FindObject::loadObjects(const QString & dirPath, bool recursive)
{
int loadedObjects = 0;
QString formats = Settings::getGeneral_imageFormats().remove('*').remove('.');
QStringList paths;
paths.append(dirPath);
QList<int> idsLoaded;
while(paths.size())
{
QString currentDir = paths.front();
@@ -159,9 +160,10 @@ int FindObject::loadObjects(const QString & dirPath, bool recursive)
const std::list<std::string> & names = dir.getFileNames(); // sorted in natural order
for(std::list<std::string>::const_iterator iter=names.begin(); iter!=names.end(); ++iter)
{
if(this->addObject((currentDir.toStdString()+dir.separator()+*iter).c_str()))
const ObjSignature * s = this->addObject((currentDir.toStdString()+dir.separator()+*iter).c_str());
if(s)
{
++loadedObjects;
idsLoaded.push_back(s->id());
}
}
}
@@ -179,13 +181,13 @@ int FindObject::loadObjects(const QString & dirPath, bool recursive)
}
}
if(loadedObjects)
if(idsLoaded.size())
{
this->updateObjects();
this->updateVocabulary();
this->updateObjects(idsLoaded);
this->updateVocabulary(idsLoaded);
}
return loadedObjects;
return idsLoaded.size();
}
const ObjSignature * FindObject::addObject(const QString & filePath)
@@ -279,7 +281,7 @@ void FindObject::addObjectAndUpdate(const cv::Mat & image, int id, const QString
QList<int> ids;
ids.push_back(s->id());
updateObjects(ids);
updateVocabulary();
updateVocabulary(ids);
}
}
@@ -739,14 +741,38 @@ void FindObject::clearVocabulary()
vocabulary_->clear();
}
void FindObject::updateVocabulary()
void FindObject::updateVocabulary(const QList<int> & ids)
{
clearVocabulary();
int count = 0;
int dim = -1;
int type = -1;
QList<ObjSignature*> objectsList;
if(ids.size())
{
for(int i=0; i<ids.size(); ++i)
{
if(objects_.contains(ids[i]))
{
objectsList.push_back(objects_[ids[i]]);
}
else
{
UERROR("Not found object %d!", ids[i]);
}
}
if(vocabulary_->size())
{
dim = vocabulary_->dim();
type = vocabulary_->type();
}
}
else
{
clearVocabulary();
objectsList = objects_.values();
}
// Get the total size and verify descriptors
QList<ObjSignature*> objectsList = objects_.values();
for(int i=0; i<objectsList.size(); ++i)
{
if(!objectsList.at(i)->descriptors().empty())
@@ -774,94 +800,119 @@ void FindObject::updateVocabulary()
{
UINFO("Updating global descriptors matrix: Objects=%d, total descriptors=%d, dim=%d, type=%d",
(int)objects_.size(), count, dim, type);
if(Settings::getGeneral_invertedSearch() || Settings::getGeneral_threads() == 1)
if(!Settings::getGeneral_invertedSearch())
{
// If only one thread, put all descriptors in the same cv::Mat
objectsDescriptors_.insert(0, cv::Mat(count, dim, type));
int row = 0;
for(int i=0; i<objectsList.size(); ++i)
if(Settings::getGeneral_threads() == 1)
{
if(objectsList.at(i)->descriptors().rows)
// If only one thread, put all descriptors in the same cv::Mat
int row = 0;
bool vocabularyEmpty = objectsDescriptors_.size() == 0;
if(vocabularyEmpty)
{
cv::Mat dest(objectsDescriptors_.begin().value(), cv::Range(row, row+objectsList.at(i)->descriptors().rows));
objectsList.at(i)->descriptors().copyTo(dest);
row += objectsList.at(i)->descriptors().rows;
// dataRange contains the upper_bound for each
// object (the last descriptors position in the
// global object descriptors matrix)
UASSERT(objectsDescriptors_.size() == 0);
objectsDescriptors_.insert(0, cv::Mat(count, dim, type));
}
else
{
row = objectsDescriptors_.begin().value().rows;
}
for(int i=0; i<objectsList.size(); ++i)
{
objectsList[i]->setWords(QMultiMap<int,int>());
if(objectsList.at(i)->descriptors().rows)
{
dataRange_.insert(row-1, objectsList.at(i)->id());
if(vocabularyEmpty)
{
cv::Mat dest(objectsDescriptors_.begin().value(), cv::Range(row, row+objectsList.at(i)->descriptors().rows));
objectsList.at(i)->descriptors().copyTo(dest);
}
else
{
UASSERT_MSG(objectsDescriptors_.begin().value().cols == objectsList.at(i)->descriptors().cols,
uFormat("%d vs %d", objectsDescriptors_.begin().value().cols, objectsList.at(i)->descriptors().cols).c_str());
UASSERT(objectsDescriptors_.begin().value().type() == objectsList.at(i)->descriptors().type());
objectsDescriptors_.begin().value().push_back(objectsList.at(i)->descriptors());
}
row += objectsList.at(i)->descriptors().rows;
// dataRange contains the upper_bound for each
// object (the last descriptors position in the
// global object descriptors matrix)
if(objectsList.at(i)->descriptors().rows)
{
dataRange_.insert(row-1, objectsList.at(i)->id());
}
}
}
}
if(Settings::getGeneral_invertedSearch())
else
{
sessionModified_ = true;
QTime time;
time.start();
bool incremental = Settings::getGeneral_vocabularyIncremental() && !Settings::getGeneral_vocabularyFixed();
if(incremental)
{
UINFO("Creating incremental vocabulary...");
}
else if(Settings::getGeneral_vocabularyFixed())
{
UINFO("Updating vocabulary correspondences only (vocabulary is fixed)...");
}
else
{
UINFO("Creating vocabulary...");
}
QTime localTime;
localTime.start();
int updateVocabularyMinWords = Settings::getGeneral_vocabularyUpdateMinWords();
int addedWords = 0;
for(int i=0; i<objectsList.size(); ++i)
{
QMultiMap<int, int> words = vocabulary_->addWords(objectsList[i]->descriptors(), objectsList.at(i)->id());
objectsList[i]->setWords(words);
addedWords += words.uniqueKeys().size();
bool updated = false;
if(incremental && addedWords && addedWords >= updateVocabularyMinWords)
{
vocabulary_->update();
addedWords = 0;
updated = true;
}
UINFO("Object %d, %d words from %d descriptors (%d words, %d ms) %s",
objectsList[i]->id(),
words.uniqueKeys().size(),
objectsList[i]->descriptors().rows,
vocabulary_->size(),
localTime.restart(),
updated?"updated":"");
}
if(addedWords && !Settings::getGeneral_vocabularyFixed())
{
vocabulary_->update();
}
if(incremental)
{
UINFO("Creating incremental vocabulary... done! size=%d (%d ms)", vocabulary_->size(), time.elapsed());
}
else if(Settings::getGeneral_vocabularyFixed())
{
UINFO("Updating vocabulary correspondences only (vocabulary is fixed)... done! size=%d (%d ms)", time.elapsed());
}
else
{
UINFO("Creating vocabulary... done! size=%d (%d ms)", vocabulary_->size(), time.elapsed());
objectsList[i]->setWords(QMultiMap<int,int>());
objectsDescriptors_.insert(objectsList.at(i)->id(), objectsList.at(i)->descriptors());
}
}
}
else
{
// Inverted index on (vocabulary)
sessionModified_ = true;
QTime time;
time.start();
bool incremental = Settings::getGeneral_vocabularyIncremental() && !Settings::getGeneral_vocabularyFixed();
if(incremental)
{
UINFO("Creating incremental vocabulary...");
}
else if(Settings::getGeneral_vocabularyFixed())
{
UINFO("Updating vocabulary correspondences only (vocabulary is fixed)...");
}
else
{
UINFO("Creating vocabulary...");
}
QTime localTime;
localTime.start();
int updateVocabularyMinWords = Settings::getGeneral_vocabularyUpdateMinWords();
int addedWords = 0;
for(int i=0; i<objectsList.size(); ++i)
{
objectsDescriptors_.insert(objectsList.at(i)->id(), objectsList.at(i)->descriptors());
QMultiMap<int, int> words = vocabulary_->addWords(objectsList[i]->descriptors(), objectsList.at(i)->id());
objectsList[i]->setWords(words);
addedWords += words.uniqueKeys().size();
bool updated = false;
if(incremental && addedWords && addedWords >= updateVocabularyMinWords)
{
vocabulary_->update();
addedWords = 0;
updated = true;
}
UINFO("Object %d, %d words from %d descriptors (%d words, %d ms) %s",
objectsList[i]->id(),
words.uniqueKeys().size(),
objectsList[i]->descriptors().rows,
vocabulary_->size(),
localTime.restart(),
updated?"updated":"");
}
if(addedWords && !Settings::getGeneral_vocabularyFixed())
{
vocabulary_->update();
}
if(incremental)
{
UINFO("Creating incremental vocabulary... done! size=%d (%d ms)", vocabulary_->size(), time.elapsed());
}
else if(Settings::getGeneral_vocabularyFixed())
{
UINFO("Updating vocabulary correspondences only (vocabulary is fixed)... done! size=%d (%d ms)", vocabulary_->size(), time.elapsed());
}
else
{
UINFO("Creating vocabulary... done! size=%d (%d ms)", vocabulary_->size(), time.elapsed());
}
}
}
@@ -1202,6 +1253,7 @@ bool FindObject::detect(const cv::Mat & image, find_object::DetectionInfo & info
words = vocabulary_->addWords(info.sceneDescriptors_, -1);
vocabulary_->update();
info.timeStamps_.insert(DetectionInfo::kTimeIndexing, time.restart());
info.sceneWords_ = words;
}
for(QMap<int, ObjSignature*>::iterator iter=objects_.begin(); iter!=objects_.end(); ++iter)
@@ -1274,9 +1326,10 @@ bool FindObject::detect(const cv::Mat & image, find_object::DetectionInfo & info
if(matched)
{
int wordId = results.at<int>(i,0);
if(Settings::getGeneral_invertedSearch())
{
int wordId = results.at<int>(i,0);
info.sceneWords_.insertMulti(wordId, i);
QList<int> objIds = vocabulary_->wordToObjects().values(wordId);
for(int j=0; j<objIds.size(); ++j)
{
@@ -1294,7 +1347,6 @@ bool FindObject::detect(const cv::Mat & image, find_object::DetectionInfo & info
int fisrtObjectDescriptorIndex = (iter == dataRange_.begin())?0:(--iter).key()+1;
int objectDescriptorIndex = i - fisrtObjectDescriptorIndex;
int wordId = results.at<int>(i,0);
if(words.count(wordId) == 1)
{
info.matches_.find(objectId).value().insert(objectDescriptorIndex, words.value(wordId));
+13 -4
View File
@@ -33,11 +33,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace find_object {
KeypointItem::KeypointItem(int id, qreal x, qreal y, int r, const QString & info, const QColor & color, QGraphicsItem * parent) :
KeypointItem::KeypointItem(int id, qreal x, qreal y, int r, const cv::KeyPoint & kpt, int wordID, const QColor & color, QGraphicsItem * parent) :
QGraphicsEllipseItem(x, y, r, r, parent),
info_(info),
placeHolder_(0),
id_(id)
id_(id),
kpt_(kpt),
wordID_(wordID)
{
this->setPen(QPen(color));
this->setBrush(QBrush(color));
@@ -70,13 +71,21 @@ void KeypointItem::showDescription()
{
if(!placeHolder_)
{
QString info = QString( "Keypoint = %1\n"
"Word = %2\n"
"Response = %3\n"
"Angle = %4\n"
"X = %5\n"
"Y = %6\n"
"Size = %7").arg(id_).arg(wordID_).arg(kpt_.response).arg(kpt_.angle).arg(kpt_.pt.x).arg(kpt_.pt.y).arg(kpt_.size);
placeHolder_ = new QGraphicsRectItem();
placeHolder_->setVisible(false);
this->scene()->addItem(placeHolder_);
placeHolder_->setBrush(QBrush(QColor ( 0, 0, 0, 170 ))); // Black transparent background
QGraphicsTextItem * text = new QGraphicsTextItem(placeHolder_);
text->setDefaultTextColor(this->pen().color().rgb());
text->setPlainText(info_);
text->setPlainText(info);
placeHolder_->setRect(text->boundingRect());
}
+5 -2
View File
@@ -32,16 +32,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QtGui/QGraphicsTextItem>
#include <QtGui/QPen>
#include <QtGui/QBrush>
#include <opencv2/features2d/features2d.hpp>
namespace find_object {
class KeypointItem : public QGraphicsEllipseItem
{
public:
KeypointItem(int id, qreal x, qreal y, int r, const QString & info, const QColor & color = Qt::green, QGraphicsItem * parent = 0);
KeypointItem(int id, qreal x, qreal y, int r, const cv::KeyPoint & kpt, int wordID = -1, const QColor & color = Qt::green, QGraphicsItem * parent = 0);
virtual ~KeypointItem();
void setColor(const QColor & color);
void setWordID(int id) {wordID_ = id;}
int id() const {return id_;}
protected:
@@ -55,9 +57,10 @@ private:
void hideDescription();
private:
QString info_;
QGraphicsRectItem * placeHolder_;
int id_;
cv::KeyPoint kpt_;
int wordID_;
};
} // namespace find_object
+69 -27
View File
@@ -183,7 +183,7 @@ MainWindow::MainWindow(FindObject * findObject, Camera * camera, QWidget * paren
//buttons
connect(ui_->pushButton_restoreDefaults, SIGNAL(clicked()), ui_->toolBox, SLOT(resetCurrentPage()));
connect(ui_->pushButton_updateObjects, SIGNAL(clicked()), this, SLOT(updateObjects()));
connect(ui_->pushButton_updateObjects, SIGNAL(clicked()), this, SLOT(updateObjects(const QList<int> &)));
connect(ui_->horizontalSlider_objectsSize, SIGNAL(valueChanged(int)), this, SLOT(updateObjectsSize()));
ui_->actionStop_camera->setEnabled(false);
@@ -247,7 +247,7 @@ MainWindow::MainWindow(FindObject * findObject, Camera * camera, QWidget * paren
iter!=findObject_->objects().constEnd();
++iter)
{
ObjWidget * obj = new ObjWidget(iter.key(), iter.value()->keypoints(), cvtCvMat2QImage(iter.value()->image()));
ObjWidget * obj = new ObjWidget(iter.key(), iter.value()->keypoints(), iter.value()->words(), cvtCvMat2QImage(iter.value()->image()));
objWidgets_.insert(obj->id(), obj);
this->showObject(obj);
}
@@ -366,7 +366,7 @@ void MainWindow::loadSession()
{
if(iter.value())
{
ObjWidget * obj = new ObjWidget(iter.key(), iter.value()->keypoints(), cvtCvMat2QImage(iter.value()->image()));
ObjWidget * obj = new ObjWidget(iter.key(), iter.value()->keypoints(), iter.value()->words(), cvtCvMat2QImage(iter.value()->image()));
objWidgets_.insert(obj->id(), obj);
ui_->actionSave_objects->setEnabled(true);
ui_->actionSave_session->setEnabled(true);
@@ -714,7 +714,9 @@ void MainWindow::addObjectFromScene()
ui_->actionSave_objects->setEnabled(true);
ui_->actionSave_session->setEnabled(true);
showObject(obj);
updateVocabulary();
QList<int> ids;
ids.push_back(obj->id());
updateVocabulary(ids);
objectsModified_ = true;
}
if(resumeCamera || sceneImage_.empty())
@@ -764,7 +766,7 @@ int MainWindow::addObjectFromFile(const QString & filePath)
const ObjSignature * s = findObject_->addObject(filePath);
if(s)
{
ObjWidget * obj = new ObjWidget(s->id(), std::vector<cv::KeyPoint>(), cvtCvMat2QImage(s->image()));
ObjWidget * obj = new ObjWidget(s->id(), std::vector<cv::KeyPoint>(), QMultiMap<int,int>(), cvtCvMat2QImage(s->image()));
objWidgets_.insert(obj->id(), obj);
ui_->actionSave_objects->setEnabled(true);
ui_->actionSave_session->setEnabled(true);
@@ -787,7 +789,7 @@ void MainWindow::addObjectFromTcp(const cv::Mat & image, int id, const QString &
const ObjSignature * s = findObject_->addObject(image, id, filePath);
if(s)
{
ObjWidget * obj = new ObjWidget(s->id(), std::vector<cv::KeyPoint>(), cvtCvMat2QImage(s->image()));
ObjWidget * obj = new ObjWidget(s->id(), std::vector<cv::KeyPoint>(), QMultiMap<int,int>(), cvtCvMat2QImage(s->image()));
objWidgets_.insert(obj->id(), obj);
ui_->actionSave_objects->setEnabled(true);
ui_->actionSave_session->setEnabled(true);
@@ -977,21 +979,24 @@ void MainWindow::showObject(ObjWidget * obj)
void MainWindow::updateObjects(const QList<int> & ids)
{
if(ids.size())
if(objWidgets_.size())
{
this->statusBar()->showMessage(tr("Updating %1 objects...").arg(ids.size()));
this->statusBar()->showMessage(tr("Updating %1 objects...").arg(ids.size()==0?objWidgets_.size():ids.size()));
findObject_->updateObjects(ids);
updateVocabulary();
QList<int> idsTmp = ids;
if(idsTmp.size() == 0)
{
idsTmp = objWidgets_.keys();
}
QList<ObjSignature*> signatures = findObject_->objects().values();
for(int i=0; i<signatures.size(); ++i)
{
if(ids.contains(signatures[i]->id()))
if(idsTmp.contains(signatures[i]->id()))
{
QImage qtImage = cvtCvMat2QImage(signatures[i]->image());
objWidgets_.value(signatures[i]->id())->setData(signatures[i]->keypoints(), qtImage, signatures[i]->rect());
objWidgets_.value(signatures[i]->id())->updateData(signatures[i]->keypoints());
//update object labels
QLabel * title = qFindChild<QLabel*>(this, QString("%1title").arg(signatures[i]->id()));
@@ -999,6 +1004,8 @@ void MainWindow::updateObjects(const QList<int> & ids)
}
}
updateVocabulary(ids);
if(!camera_->isRunning() && !sceneImage_.empty())
{
this->update(sceneImage_);
@@ -1007,23 +1014,34 @@ void MainWindow::updateObjects(const QList<int> & ids)
}
}
void MainWindow::updateObjects()
{
updateObjects(objWidgets_.keys());
}
void MainWindow::updateVocabulary()
void MainWindow::updateVocabulary(const QList<int> & ids)
{
this->statusBar()->showMessage(tr("Updating vocabulary..."));
QTime time;
time.start();
findObject_->updateVocabulary();
findObject_->updateVocabulary(ids);
if(findObject_->vocabulary()->size())
QList<int> idsTmp = ids;
if(idsTmp.size() == 0)
{
ui_->label_timeIndexing->setNum(time.elapsed());
ui_->label_vocabularySize->setNum(findObject_->vocabulary()->size());
idsTmp = objWidgets_.keys();
}
QList<ObjSignature*> signatures = findObject_->objects().values();
for(int i=0; i<signatures.size(); ++i)
{
if(idsTmp.contains(signatures[i]->id()))
{
objWidgets_.value(signatures[i]->id())->updateWords(signatures[i]->words());
}
}
ui_->label_timeIndexing->setNum(time.elapsed());
ui_->label_vocabularySize->setNum(findObject_->vocabulary()->size());
if(ids.size() && findObject_->vocabulary()->size() == 0 && Settings::getGeneral_vocabularyFixed() && Settings::getGeneral_invertedSearch())
{
QMessageBox::warning(this, tr("Vocabulary update"), tr("\"General/VocabularyFixed=true\" and the "
"vocabulary is empty. New features cannot be matched to any words in the vocabulary."));
}
lastObjectsUpdateParameters_ = Settings::getParameters();
this->statusBar()->clearMessage();
@@ -1172,6 +1190,10 @@ void MainWindow::update(const cv::Mat & image)
for(QMap<int, ObjWidget*>::iterator iter=objWidgets_.begin(); iter!=objWidgets_.end(); ++iter)
{
iter.value()->resetKptsColor();
if(!Settings::getGeneral_invertedSearch())
{
iter.value()->resetKptsWordID();
}
}
QTime guiRefreshTime;
@@ -1184,7 +1206,8 @@ void MainWindow::update(const cv::Mat & image)
ui_->label_timeSkewAffine->setNum(info.timeStamps_.value(DetectionInfo::kTimeSkewAffine, 0));
ui_->label_timeExtraction->setNum(info.timeStamps_.value(DetectionInfo::kTimeDescriptorExtraction, 0));
ui_->label_timeSubPix->setNum(info.timeStamps_.value(DetectionInfo::kTimeSubPixelRefining, 0));
ui_->imageView_source->setData(info.sceneKeypoints_, cvtCvMat2QImage(sceneImage_));
ui_->imageView_source->updateImage(cvtCvMat2QImage(sceneImage_));
ui_->imageView_source->updateData(info.sceneKeypoints_, info.sceneWords_);
if(!findObject_->vocabulary()->size())
{
ui_->label_timeIndexing->setNum(info.timeStamps_.value(DetectionInfo::kTimeIndexing, 0));
@@ -1221,6 +1244,10 @@ void MainWindow::update(const cv::Mat & image)
{
obj->setKptColor(iter.key(), obj->color());
ui_->imageView_source->setKptColor(iter.value(), obj->color());
if(!Settings::getGeneral_invertedSearch())
{
obj->setKptWordID(iter.key(), ui_->imageView_source->words().value(iter.value(), -1));
}
}
}
else if(!info.objDetected_.contains(id))
@@ -1263,6 +1290,8 @@ void MainWindow::update(const cv::Mat & image)
}
// Add homography rectangles when homographies are computed
int maxHomographyScoreId = -1;
int maxHomographyScore = 0;
QMultiMap<int, QMultiMap<int,int> >::const_iterator inliersIter = info.objDetectedInliers_.constBegin();
QMultiMap<int, QMultiMap<int,int> >::const_iterator outliersIter = info.objDetectedOutliers_.constBegin();
for(QMultiMap<int,QTransform>::iterator iter = info.objDetected_.begin();
@@ -1270,6 +1299,13 @@ void MainWindow::update(const cv::Mat & image)
++iter, ++inliersIter, ++outliersIter)
{
int id = iter.key();
if(maxHomographyScoreId == -1 || maxHomographyScore < inliersIter.value().size())
{
maxHomographyScoreId = id;
maxHomographyScore = inliersIter.value().size();
}
ObjWidget * obj = objWidgets_.value(id);
UASSERT(obj != 0);
@@ -1294,6 +1330,10 @@ void MainWindow::update(const cv::Mat & image)
{
obj->setKptColor(iter.key(), obj->color());
ui_->imageView_source->setKptColor(iter.value(), obj->color());
if(!Settings::getGeneral_invertedSearch())
{
obj->setKptWordID(iter.key(), ui_->imageView_source->words().value(iter.value(), -1));
}
}
QLabel * label = ui_->dockWidget_objects->findChild<QLabel*>(QString("%1detection").arg(id));
@@ -1339,9 +1379,9 @@ void MainWindow::update(const cv::Mat & image)
ui_->label_maxMatchedDistance->setNum(info.maxMatchedDistance_);
//Scroll objects slider to the best score
if(maxScoreId>=0 && Settings::getGeneral_autoScroll())
if((maxScoreId>=0 || maxHomographyScoreId>=0) && Settings::getGeneral_autoScroll())
{
QLabel * label = ui_->dockWidget_objects->findChild<QLabel*>(QString("%1title").arg(maxScoreId));
QLabel * label = ui_->dockWidget_objects->findChild<QLabel*>(QString("%1title").arg(maxHomographyScoreId>=0?maxHomographyScoreId:maxScoreId));
if(label)
{
ui_->objects_area->verticalScrollBar()->setValue(label->pos().y());
@@ -1385,7 +1425,8 @@ void MainWindow::update(const cv::Mat & image)
ui_->label_timeSkewAffine->setNum(info.timeStamps_.value(DetectionInfo::kTimeSkewAffine, 0));
ui_->label_timeExtraction->setNum(info.timeStamps_.value(DetectionInfo::kTimeDescriptorExtraction, 0));
ui_->label_timeSubPix->setNum(info.timeStamps_.value(DetectionInfo::kTimeSubPixelRefining, 0));
ui_->imageView_source->setData(info.sceneKeypoints_, cvtCvMat2QImage(sceneImage_));
ui_->imageView_source->updateImage(cvtCvMat2QImage(sceneImage_));
ui_->imageView_source->updateData(info.sceneKeypoints_, info.sceneWords_);
}
@@ -1454,6 +1495,7 @@ void MainWindow::notifyParametersChanged(const QStringList & paramChanged)
else if( (iter->contains("NearestNeighbor") && Settings::getGeneral_invertedSearch()) ||
iter->compare(Settings::kGeneral_invertedSearch()) == 0 ||
(iter->compare(Settings::kGeneral_vocabularyIncremental()) == 0 && Settings::getGeneral_invertedSearch()) ||
(iter->compare(Settings::kGeneral_vocabularyFixed()) == 0 && Settings::getGeneral_invertedSearch()) ||
(iter->compare(Settings::kGeneral_threads()) == 0 && !Settings::getGeneral_invertedSearch()) )
{
nearestNeighborParamsChanged = true;
@@ -1478,7 +1520,7 @@ void MainWindow::notifyParametersChanged(const QStringList & paramChanged)
{
if(detectorDescriptorParamsChanged)
{
this->updateObjects(objWidgets_.keys());
this->updateObjects();
}
else if(nearestNeighborParamsChanged)
{
+44 -18
View File
@@ -65,7 +65,7 @@ ObjWidget::ObjWidget(QWidget * parent) :
{
setupUi();
}
ObjWidget::ObjWidget(int id, const std::vector<cv::KeyPoint> & keypoints, const QImage & image, QWidget * parent) :
ObjWidget::ObjWidget(int id, const std::vector<cv::KeyPoint> & keypoints, const QMultiMap<int,int> & words, const QImage & image, QWidget * parent) :
QWidget(parent),
id_(id),
graphicsView_(0),
@@ -74,7 +74,8 @@ ObjWidget::ObjWidget(int id, const std::vector<cv::KeyPoint> & keypoints, const
color_(QColor((Qt::GlobalColor)((id % 11 + 7)==Qt::yellow?Qt::gray:(id % 11 + 7))))
{
setupUi();
this->setData(keypoints, image, image.rect());
this->updateImage(image);
this->updateData(keypoints, words);
}
ObjWidget::~ObjWidget()
{
@@ -264,29 +265,42 @@ void ObjWidget::setTextLabel(const QString & text)
label_->setText(text);
}
void ObjWidget::setData(const std::vector<cv::KeyPoint> & keypoints, const QImage & image, const QRect & rect)
void ObjWidget::updateImage(const QImage & image)
{
pixmap_ = QPixmap::fromImage(image);
rect_ = pixmap_.rect();
label_->setVisible(image.isNull());
}
void ObjWidget::updateData(const std::vector<cv::KeyPoint> & keypoints, const QMultiMap<int, int> & words)
{
keypoints_ = keypoints;
kptColors_ = QVector<QColor>((int)keypoints.size(), defaultColor());
keypointItems_.clear();
rectItems_.clear();
this->updateWords(words);
graphicsView_->scene()->clear();
graphicsViewInitialized_ = false;
mouseCurrentPos_ = mousePressedPos_; // this will reset roi selection
pixmap_ = QPixmap::fromImage(image);
rect_ = rect;
if(rect_.isNull())
{
rect_ = pixmap_.rect();
}
//this->setMinimumSize(image_.size());
if(graphicsViewMode_->isChecked())
{
this->setupGraphicsView();
}
label_->setVisible(image.isNull());
}
void ObjWidget::updateWords(const QMultiMap<int,int> & words)
{
words_.clear();
for(QMultiMap<int,int>::const_iterator iter=words.begin(); iter!=words.end(); ++iter)
{
words_.insert(iter.value(), iter.key());
}
for(int i=0; i<keypointItems_.size(); ++i)
{
keypointItems_[i]->setWordID(words_.value(i,-1));
}
}
void ObjWidget::resetKptsColor()
@@ -303,6 +317,15 @@ void ObjWidget::resetKptsColor()
rectItems_.clear();
}
void ObjWidget::resetKptsWordID()
{
words_.clear();
for(int i=0; i<keypointItems_.size(); ++i)
{
keypointItems_[i]->setWordID(-1);
}
}
void ObjWidget::setKptColor(int index, const QColor & color)
{
if(index < kptColors_.size())
@@ -325,6 +348,15 @@ void ObjWidget::setKptColor(int index, const QColor & color)
}
}
void ObjWidget::setKptWordID(int index, int wordID)
{
words_.insert(index, wordID);
if(index < keypointItems_.size())
{
keypointItems_.at(index)->setWordID(wordID);
}
}
void ObjWidget::addRect(QGraphicsRectItem * rect)
{
if(graphicsViewInitialized_)
@@ -701,14 +733,8 @@ void ObjWidget::drawKeypoints(QPainter * painter)
QColor color(kptColors_.at(i).red(), kptColors_.at(i).green(), kptColors_.at(i).blue(), alpha_);
if(graphicsViewMode_->isChecked())
{
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, color);
item = new KeypointItem(i, r.pt.x-radius, r.pt.y-radius, radius*2, r, words_.value(i, -1), color);
item->setVisible(this->isFeaturesShown());
item->setZValue(2);
graphicsView_->scene()->addItem(item);
@@ -743,7 +769,7 @@ std::vector<cv::KeyPoint> ObjWidget::selectedKeypoints() const
{
if(qgraphicsitem_cast<KeypointItem*>(items.at(i)))
{
selected.push_back(keypoints_.at(((KeypointItem*)items.at(i))->id()-1)); // ids start at 1
selected.push_back(keypoints_.at(((KeypointItem*)items.at(i))->id()));
}
}
}
+2
View File
@@ -44,6 +44,8 @@ public:
void update();
void search(const cv::Mat & descriptors, cv::Mat & results, cv::Mat & dists, int k);
int size() const {return indexedDescriptors_.rows + notIndexedDescriptors_.rows;}
int dim() const {return !indexedDescriptors_.empty()?indexedDescriptors_.cols:notIndexedDescriptors_.cols;}
int type() const {return !indexedDescriptors_.empty()?indexedDescriptors_.type():notIndexedDescriptors_.type();}
const QMultiMap<int, int> & wordToObjects() const {return wordToObjects_;}
const cv::Mat & indexedDescriptors() const {return indexedDescriptors_;}