Refactored GPU/Keypoint detector/Descriptor extractor
git-svn-id: http://find-object.googlecode.com/svn/trunk/find_object@342 620bd6b2-0a58-f614-fd9a-1bd335dccda9
This commit is contained in:
parent
7bdf4e903e
commit
0dd16a6ef4
@ -66,7 +66,7 @@ void ImagesTcpServer::publishImage(const cv::Mat & image)
|
|||||||
QDataStream out(&block, QIODevice::WriteOnly);
|
QDataStream out(&block, QIODevice::WriteOnly);
|
||||||
out.setVersion(QDataStream::Qt_4_0);
|
out.setVersion(QDataStream::Qt_4_0);
|
||||||
out << (quint64)0;
|
out << (quint64)0;
|
||||||
out.writeRawData((char*)buf.data(), buf.size());
|
out.writeRawData((char*)buf.data(), (int)buf.size());
|
||||||
out.device()->seek(0);
|
out.device()->seek(0);
|
||||||
out << (quint64)(block.size() - sizeof(quint64));
|
out << (quint64)(block.size() - sizeof(quint64));
|
||||||
(*iter)->write(block);
|
(*iter)->write(block);
|
||||||
|
|||||||
@ -27,7 +27,6 @@ private slots:
|
|||||||
void publishImage(const cv::Mat & image);
|
void publishImage(const cv::Mat & image);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float hz_;
|
|
||||||
Camera camera_;
|
Camera camera_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -27,8 +27,8 @@ AddObjectDialog::AddObjectDialog(Camera * camera, const cv::Mat & image, bool mi
|
|||||||
ui_ = new Ui_addObjectDialog();
|
ui_ = new Ui_addObjectDialog();
|
||||||
ui_->setupUi(this);
|
ui_->setupUi(this);
|
||||||
|
|
||||||
detector_ = Settings::createFeaturesDetector();
|
detector_ = Settings::createKeypointDetector();
|
||||||
extractor_ = Settings::createDescriptorsExtractor();
|
extractor_ = Settings::createDescriptorExtractor();
|
||||||
Q_ASSERT(detector_ != 0 && extractor_ != 0);
|
Q_ASSERT(detector_ != 0 && extractor_ != 0);
|
||||||
|
|
||||||
connect(ui_->pushButton_cancel, SIGNAL(clicked()), this, SLOT(cancel()));
|
connect(ui_->pushButton_cancel, SIGNAL(clicked()), this, SLOT(cancel()));
|
||||||
|
|||||||
@ -14,6 +14,8 @@ class Ui_addObjectDialog;
|
|||||||
class ObjWidget;
|
class ObjWidget;
|
||||||
class Camera;
|
class Camera;
|
||||||
class KeypointItem;
|
class KeypointItem;
|
||||||
|
class KeypointDetector;
|
||||||
|
class DescriptorExtractor;
|
||||||
|
|
||||||
class AddObjectDialog : public QDialog {
|
class AddObjectDialog : public QDialog {
|
||||||
|
|
||||||
@ -47,8 +49,8 @@ private:
|
|||||||
Camera * camera_;
|
Camera * camera_;
|
||||||
ObjWidget * object_;
|
ObjWidget * object_;
|
||||||
cv::Mat cvImage_;
|
cv::Mat cvImage_;
|
||||||
cv::FeatureDetector * detector_;
|
KeypointDetector * detector_;
|
||||||
cv::DescriptorExtractor * extractor_;
|
DescriptorExtractor * extractor_;
|
||||||
|
|
||||||
enum State{kTakePicture, kSelectFeatures, kVerifySelection, kClosing};
|
enum State{kTakePicture, kSelectFeatures, kVerifySelection, kClosing};
|
||||||
int state_;
|
int state_;
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
#include "AboutDialog.h"
|
#include "AboutDialog.h"
|
||||||
#include "TcpServer.h"
|
#include "TcpServer.h"
|
||||||
#include "rtabmap/PdfPlot.h"
|
#include "rtabmap/PdfPlot.h"
|
||||||
|
#include "Vocabulary.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -49,6 +50,7 @@ MainWindow::MainWindow(Camera * camera, const QString & settings, QWidget * pare
|
|||||||
settings_(settings),
|
settings_(settings),
|
||||||
likelihoodCurve_(0),
|
likelihoodCurve_(0),
|
||||||
inliersCurve_(0),
|
inliersCurve_(0),
|
||||||
|
vocabulary_(new Vocabulary()),
|
||||||
lowestRefreshRate_(99),
|
lowestRefreshRate_(99),
|
||||||
objectsModified_(false),
|
objectsModified_(false),
|
||||||
tcpServer_(0),
|
tcpServer_(0),
|
||||||
@ -117,13 +119,14 @@ MainWindow::MainWindow(Camera * camera, const QString & settings, QWidget * pare
|
|||||||
ui_->toolBox->updateParameter(Settings::kFeature2D_Fast_gpu());
|
ui_->toolBox->updateParameter(Settings::kFeature2D_Fast_gpu());
|
||||||
ui_->toolBox->updateParameter(Settings::kFeature2D_ORB_gpu());
|
ui_->toolBox->updateParameter(Settings::kFeature2D_ORB_gpu());
|
||||||
ui_->toolBox->getParameterWidget(Settings::kFeature2D_SURF_gpu())->setEnabled(false);
|
ui_->toolBox->getParameterWidget(Settings::kFeature2D_SURF_gpu())->setEnabled(false);
|
||||||
|
ui_->toolBox->getParameterWidget(Settings::kFeature2D_SURF_keypointsRatio())->setEnabled(false);
|
||||||
ui_->toolBox->getParameterWidget(Settings::kFeature2D_Fast_gpu())->setEnabled(false);
|
ui_->toolBox->getParameterWidget(Settings::kFeature2D_Fast_gpu())->setEnabled(false);
|
||||||
ui_->toolBox->getParameterWidget(Settings::kFeature2D_Fast_keypointsRatio())->setEnabled(false);
|
ui_->toolBox->getParameterWidget(Settings::kFeature2D_Fast_keypointsRatio())->setEnabled(false);
|
||||||
ui_->toolBox->getParameterWidget(Settings::kFeature2D_ORB_gpu())->setEnabled(false);
|
ui_->toolBox->getParameterWidget(Settings::kFeature2D_ORB_gpu())->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
detector_ = Settings::createFeaturesDetector();
|
detector_ = Settings::createKeypointDetector();
|
||||||
extractor_ = Settings::createDescriptorsExtractor();
|
extractor_ = Settings::createDescriptorExtractor();
|
||||||
Q_ASSERT(detector_ != 0 && extractor_ != 0);
|
Q_ASSERT(detector_ != 0 && extractor_ != 0);
|
||||||
|
|
||||||
connect((QDoubleSpinBox*)ui_->toolBox->getParameterWidget(Settings::kCamera_4imageRate()),
|
connect((QDoubleSpinBox*)ui_->toolBox->getParameterWidget(Settings::kCamera_4imageRate()),
|
||||||
@ -217,6 +220,7 @@ MainWindow::~MainWindow()
|
|||||||
camera_->stop();
|
camera_->stop();
|
||||||
delete detector_;
|
delete detector_;
|
||||||
delete extractor_;
|
delete extractor_;
|
||||||
|
delete vocabulary_;
|
||||||
objectsDescriptors_.clear();
|
objectsDescriptors_.clear();
|
||||||
qDeleteAll(objects_.begin(), objects_.end());
|
qDeleteAll(objects_.begin(), objects_.end());
|
||||||
objects_.clear();
|
objects_.clear();
|
||||||
@ -349,7 +353,7 @@ int MainWindow::loadObjects(const QString & dirPath)
|
|||||||
{
|
{
|
||||||
this->updateObjects();
|
this->updateObjects();
|
||||||
}
|
}
|
||||||
loadedObjects = names.size();
|
loadedObjects = (int)names.size();
|
||||||
}
|
}
|
||||||
return loadedObjects;
|
return loadedObjects;
|
||||||
}
|
}
|
||||||
@ -756,7 +760,7 @@ protected:
|
|||||||
QTime time;
|
QTime time;
|
||||||
time.start();
|
time.start();
|
||||||
printf("Extracting descriptors from object %d...\n", objectId_);
|
printf("Extracting descriptors from object %d...\n", objectId_);
|
||||||
cv::FeatureDetector * detector = Settings::createFeaturesDetector();
|
KeypointDetector * detector = Settings::createKeypointDetector();
|
||||||
keypoints_.clear();
|
keypoints_.clear();
|
||||||
descriptors_ = cv::Mat();
|
descriptors_ = cv::Mat();
|
||||||
detector->detect(image_, keypoints_);
|
detector->detect(image_, keypoints_);
|
||||||
@ -767,12 +771,12 @@ protected:
|
|||||||
int maxFeatures = Settings::getFeature2D_3MaxFeatures();
|
int maxFeatures = Settings::getFeature2D_3MaxFeatures();
|
||||||
if(maxFeatures > 0 && (int)keypoints_.size() > maxFeatures)
|
if(maxFeatures > 0 && (int)keypoints_.size() > maxFeatures)
|
||||||
{
|
{
|
||||||
int previousCount = keypoints_.size();
|
int previousCount = (int)keypoints_.size();
|
||||||
keypoints_ = limitKeypoints(keypoints_, maxFeatures);
|
keypoints_ = limitKeypoints(keypoints_, maxFeatures);
|
||||||
printf("obj=%d, %d keypoints removed, (kept %d), min/max response=%f/%f\n", objectId_, previousCount-(int)keypoints_.size(), (int)keypoints_.size(), keypoints_.size()?keypoints_.back().response:0.0f, keypoints_.size()?keypoints_.front().response:0.0f);
|
printf("obj=%d, %d keypoints removed, (kept %d), min/max response=%f/%f\n", objectId_, previousCount-(int)keypoints_.size(), (int)keypoints_.size(), keypoints_.size()?keypoints_.back().response:0.0f, keypoints_.size()?keypoints_.front().response:0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::DescriptorExtractor * extractor = Settings::createDescriptorsExtractor();
|
DescriptorExtractor * extractor = Settings::createDescriptorExtractor();
|
||||||
extractor->compute(image_, keypoints_, descriptors_);
|
extractor->compute(image_, keypoints_, descriptors_);
|
||||||
delete extractor;
|
delete extractor;
|
||||||
if((int)keypoints_.size() != descriptors_.rows)
|
if((int)keypoints_.size() != descriptors_.rows)
|
||||||
@ -858,7 +862,7 @@ void MainWindow::updateData()
|
|||||||
|
|
||||||
objectsDescriptors_.clear();
|
objectsDescriptors_.clear();
|
||||||
dataRange_.clear();
|
dataRange_.clear();
|
||||||
vocabulary_.clear();
|
vocabulary_->clear();
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int dim = -1;
|
int dim = -1;
|
||||||
int type = -1;
|
int type = -1;
|
||||||
@ -944,13 +948,13 @@ void MainWindow::updateData()
|
|||||||
int addedWords = 0;
|
int addedWords = 0;
|
||||||
for(int i=0; i<objects_.size(); ++i)
|
for(int i=0; i<objects_.size(); ++i)
|
||||||
{
|
{
|
||||||
QMultiMap<int, int> words = vocabulary_.addWords(objects_[i]->descriptors(), i, incremental);
|
QMultiMap<int, int> words = vocabulary_->addWords(objects_[i]->descriptors(), i, incremental);
|
||||||
objects_[i]->setWords(words);
|
objects_[i]->setWords(words);
|
||||||
addedWords += words.uniqueKeys().size();
|
addedWords += words.uniqueKeys().size();
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
if(incremental && addedWords && addedWords >= updateVocabularyMinWords)
|
if(incremental && addedWords && addedWords >= updateVocabularyMinWords)
|
||||||
{
|
{
|
||||||
vocabulary_.update();
|
vocabulary_->update();
|
||||||
addedWords = 0;
|
addedWords = 0;
|
||||||
updated = true;
|
updated = true;
|
||||||
}
|
}
|
||||||
@ -958,23 +962,23 @@ void MainWindow::updateData()
|
|||||||
objects_[i]->id(),
|
objects_[i]->id(),
|
||||||
words.uniqueKeys().size(),
|
words.uniqueKeys().size(),
|
||||||
objects_[i]->descriptors().rows,
|
objects_[i]->descriptors().rows,
|
||||||
vocabulary_.size(),
|
vocabulary_->size(),
|
||||||
localTime.restart(),
|
localTime.restart(),
|
||||||
updated?"updated":"");
|
updated?"updated":"");
|
||||||
}
|
}
|
||||||
if(addedWords)
|
if(addedWords)
|
||||||
{
|
{
|
||||||
vocabulary_.update();
|
vocabulary_->update();
|
||||||
}
|
}
|
||||||
ui_->label_timeIndexing->setNum(time.elapsed());
|
ui_->label_timeIndexing->setNum(time.elapsed());
|
||||||
ui_->label_vocabularySize->setNum(vocabulary_.size());
|
ui_->label_vocabularySize->setNum(vocabulary_->size());
|
||||||
if(incremental)
|
if(incremental)
|
||||||
{
|
{
|
||||||
printf("Creating incremental vocabulary... done! size=%d (%d ms)\n", vocabulary_.size(), time.elapsed());
|
printf("Creating incremental vocabulary... done! size=%d (%d ms)\n", vocabulary_->size(), time.elapsed());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("Creating vocabulary... done! size=%d (%d ms)\n", vocabulary_.size(), time.elapsed());
|
printf("Creating vocabulary... done! size=%d (%d ms)\n", vocabulary_->size(), time.elapsed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1366,8 +1370,8 @@ void MainWindow::update(const cv::Mat & image)
|
|||||||
ui_->imageView_source->setData(keypoints, cv::Mat(), image, Settings::currentDetectorType(), Settings::currentDescriptorType());
|
ui_->imageView_source->setData(keypoints, cv::Mat(), image, Settings::currentDetectorType(), Settings::currentDescriptorType());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool consistentNNData = (vocabulary_.size()!=0 && vocabulary_.wordToObjects().begin().value()!=-1 && Settings::getGeneral_invertedSearch()) ||
|
bool consistentNNData = (vocabulary_->size()!=0 && vocabulary_->wordToObjects().begin().value()!=-1 && Settings::getGeneral_invertedSearch()) ||
|
||||||
((vocabulary_.size()==0 || vocabulary_.wordToObjects().begin().value()==-1) && !Settings::getGeneral_invertedSearch());
|
((vocabulary_->size()==0 || vocabulary_->wordToObjects().begin().value()==-1) && !Settings::getGeneral_invertedSearch());
|
||||||
|
|
||||||
// COMPARE
|
// COMPARE
|
||||||
if(!objectsDescriptors_.empty() &&
|
if(!objectsDescriptors_.empty() &&
|
||||||
@ -1385,15 +1389,15 @@ void MainWindow::update(const cv::Mat & image)
|
|||||||
{
|
{
|
||||||
// CREATE INDEX for the scene
|
// CREATE INDEX for the scene
|
||||||
//printf("Creating FLANN index (%s)\n", Settings::currentNearestNeighborType().toStdString().c_str());
|
//printf("Creating FLANN index (%s)\n", Settings::currentNearestNeighborType().toStdString().c_str());
|
||||||
vocabulary_.clear();
|
vocabulary_->clear();
|
||||||
QMultiMap<int, int> words = vocabulary_.addWords(descriptors, -1, Settings::getGeneral_vocabularyIncremental());
|
QMultiMap<int, int> words = vocabulary_->addWords(descriptors, -1, Settings::getGeneral_vocabularyIncremental());
|
||||||
if(!Settings::getGeneral_vocabularyIncremental())
|
if(!Settings::getGeneral_vocabularyIncremental())
|
||||||
{
|
{
|
||||||
vocabulary_.update();
|
vocabulary_->update();
|
||||||
}
|
}
|
||||||
ui_->imageView_source->setWords(words);
|
ui_->imageView_source->setWords(words);
|
||||||
ui_->label_timeIndexing->setNum(time.restart());
|
ui_->label_timeIndexing->setNum(time.restart());
|
||||||
ui_->label_vocabularySize->setNum(vocabulary_.size());
|
ui_->label_vocabularySize->setNum(vocabulary_->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Settings::getGeneral_invertedSearch() || Settings::getGeneral_threads() == 1)
|
if(Settings::getGeneral_invertedSearch() || Settings::getGeneral_threads() == 1)
|
||||||
@ -1407,14 +1411,14 @@ void MainWindow::update(const cv::Mat & image)
|
|||||||
//match objects to scene
|
//match objects to scene
|
||||||
results = cv::Mat(objectsDescriptors_[0].rows, k, CV_32SC1); // results index
|
results = cv::Mat(objectsDescriptors_[0].rows, k, CV_32SC1); // results index
|
||||||
dists = cv::Mat(objectsDescriptors_[0].rows, k, CV_32FC1); // Distance results are CV_32FC1
|
dists = cv::Mat(objectsDescriptors_[0].rows, k, CV_32FC1); // Distance results are CV_32FC1
|
||||||
vocabulary_.search(objectsDescriptors_[0], results, dists, k);
|
vocabulary_->search(objectsDescriptors_[0], results, dists, k);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//match scene to objects
|
//match scene to objects
|
||||||
results = cv::Mat(descriptors.rows, k, CV_32SC1); // results index
|
results = cv::Mat(descriptors.rows, k, CV_32SC1); // results index
|
||||||
dists = cv::Mat(descriptors.rows, k, CV_32FC1); // Distance results are CV_32FC1
|
dists = cv::Mat(descriptors.rows, k, CV_32FC1); // Distance results are CV_32FC1
|
||||||
vocabulary_.search(descriptors, results, dists, k);
|
vocabulary_->search(descriptors, results, dists, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PROCESS RESULTS
|
// PROCESS RESULTS
|
||||||
@ -1459,11 +1463,11 @@ void MainWindow::update(const cv::Mat & image)
|
|||||||
if(Settings::getGeneral_invertedSearch())
|
if(Settings::getGeneral_invertedSearch())
|
||||||
{
|
{
|
||||||
int wordId = results.at<int>(i,0);
|
int wordId = results.at<int>(i,0);
|
||||||
QList<int> objIndexes = vocabulary_.wordToObjects().values(wordId);
|
QList<int> objIndexes = vocabulary_->wordToObjects().values(wordId);
|
||||||
for(int j=0; j<objIndexes.size(); ++j)
|
for(int j=0; j<objIndexes.size(); ++j)
|
||||||
{
|
{
|
||||||
// just add unique matches
|
// just add unique matches
|
||||||
if(vocabulary_.wordToObjects().count(wordId, objIndexes[j]) == 1)
|
if(vocabulary_->wordToObjects().count(wordId, objIndexes[j]) == 1)
|
||||||
{
|
{
|
||||||
matches[objIndexes[j]].insert(objects_.at(objIndexes[j])->words().value(wordId), i);
|
matches[objIndexes[j]].insert(objects_.at(objIndexes[j])->words().value(wordId), i);
|
||||||
}
|
}
|
||||||
@ -1491,7 +1495,7 @@ void MainWindow::update(const cv::Mat & image)
|
|||||||
unsigned int threadCounts = Settings::getGeneral_threads();
|
unsigned int threadCounts = Settings::getGeneral_threads();
|
||||||
if(threadCounts == 0)
|
if(threadCounts == 0)
|
||||||
{
|
{
|
||||||
threadCounts = objectsDescriptors_.size();
|
threadCounts = (int)objectsDescriptors_.size();
|
||||||
}
|
}
|
||||||
for(unsigned int j=0; j<objectsDescriptors_.size(); j+=threadCounts)
|
for(unsigned int j=0; j<objectsDescriptors_.size(); j+=threadCounts)
|
||||||
{
|
{
|
||||||
@ -1499,7 +1503,7 @@ void MainWindow::update(const cv::Mat & image)
|
|||||||
|
|
||||||
for(unsigned int k=j; k<j+threadCounts && k<objectsDescriptors_.size(); ++k)
|
for(unsigned int k=j; k<j+threadCounts && k<objectsDescriptors_.size(); ++k)
|
||||||
{
|
{
|
||||||
threads.push_back(new SearchThread(&vocabulary_, k, &objectsDescriptors_[k], ui_->imageView_source));
|
threads.push_back(new SearchThread(vocabulary_, k, &objectsDescriptors_[k], ui_->imageView_source));
|
||||||
threads.back()->start();
|
threads.back()->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1823,6 +1827,9 @@ void MainWindow::notifyParametersChanged(const QStringList & paramChanged)
|
|||||||
for(QStringList::const_iterator iter = paramChanged.begin(); iter!=paramChanged.end(); ++iter)
|
for(QStringList::const_iterator iter = paramChanged.begin(); iter!=paramChanged.end(); ++iter)
|
||||||
{
|
{
|
||||||
printf("Parameter changed: %s -> \"%s\"\n", iter->toStdString().c_str(), Settings::getParameter(*iter).toString().toStdString().c_str());
|
printf("Parameter changed: %s -> \"%s\"\n", iter->toStdString().c_str(), Settings::getParameter(*iter).toString().toStdString().c_str());
|
||||||
|
printf("lastObjectsUpdateParameters_.value(*iter)=%s, Settings::getParameter(*iter)=%s",
|
||||||
|
lastObjectsUpdateParameters_.value(*iter).toString().toStdString().c_str(),
|
||||||
|
Settings::getParameter(*iter).toString().toStdString().c_str());
|
||||||
if(lastObjectsUpdateParameters_.value(*iter) != Settings::getParameter(*iter))
|
if(lastObjectsUpdateParameters_.value(*iter) != Settings::getParameter(*iter))
|
||||||
{
|
{
|
||||||
if(!detectorDescriptorParamsChanged && iter->contains("Feature2D"))
|
if(!detectorDescriptorParamsChanged && iter->contains("Feature2D"))
|
||||||
@ -1837,6 +1844,7 @@ void MainWindow::notifyParametersChanged(const QStringList & paramChanged)
|
|||||||
{
|
{
|
||||||
nearestNeighborParamsChanged = true;
|
nearestNeighborParamsChanged = true;
|
||||||
}
|
}
|
||||||
|
lastObjectsUpdateParameters_[*iter] = Settings::getParameter(*iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(iter->compare(Settings::kGeneral_port()) == 0 &&
|
if(iter->compare(Settings::kGeneral_port()) == 0 &&
|
||||||
@ -1852,8 +1860,8 @@ void MainWindow::notifyParametersChanged(const QStringList & paramChanged)
|
|||||||
//Re-init detector and extractor
|
//Re-init detector and extractor
|
||||||
delete detector_;
|
delete detector_;
|
||||||
delete extractor_;
|
delete extractor_;
|
||||||
detector_ = Settings::createFeaturesDetector();
|
detector_ = Settings::createKeypointDetector();
|
||||||
extractor_ = Settings::createDescriptorsExtractor();
|
extractor_ = Settings::createDescriptorExtractor();
|
||||||
Q_ASSERT(detector_ != 0 && extractor_ != 0);
|
Q_ASSERT(detector_ != 0 && extractor_ != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,11 +12,7 @@
|
|||||||
#include <QtCore/QMap>
|
#include <QtCore/QMap>
|
||||||
#include <QtCore/QByteArray>
|
#include <QtCore/QByteArray>
|
||||||
|
|
||||||
#include <opencv2/core/core.hpp>
|
#include <opencv2/opencv.hpp>
|
||||||
#include <opencv2/features2d/features2d.hpp>
|
|
||||||
#include <opencv2/imgproc/imgproc_c.h>
|
|
||||||
|
|
||||||
#include "Vocabulary.h"
|
|
||||||
|
|
||||||
class Ui_mainWindow;
|
class Ui_mainWindow;
|
||||||
class ObjWidget;
|
class ObjWidget;
|
||||||
@ -25,6 +21,9 @@ class ParametersToolBox;
|
|||||||
class QLabel;
|
class QLabel;
|
||||||
class AboutDialog;
|
class AboutDialog;
|
||||||
class TcpServer;
|
class TcpServer;
|
||||||
|
class KeypointDetector;
|
||||||
|
class DescriptorExtractor;
|
||||||
|
class Vocabulary;
|
||||||
|
|
||||||
namespace rtabmap
|
namespace rtabmap
|
||||||
{
|
{
|
||||||
@ -96,7 +95,7 @@ private:
|
|||||||
AboutDialog * aboutDialog_;
|
AboutDialog * aboutDialog_;
|
||||||
QList<ObjWidget*> objects_;
|
QList<ObjWidget*> objects_;
|
||||||
std::vector<cv::Mat> objectsDescriptors_;
|
std::vector<cv::Mat> objectsDescriptors_;
|
||||||
Vocabulary vocabulary_;
|
Vocabulary * vocabulary_;
|
||||||
QMap<int, int> dataRange_; // <last id of object's descriptor, id>
|
QMap<int, int> dataRange_; // <last id of object's descriptor, id>
|
||||||
QTime updateRate_;
|
QTime updateRate_;
|
||||||
QTime refreshStartTime_;
|
QTime refreshStartTime_;
|
||||||
@ -105,8 +104,8 @@ private:
|
|||||||
QMap<int, QByteArray> imagesMap_;
|
QMap<int, QByteArray> imagesMap_;
|
||||||
TcpServer * tcpServer_;
|
TcpServer * tcpServer_;
|
||||||
QMap<QString, QVariant> lastObjectsUpdateParameters_; // ParametersMap
|
QMap<QString, QVariant> lastObjectsUpdateParameters_; // ParametersMap
|
||||||
cv::FeatureDetector * detector_;
|
KeypointDetector * detector_;
|
||||||
cv::DescriptorExtractor * extractor_;
|
DescriptorExtractor * extractor_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MainWindow_H_ */
|
#endif /* MainWindow_H_ */
|
||||||
|
|||||||
@ -247,7 +247,7 @@ void ObjWidget::setData(const std::vector<cv::KeyPoint> & keypoints,
|
|||||||
{
|
{
|
||||||
keypoints_ = keypoints;
|
keypoints_ = keypoints;
|
||||||
descriptors_ = descriptors;
|
descriptors_ = descriptors;
|
||||||
kptColors_ = QVector<QColor>(keypoints.size(), defaultColor());
|
kptColors_ = QVector<QColor>((int)keypoints.size(), defaultColor());
|
||||||
keypointItems_.clear();
|
keypointItems_.clear();
|
||||||
rectItems_.clear();
|
rectItems_.clear();
|
||||||
graphicsView_->scene()->clear();
|
graphicsView_->scene()->clear();
|
||||||
|
|||||||
302
src/Settings.cpp
302
src/Settings.cpp
@ -11,6 +11,7 @@
|
|||||||
#include <opencv2/nonfree/features2d.hpp>
|
#include <opencv2/nonfree/features2d.hpp>
|
||||||
#include <opencv2/calib3d/calib3d.hpp>
|
#include <opencv2/calib3d/calib3d.hpp>
|
||||||
#include <opencv2/nonfree/gpu.hpp>
|
#include <opencv2/nonfree/gpu.hpp>
|
||||||
|
#include <opencv2/gpu/gpu.hpp>
|
||||||
|
|
||||||
#define VERBOSE 0
|
#define VERBOSE 0
|
||||||
|
|
||||||
@ -118,56 +119,77 @@ void Settings::saveSettings(const QString & fileName, const QByteArray & windowG
|
|||||||
printf("Settings saved to %s\n", path.toStdString().c_str());
|
printf("Settings saved to %s\n", path.toStdString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
class GPUSURF : public cv::Feature2D
|
class GPUFeature2D
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GPUFeature2D() {}
|
||||||
|
virtual ~GPUFeature2D() {}
|
||||||
|
|
||||||
|
virtual void detectKeypoints(const cv::Mat & image,
|
||||||
|
std::vector<cv::KeyPoint> & keypoints) = 0;
|
||||||
|
|
||||||
|
virtual void computeDescriptors(const cv::Mat & image,
|
||||||
|
std::vector<cv::KeyPoint> & keypoints,
|
||||||
|
cv::Mat & descriptors) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GPUSURF : public GPUFeature2D
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GPUSURF(double hessianThreshold,
|
GPUSURF(double hessianThreshold,
|
||||||
int nOctaves = Settings::defaultFeature2D_SURF_nOctaves(),
|
int nOctaves,
|
||||||
int nOctaveLayers = Settings::defaultFeature2D_SURF_nOctaveLayers(),
|
int nOctaveLayers,
|
||||||
bool extended = Settings::defaultFeature2D_SURF_extended(),
|
bool extended,
|
||||||
bool upright = Settings::defaultFeature2D_SURF_upright()) :
|
float keypointsRatio,
|
||||||
hessianThreshold_(hessianThreshold),
|
bool upright) :
|
||||||
nOctaves_(nOctaves),
|
surf_(hessianThreshold,
|
||||||
nOctaveLayers_(nOctaveLayers),
|
nOctaves,
|
||||||
extended_(extended),
|
nOctaveLayers,
|
||||||
upright_(upright)
|
extended,
|
||||||
|
keypointsRatio,
|
||||||
|
upright)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
virtual ~GPUSURF() {}
|
virtual ~GPUSURF() {}
|
||||||
|
|
||||||
void operator()(cv::InputArray img, cv::InputArray mask,
|
void detectKeypoints(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints)
|
||||||
std::vector<cv::KeyPoint>& keypoints,
|
|
||||||
cv::OutputArray descriptors,
|
|
||||||
bool useProvidedKeypoints=false) const
|
|
||||||
{
|
|
||||||
printf("GPUSURF:operator() Don't call this directly!\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
int descriptorSize() const
|
|
||||||
{
|
|
||||||
return extended_ ? 128 : 64;
|
|
||||||
}
|
|
||||||
int descriptorType() const
|
|
||||||
{
|
|
||||||
return CV_32F;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void detectImpl( const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask=cv::Mat() ) const
|
|
||||||
{
|
{
|
||||||
cv::gpu::GpuMat imgGpu(image);
|
cv::gpu::GpuMat imgGpu(image);
|
||||||
cv::gpu::GpuMat maskGpu(mask);
|
try
|
||||||
cv::gpu::SURF_GPU surfGpu(hessianThreshold_, nOctaves_, nOctaveLayers_, extended_, 0.01f, upright_);
|
{
|
||||||
surfGpu(imgGpu, maskGpu, keypoints);
|
surf_(imgGpu, cv::gpu::GpuMat(), keypoints);
|
||||||
|
}
|
||||||
|
catch(cv::Exception &e)
|
||||||
|
{
|
||||||
|
printf("GPUSURF error: %s \n(If something about layer_rows, parameter nOctaves=%d of SURF is too high for the size of the image (%d,%d).)\n",
|
||||||
|
e.msg.c_str(),
|
||||||
|
surf_.nOctaves,
|
||||||
|
image.cols,
|
||||||
|
image.rows);
|
||||||
|
printf("img.size().area()=%d surf.keypointsRatio=%d\n", imgGpu.size().area(), surf_.keypointsRatio);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void computeImpl( const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, cv::Mat& descriptors ) const
|
void computeDescriptors( const cv::Mat& image,
|
||||||
|
std::vector<cv::KeyPoint>& keypoints,
|
||||||
|
cv::Mat& descriptors)
|
||||||
{
|
{
|
||||||
std::vector<float> d;
|
std::vector<float> d;
|
||||||
cv::gpu::GpuMat imgGpu(image);
|
cv::gpu::GpuMat imgGpu(image);
|
||||||
cv::gpu::SURF_GPU surfGpu(hessianThreshold_, nOctaves_, nOctaveLayers_, extended_, 0.01f, upright_);
|
|
||||||
cv::gpu::GpuMat descriptorsGPU;
|
cv::gpu::GpuMat descriptorsGPU;
|
||||||
surfGpu(imgGpu, cv::gpu::GpuMat(), keypoints, descriptorsGPU, true);
|
try
|
||||||
|
{
|
||||||
|
surf_(imgGpu, cv::gpu::GpuMat(), keypoints, descriptorsGPU, true);
|
||||||
|
}
|
||||||
|
catch(cv::Exception &e)
|
||||||
|
{
|
||||||
|
printf("GPUSURF error: %s \n(If something about layer_rows, parameter nOctaves=%d of SURF is too high for the size of the image (%d,%d).)\n",
|
||||||
|
e.msg.c_str(),
|
||||||
|
surf_.nOctaves,
|
||||||
|
image.cols,
|
||||||
|
image.rows);
|
||||||
|
printf("img.size().area()=%d surf.keypointsRatio=%d\n", imgGpu.size().area(), surf_.keypointsRatio);
|
||||||
|
}
|
||||||
|
|
||||||
// Download descriptors
|
// Download descriptors
|
||||||
if (descriptorsGPU.empty())
|
if (descriptorsGPU.empty())
|
||||||
@ -179,44 +201,41 @@ protected:
|
|||||||
descriptorsGPU.download(descriptors);
|
descriptorsGPU.download(descriptors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double hessianThreshold_;
|
cv::gpu::SURF_GPU surf_; // HACK: static because detectImpl() is const!
|
||||||
int nOctaves_;
|
|
||||||
int nOctaveLayers_;
|
|
||||||
bool extended_;
|
|
||||||
bool upright_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class GPUFAST : public cv::FeatureDetector
|
class GPUFAST : public GPUFeature2D
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GPUFAST(int threshold=Settings::defaultFeature2D_Fast_threshold(),
|
GPUFAST(int threshold=Settings::defaultFeature2D_Fast_threshold(),
|
||||||
bool nonmaxSuppression=Settings::defaultFeature2D_Fast_nonmaxSuppression(),
|
bool nonmaxSuppression=Settings::defaultFeature2D_Fast_nonmaxSuppression(),
|
||||||
double keypointsRatio=Settings::defaultFeature2D_Fast_keypointsRatio()) :
|
double keypointsRatio=Settings::defaultFeature2D_Fast_keypointsRatio()) :
|
||||||
threshold_(threshold),
|
fast_(threshold,
|
||||||
nonmaxSuppression_(nonmaxSuppression),
|
nonmaxSuppression,
|
||||||
keypointsRatio_(keypointsRatio)
|
keypointsRatio)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
virtual ~GPUFAST() {}
|
virtual ~GPUFAST() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void detectImpl( const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask=cv::Mat() ) const
|
void detectKeypoints(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints)
|
||||||
{
|
{
|
||||||
cv::gpu::GpuMat imgGpu(image);
|
cv::gpu::GpuMat imgGpu(image);
|
||||||
cv::gpu::GpuMat maskGpu(mask);
|
fast_(imgGpu, cv::gpu::GpuMat(), keypoints);
|
||||||
cv::gpu::FAST_GPU fastGpu(threshold_, nonmaxSuppression_, keypointsRatio_);
|
}
|
||||||
fastGpu(imgGpu, maskGpu, keypoints);
|
void computeDescriptors( const cv::Mat& image,
|
||||||
|
std::vector<cv::KeyPoint>& keypoints,
|
||||||
|
cv::Mat& descriptors)
|
||||||
|
{
|
||||||
|
printf("GPUFAST:computeDescriptors() Should not be used!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int threshold_;
|
cv::gpu::FAST_GPU fast_;
|
||||||
bool nonmaxSuppression_;
|
|
||||||
double keypointsRatio_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class GPUORB : public cv::Feature2D
|
class GPUORB : public GPUFeature2D
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GPUORB(int nFeatures = Settings::defaultFeature2D_ORB_nFeatures(),
|
GPUORB(int nFeatures = Settings::defaultFeature2D_ORB_nFeatures(),
|
||||||
@ -229,56 +248,54 @@ public:
|
|||||||
int patchSize = Settings::defaultFeature2D_ORB_patchSize(),
|
int patchSize = Settings::defaultFeature2D_ORB_patchSize(),
|
||||||
int fastThreshold = Settings::defaultFeature2D_Fast_threshold(),
|
int fastThreshold = Settings::defaultFeature2D_Fast_threshold(),
|
||||||
bool fastNonmaxSupression = Settings::defaultFeature2D_Fast_nonmaxSuppression()) :
|
bool fastNonmaxSupression = Settings::defaultFeature2D_Fast_nonmaxSuppression()) :
|
||||||
nFeatures_(nFeatures),
|
orb_(nFeatures,
|
||||||
scaleFactor_(scaleFactor),
|
scaleFactor,
|
||||||
nLevels_(nLevels),
|
nLevels,
|
||||||
edgeThreshold_(edgeThreshold),
|
edgeThreshold ,
|
||||||
firstLevel_(firstLevel),
|
firstLevel,
|
||||||
WTA_K_(WTA_K),
|
WTA_K,
|
||||||
scoreType_(scoreType),
|
scoreType,
|
||||||
patchSize_(patchSize),
|
patchSize)
|
||||||
fastThreshold_(fastThreshold),
|
|
||||||
fastNonmaxSupression_(fastNonmaxSupression)
|
|
||||||
{
|
{
|
||||||
|
orb_.setFastParams(fastThreshold, fastNonmaxSupression);
|
||||||
}
|
}
|
||||||
virtual ~GPUORB() {}
|
virtual ~GPUORB() {}
|
||||||
|
|
||||||
void operator()(cv::InputArray img, cv::InputArray mask,
|
|
||||||
std::vector<cv::KeyPoint>& keypoints,
|
|
||||||
cv::OutputArray descriptors,
|
|
||||||
bool useProvidedKeypoints=false) const
|
|
||||||
{
|
|
||||||
printf("GPUSURF:operator() Don't call this directly!\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
int descriptorSize() const
|
|
||||||
{
|
|
||||||
return cv::ORB::kBytes;
|
|
||||||
}
|
|
||||||
int descriptorType() const
|
|
||||||
{
|
|
||||||
return CV_8U;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void detectImpl( const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask=cv::Mat() ) const
|
void detectKeypoints(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints)
|
||||||
{
|
{
|
||||||
cv::gpu::GpuMat imgGpu(image);
|
cv::gpu::GpuMat imgGpu(image);
|
||||||
cv::gpu::GpuMat maskGpu(mask);
|
try
|
||||||
cv::gpu::ORB_GPU orbGPU(nFeatures_, scaleFactor_, nLevels_, edgeThreshold_ ,firstLevel_, WTA_K_, scoreType_, patchSize_);
|
{
|
||||||
orbGPU.setFastParams(fastThreshold_, fastNonmaxSupression_);
|
orb_(imgGpu, cv::gpu::GpuMat(), keypoints);
|
||||||
orbGPU(imgGpu, maskGpu, keypoints);
|
}
|
||||||
|
catch(cv::Exception &e)
|
||||||
|
{
|
||||||
|
printf("GPUORB error: %s \n(If something about matrix size, the image/object may be too small (%d,%d).)\n",
|
||||||
|
e.msg.c_str(),
|
||||||
|
image.cols,
|
||||||
|
image.rows);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void computeImpl( const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, cv::Mat& descriptors ) const
|
void computeDescriptors( const cv::Mat& image,
|
||||||
|
std::vector<cv::KeyPoint>& keypoints,
|
||||||
|
cv::Mat& descriptors)
|
||||||
{
|
{
|
||||||
std::vector<float> d;
|
std::vector<float> d;
|
||||||
cv::gpu::GpuMat imgGpu(image);
|
cv::gpu::GpuMat imgGpu(image);
|
||||||
cv::gpu::ORB_GPU orbGPU(nFeatures_, scaleFactor_, nLevels_, edgeThreshold_ ,firstLevel_, WTA_K_, scoreType_, patchSize_);
|
|
||||||
orbGPU.setFastParams(fastThreshold_, fastNonmaxSupression_);
|
|
||||||
cv::gpu::GpuMat descriptorsGPU;
|
cv::gpu::GpuMat descriptorsGPU;
|
||||||
orbGPU(imgGpu, cv::gpu::GpuMat(), keypoints, descriptorsGPU); // No option to use provided keypoints!?
|
try
|
||||||
|
{
|
||||||
|
orb_(imgGpu, cv::gpu::GpuMat(), keypoints, descriptorsGPU); // No option to use provided keypoints!?
|
||||||
|
}
|
||||||
|
catch(cv::Exception &e)
|
||||||
|
{
|
||||||
|
printf("GPUORB error: %s \n(If something about matrix size, the image/object may be too small (%d,%d).)\n",
|
||||||
|
e.msg.c_str(),
|
||||||
|
image.cols,
|
||||||
|
image.rows);
|
||||||
|
}
|
||||||
// Download descriptors
|
// Download descriptors
|
||||||
if (descriptorsGPU.empty())
|
if (descriptorsGPU.empty())
|
||||||
descriptors = cv::Mat();
|
descriptors = cv::Mat();
|
||||||
@ -289,24 +306,14 @@ protected:
|
|||||||
descriptorsGPU.download(descriptors);
|
descriptorsGPU.download(descriptors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int nFeatures_;
|
cv::gpu::ORB_GPU orb_;
|
||||||
float scaleFactor_;
|
|
||||||
int nLevels_;
|
|
||||||
int edgeThreshold_;
|
|
||||||
int firstLevel_;
|
|
||||||
int WTA_K_;
|
|
||||||
int scoreType_;
|
|
||||||
int patchSize_;
|
|
||||||
int fastThreshold_;
|
|
||||||
bool fastNonmaxSupression_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
KeypointDetector * Settings::createKeypointDetector()
|
||||||
cv::FeatureDetector * Settings::createFeaturesDetector()
|
|
||||||
{
|
{
|
||||||
cv::FeatureDetector * detector = 0;
|
cv::FeatureDetector * detector = 0;
|
||||||
|
GPUFeature2D * detectorGPU = 0;
|
||||||
QString str = getFeature2D_1Detector();
|
QString str = getFeature2D_1Detector();
|
||||||
QStringList split = str.split(':');
|
QStringList split = str.split(':');
|
||||||
if(split.size()==2)
|
if(split.size()==2)
|
||||||
@ -339,7 +346,7 @@ cv::FeatureDetector * Settings::createFeaturesDetector()
|
|||||||
{
|
{
|
||||||
if(getFeature2D_Fast_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
if(getFeature2D_Fast_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
||||||
{
|
{
|
||||||
detector = new GPUFAST(
|
detectorGPU = new GPUFAST(
|
||||||
getFeature2D_Fast_threshold(),
|
getFeature2D_Fast_threshold(),
|
||||||
getFeature2D_Fast_nonmaxSuppression());
|
getFeature2D_Fast_nonmaxSuppression());
|
||||||
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s GPU\n", strategies.at(index).toStdString().c_str());
|
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s GPU\n", strategies.at(index).toStdString().c_str());
|
||||||
@ -387,7 +394,7 @@ cv::FeatureDetector * Settings::createFeaturesDetector()
|
|||||||
{
|
{
|
||||||
if(getFeature2D_ORB_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
if(getFeature2D_ORB_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
||||||
{
|
{
|
||||||
detector = new GPUORB(
|
detectorGPU = new GPUORB(
|
||||||
getFeature2D_ORB_nFeatures(),
|
getFeature2D_ORB_nFeatures(),
|
||||||
getFeature2D_ORB_scaleFactor(),
|
getFeature2D_ORB_scaleFactor(),
|
||||||
getFeature2D_ORB_nLevels(),
|
getFeature2D_ORB_nLevels(),
|
||||||
@ -444,11 +451,12 @@ cv::FeatureDetector * Settings::createFeaturesDetector()
|
|||||||
{
|
{
|
||||||
if(getFeature2D_SURF_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
if(getFeature2D_SURF_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
||||||
{
|
{
|
||||||
detector = new GPUSURF(
|
detectorGPU = new GPUSURF(
|
||||||
getFeature2D_SURF_hessianThreshold(),
|
getFeature2D_SURF_hessianThreshold(),
|
||||||
getFeature2D_SURF_nOctaves(),
|
getFeature2D_SURF_nOctaves(),
|
||||||
getFeature2D_SURF_nOctaveLayers(),
|
getFeature2D_SURF_nOctaveLayers(),
|
||||||
getFeature2D_SURF_extended(),
|
getFeature2D_SURF_extended(),
|
||||||
|
getFeature2D_SURF_keypointsRatio(),
|
||||||
getFeature2D_SURF_upright());
|
getFeature2D_SURF_upright());
|
||||||
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s (GPU)\n", strategies.at(index).toStdString().c_str());
|
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s (GPU)\n", strategies.at(index).toStdString().c_str());
|
||||||
}
|
}
|
||||||
@ -480,17 +488,22 @@ cv::FeatureDetector * Settings::createFeaturesDetector()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!detector)
|
|
||||||
|
Q_ASSERT(detectorGPU!=0 || detector!=0);
|
||||||
|
if(detectorGPU)
|
||||||
{
|
{
|
||||||
printf("ERROR: detector strategy not found !? Using default SURF...\n");
|
return new KeypointDetector(detectorGPU);
|
||||||
detector = new cv::SURF();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new KeypointDetector(detector);
|
||||||
}
|
}
|
||||||
return detector;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::DescriptorExtractor * Settings::createDescriptorsExtractor()
|
DescriptorExtractor * Settings::createDescriptorExtractor()
|
||||||
{
|
{
|
||||||
cv::DescriptorExtractor * extractor = 0;
|
cv::DescriptorExtractor * extractor = 0;
|
||||||
|
GPUFeature2D * extractorGPU = 0;
|
||||||
QString str = getFeature2D_2Descriptor();
|
QString str = getFeature2D_2Descriptor();
|
||||||
QStringList split = str.split(':');
|
QStringList split = str.split(':');
|
||||||
if(split.size()==2)
|
if(split.size()==2)
|
||||||
@ -517,7 +530,7 @@ cv::DescriptorExtractor * Settings::createDescriptorsExtractor()
|
|||||||
{
|
{
|
||||||
if(getFeature2D_ORB_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
if(getFeature2D_ORB_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
||||||
{
|
{
|
||||||
extractor = new GPUORB(
|
extractorGPU = new GPUORB(
|
||||||
getFeature2D_ORB_nFeatures(),
|
getFeature2D_ORB_nFeatures(),
|
||||||
getFeature2D_ORB_scaleFactor(),
|
getFeature2D_ORB_scaleFactor(),
|
||||||
getFeature2D_ORB_nLevels(),
|
getFeature2D_ORB_nLevels(),
|
||||||
@ -562,11 +575,12 @@ cv::DescriptorExtractor * Settings::createDescriptorsExtractor()
|
|||||||
{
|
{
|
||||||
if(getFeature2D_SURF_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
if(getFeature2D_SURF_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
||||||
{
|
{
|
||||||
extractor = new GPUSURF(
|
extractorGPU = new GPUSURF(
|
||||||
getFeature2D_SURF_hessianThreshold(),
|
getFeature2D_SURF_hessianThreshold(),
|
||||||
getFeature2D_SURF_nOctaves(),
|
getFeature2D_SURF_nOctaves(),
|
||||||
getFeature2D_SURF_nOctaveLayers(),
|
getFeature2D_SURF_nOctaveLayers(),
|
||||||
getFeature2D_SURF_extended(),
|
getFeature2D_SURF_extended(),
|
||||||
|
getFeature2D_SURF_keypointsRatio(),
|
||||||
getFeature2D_SURF_upright());
|
getFeature2D_SURF_upright());
|
||||||
if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s (GPU)\n", strategies.at(index).toStdString().c_str());
|
if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s (GPU)\n", strategies.at(index).toStdString().c_str());
|
||||||
}
|
}
|
||||||
@ -609,12 +623,16 @@ cv::DescriptorExtractor * Settings::createDescriptorsExtractor()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!extractor)
|
|
||||||
|
Q_ASSERT(extractorGPU!=0 || extractor!=0);
|
||||||
|
if(extractorGPU)
|
||||||
{
|
{
|
||||||
printf("ERROR: descriptor strategy not found !? Using default SURF...\n");
|
return new DescriptorExtractor(extractorGPU);
|
||||||
extractor = new cv::SURF();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new DescriptorExtractor(extractor);
|
||||||
}
|
}
|
||||||
return extractor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Settings::currentDetectorType()
|
QString Settings::currentDetectorType()
|
||||||
@ -808,3 +826,53 @@ int Settings::getHomographyMethod()
|
|||||||
if(VERBOSE)printf("Settings::getHomographyMethod() method=%d\n", method);
|
if(VERBOSE)printf("Settings::getHomographyMethod() method=%d\n", method);
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeypointDetector::KeypointDetector(cv::FeatureDetector * featureDetector) :
|
||||||
|
featureDetector_(featureDetector),
|
||||||
|
gpuFeature2D_(0)
|
||||||
|
{
|
||||||
|
Q_ASSERT(featureDetector_!=0);
|
||||||
|
}
|
||||||
|
KeypointDetector::KeypointDetector(GPUFeature2D * gpuFeature2D) :
|
||||||
|
featureDetector_(0),
|
||||||
|
gpuFeature2D_(gpuFeature2D)
|
||||||
|
{
|
||||||
|
Q_ASSERT(gpuFeature2D_!=0);
|
||||||
|
}
|
||||||
|
void KeypointDetector::detect(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints)
|
||||||
|
{
|
||||||
|
if(featureDetector_)
|
||||||
|
{
|
||||||
|
featureDetector_->detect(image, keypoints);
|
||||||
|
}
|
||||||
|
else // assume GPU
|
||||||
|
{
|
||||||
|
gpuFeature2D_->detectKeypoints(image, keypoints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorExtractor::DescriptorExtractor(cv::DescriptorExtractor * descriptorExtractor) :
|
||||||
|
descriptorExtractor_(descriptorExtractor),
|
||||||
|
gpuFeature2D_(0)
|
||||||
|
{
|
||||||
|
Q_ASSERT(descriptorExtractor_!=0);
|
||||||
|
}
|
||||||
|
DescriptorExtractor::DescriptorExtractor(GPUFeature2D * gpuFeature2D) :
|
||||||
|
descriptorExtractor_(0),
|
||||||
|
gpuFeature2D_(gpuFeature2D)
|
||||||
|
{
|
||||||
|
Q_ASSERT(gpuFeature2D_!=0);
|
||||||
|
}
|
||||||
|
void DescriptorExtractor::compute(const cv::Mat & image,
|
||||||
|
std::vector<cv::KeyPoint> & keypoints,
|
||||||
|
cv::Mat & descriptors)
|
||||||
|
{
|
||||||
|
if(descriptorExtractor_)
|
||||||
|
{
|
||||||
|
descriptorExtractor_->compute(image, keypoints, descriptors);
|
||||||
|
}
|
||||||
|
else // assume GPU
|
||||||
|
{
|
||||||
|
gpuFeature2D_->computeDescriptors(image, keypoints, descriptors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -10,7 +10,9 @@
|
|||||||
#include <QtCore/QByteArray>
|
#include <QtCore/QByteArray>
|
||||||
#include <opencv2/features2d/features2d.hpp>
|
#include <opencv2/features2d/features2d.hpp>
|
||||||
|
|
||||||
class Camera;
|
class KeypointDetector;
|
||||||
|
class DescriptorExtractor;
|
||||||
|
class GPUFeature2D;
|
||||||
|
|
||||||
typedef QMap<QString, QVariant> ParametersMap; // Key, value
|
typedef QMap<QString, QVariant> ParametersMap; // Key, value
|
||||||
typedef QMap<QString, QString> ParametersType; // Key, type
|
typedef QMap<QString, QString> ParametersType; // Key, type
|
||||||
@ -129,6 +131,7 @@ class Settings
|
|||||||
PARAMETER(Feature2D, SURF_extended, bool, true, "Extended descriptor flag (true - use extended 128-element descriptors; false - use 64-element descriptors).");
|
PARAMETER(Feature2D, SURF_extended, bool, true, "Extended descriptor flag (true - use extended 128-element descriptors; false - use 64-element descriptors).");
|
||||||
PARAMETER(Feature2D, SURF_upright, bool, false, "Up-right or rotated features flag (true - do not compute orientation of features; false - compute orientation).");
|
PARAMETER(Feature2D, SURF_upright, bool, false, "Up-right or rotated features flag (true - do not compute orientation of features; false - compute orientation).");
|
||||||
PARAMETER(Feature2D, SURF_gpu, bool, false, "GPU-SURF: Use GPU version of SURF. This option is enabled only if OpenCV is built with CUDA and GPUs are detected.");
|
PARAMETER(Feature2D, SURF_gpu, bool, false, "GPU-SURF: Use GPU version of SURF. This option is enabled only if OpenCV is built with CUDA and GPUs are detected.");
|
||||||
|
PARAMETER(Feature2D, SURF_keypointsRatio, float, 0.01f, "Used with SURF GPU.");
|
||||||
|
|
||||||
PARAMETER(Feature2D, BRISK_thresh, int, 30, "FAST/AGAST detection threshold score.");
|
PARAMETER(Feature2D, BRISK_thresh, int, 30, "FAST/AGAST detection threshold score.");
|
||||||
PARAMETER(Feature2D, BRISK_octaves, int, 3, "Detection octaves. Use 0 to do single scale.");
|
PARAMETER(Feature2D, BRISK_octaves, int, 3, "Detection octaves. Use 0 to do single scale.");
|
||||||
@ -214,8 +217,8 @@ public:
|
|||||||
static void resetParameter(const QString & key) {if(defaultParameters_.contains(key)) parameters_.insert(key, defaultParameters_.value(key));}
|
static void resetParameter(const QString & key) {if(defaultParameters_.contains(key)) parameters_.insert(key, defaultParameters_.value(key));}
|
||||||
static QVariant getParameter(const QString & key) {return parameters_.value(key, QVariant());}
|
static QVariant getParameter(const QString & key) {return parameters_.value(key, QVariant());}
|
||||||
|
|
||||||
static cv::FeatureDetector * createFeaturesDetector();
|
static KeypointDetector * createKeypointDetector();
|
||||||
static cv::DescriptorExtractor * createDescriptorsExtractor();
|
static DescriptorExtractor * createDescriptorExtractor();
|
||||||
|
|
||||||
static QString currentDescriptorType();
|
static QString currentDescriptorType();
|
||||||
static QString currentDetectorType();
|
static QString currentDetectorType();
|
||||||
@ -238,5 +241,32 @@ private:
|
|||||||
static Settings dummyInit_;
|
static Settings dummyInit_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class KeypointDetector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KeypointDetector(cv::FeatureDetector * featureDetector);
|
||||||
|
KeypointDetector(GPUFeature2D * gpuFeature2D);
|
||||||
|
|
||||||
|
void detect(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints);
|
||||||
|
|
||||||
|
private:
|
||||||
|
cv::FeatureDetector * featureDetector_;
|
||||||
|
GPUFeature2D * gpuFeature2D_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DescriptorExtractor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DescriptorExtractor(cv::DescriptorExtractor * descriptorExtractor);
|
||||||
|
DescriptorExtractor(GPUFeature2D * gpuFeature2D);
|
||||||
|
|
||||||
|
void compute(const cv::Mat & image,
|
||||||
|
std::vector<cv::KeyPoint> & keypoints,
|
||||||
|
cv::Mat & descriptors);
|
||||||
|
|
||||||
|
private:
|
||||||
|
cv::DescriptorExtractor * descriptorExtractor_;
|
||||||
|
GPUFeature2D * gpuFeature2D_;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* SETTINGS_H_ */
|
#endif /* SETTINGS_H_ */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user