Added option to recursively parse subdirectories when loading objects (File->"Load objects...")
This commit is contained in:
parent
34f0262bfd
commit
76b6ff4b7e
@ -70,7 +70,7 @@ public:
|
|||||||
// Those maps have the same size
|
// Those maps have the same size
|
||||||
QMultiMap<int, QTransform> objDetected_;
|
QMultiMap<int, QTransform> objDetected_;
|
||||||
QMultiMap<int, QSize> objDetectedSizes_; // Object ID <width, height> match the number of detected objects
|
QMultiMap<int, QSize> objDetectedSizes_; // Object ID <width, height> match the number of detected objects
|
||||||
QMultiMap<int, QString > objDetectedFilenames_; // Object ID <filename> match the number of detected objects
|
QMultiMap<int, QString > objDetectedFilePaths_; // Object ID <filename> match the number of detected objects
|
||||||
QMultiMap<int, int> objDetectedInliersCount_; // ObjectID <count> match the number of detected objects
|
QMultiMap<int, int> objDetectedInliersCount_; // ObjectID <count> match the number of detected objects
|
||||||
QMultiMap<int, int> objDetectedOutliersCount_; // ObjectID <count> match the number of detected objects
|
QMultiMap<int, int> objDetectedOutliersCount_; // ObjectID <count> match the number of detected objects
|
||||||
QMultiMap<int, QMultiMap<int, int> > objDetectedInliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >, match the number of detected objects
|
QMultiMap<int, QMultiMap<int, int> > objDetectedInliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >, match the number of detected objects
|
||||||
@ -98,7 +98,7 @@ inline QDataStream & operator<<(QDataStream &out, const DetectionInfo & info)
|
|||||||
QMultiMap<int, int>::const_iterator iterInliers = info.objDetectedInliersCount_.constBegin();
|
QMultiMap<int, int>::const_iterator iterInliers = info.objDetectedInliersCount_.constBegin();
|
||||||
QMultiMap<int, int>::const_iterator iterOutliers = info.objDetectedOutliersCount_.constBegin();
|
QMultiMap<int, int>::const_iterator iterOutliers = info.objDetectedOutliersCount_.constBegin();
|
||||||
QMultiMap<int, QSize>::const_iterator iterSizes = info.objDetectedSizes_.constBegin();
|
QMultiMap<int, QSize>::const_iterator iterSizes = info.objDetectedSizes_.constBegin();
|
||||||
QMultiMap<int, QString>::const_iterator iterFilenames = info.objDetectedFilenames_.constBegin();
|
QMultiMap<int, QString>::const_iterator iterFilenames = info.objDetectedFilePaths_.constBegin();
|
||||||
for(QMultiMap<int, QTransform>::const_iterator iter=info.objDetected_.constBegin();
|
for(QMultiMap<int, QTransform>::const_iterator iter=info.objDetected_.constBegin();
|
||||||
iter!=info.objDetected_.constEnd();
|
iter!=info.objDetected_.constEnd();
|
||||||
++iter)
|
++iter)
|
||||||
@ -148,7 +148,7 @@ inline QDataStream & operator>>(QDataStream &in, DetectionInfo & info)
|
|||||||
in >> id >> size >> homography >> filename >> inliers >> outliers;
|
in >> id >> size >> homography >> filename >> inliers >> outliers;
|
||||||
info.objDetected_.insert(id, homography);
|
info.objDetected_.insert(id, homography);
|
||||||
info.objDetectedSizes_.insert(id, size);
|
info.objDetectedSizes_.insert(id, size);
|
||||||
info.objDetectedFilenames_.insert(id, filename);
|
info.objDetectedFilePaths_.insert(id, filename);
|
||||||
info.objDetectedInliersCount_.insert(id, inliers);
|
info.objDetectedInliersCount_.insert(id, inliers);
|
||||||
info.objDetectedOutliersCount_.insert(id, outliers);
|
info.objDetectedOutliersCount_.insert(id, outliers);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -69,9 +69,9 @@ public:
|
|||||||
bool saveSession(const QString & path);
|
bool saveSession(const QString & path);
|
||||||
bool isSessionModified() const {return sessionModified_;}
|
bool isSessionModified() const {return sessionModified_;}
|
||||||
|
|
||||||
int loadObjects(const QString & dirPath); // call updateObjects()
|
int loadObjects(const QString & dirPath, bool recursive = false); // call updateObjects()
|
||||||
const ObjSignature * addObject(const QString & filePath);
|
const ObjSignature * addObject(const QString & filePath);
|
||||||
const ObjSignature * addObject(const cv::Mat & image, int id=0, const QString & filename = QString());
|
const ObjSignature * addObject(const cv::Mat & image, int id=0, const QString & filePath = QString());
|
||||||
bool addObject(ObjSignature * obj); // take ownership when true is returned
|
bool addObject(ObjSignature * obj); // take ownership when true is returned
|
||||||
void removeObject(int id);
|
void removeObject(int id);
|
||||||
void removeAllObjects();
|
void removeAllObjects();
|
||||||
@ -86,7 +86,7 @@ public:
|
|||||||
const Vocabulary * vocabulary() const {return vocabulary_;}
|
const Vocabulary * vocabulary() const {return vocabulary_;}
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void addObjectAndUpdate(const cv::Mat & image, int id=0, const QString & filename = QString());
|
void addObjectAndUpdate(const cv::Mat & image, int id=0, const QString & filePath = QString());
|
||||||
void removeObjectAndUpdate(int id);
|
void removeObjectAndUpdate(int id);
|
||||||
void detect(const cv::Mat & image); // emit objectsFound()
|
void detect(const cv::Mat & image); // emit objectsFound()
|
||||||
|
|
||||||
|
|||||||
@ -115,7 +115,7 @@ Q_SIGNALS:
|
|||||||
private:
|
private:
|
||||||
bool loadSettings(const QString & path);
|
bool loadSettings(const QString & path);
|
||||||
bool saveSettings(const QString & path) const;
|
bool saveSettings(const QString & path) const;
|
||||||
int loadObjects(const QString & dirPath);
|
int loadObjects(const QString & dirPath, bool recursive = false);
|
||||||
int saveObjects(const QString & dirPath);
|
int saveObjects(const QString & dirPath);
|
||||||
void setupTCPServer();
|
void setupTCPServer();
|
||||||
int addObjectFromFile(const QString & filePath);
|
int addObjectFromFile(const QString & filePath);
|
||||||
|
|||||||
@ -37,6 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <QtCore/QFileInfo>
|
#include <QtCore/QFileInfo>
|
||||||
#include <QtCore/QStringList>
|
#include <QtCore/QStringList>
|
||||||
#include <QtCore/QTime>
|
#include <QtCore/QTime>
|
||||||
|
#include <QtCore/QDir>
|
||||||
#include <QtGui/QGraphicsRectItem>
|
#include <QtGui/QGraphicsRectItem>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@ -140,25 +141,49 @@ bool FindObject::saveSession(const QString & path)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FindObject::loadObjects(const QString & dirPath)
|
int FindObject::loadObjects(const QString & dirPath, bool recursive)
|
||||||
{
|
{
|
||||||
int loadedObjects = 0;
|
int loadedObjects = 0;
|
||||||
QString formats = Settings::getGeneral_imageFormats().remove('*').remove('.');
|
QString formats = Settings::getGeneral_imageFormats().remove('*').remove('.');
|
||||||
UDirectory dir(dirPath.toStdString(), formats.toStdString());
|
|
||||||
|
QStringList paths;
|
||||||
|
paths.append(dirPath);
|
||||||
|
|
||||||
|
while(paths.size())
|
||||||
|
{
|
||||||
|
QString currentDir = paths.front();
|
||||||
|
UDirectory dir(currentDir.toStdString(), formats.toStdString());
|
||||||
if(dir.isValid())
|
if(dir.isValid())
|
||||||
{
|
{
|
||||||
const std::list<std::string> & names = dir.getFileNames(); // sorted in natural order
|
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)
|
for(std::list<std::string>::const_iterator iter=names.begin(); iter!=names.end(); ++iter)
|
||||||
{
|
{
|
||||||
this->addObject((dirPath.toStdString()+dir.separator()+*iter).c_str());
|
if(this->addObject((currentDir.toStdString()+dir.separator()+*iter).c_str()))
|
||||||
|
{
|
||||||
|
++loadedObjects;
|
||||||
}
|
}
|
||||||
if(names.size())
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
paths.pop_front();
|
||||||
|
|
||||||
|
if(recursive)
|
||||||
|
{
|
||||||
|
QDir d(currentDir);
|
||||||
|
QStringList subDirs = d.entryList(QDir::AllDirs|QDir::NoDotAndDotDot, QDir::Name);
|
||||||
|
for(int i=subDirs.size()-1; i>=0; --i)
|
||||||
|
{
|
||||||
|
paths.prepend(currentDir+QDir::separator()+subDirs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(loadedObjects)
|
||||||
{
|
{
|
||||||
this->updateObjects();
|
this->updateObjects();
|
||||||
this->updateVocabulary();
|
this->updateVocabulary();
|
||||||
}
|
}
|
||||||
loadedObjects = (int)names.size();
|
|
||||||
}
|
|
||||||
return loadedObjects;
|
return loadedObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,16 +215,16 @@ const ObjSignature * FindObject::addObject(const QString & filePath)
|
|||||||
id = 0;
|
id = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this->addObject(img, id, file.fileName());
|
return this->addObject(img, id, filePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ObjSignature * FindObject::addObject(const cv::Mat & image, int id, const QString & filename)
|
const ObjSignature * FindObject::addObject(const cv::Mat & image, int id, const QString & filePath)
|
||||||
{
|
{
|
||||||
UASSERT(id >= 0);
|
UASSERT(id >= 0);
|
||||||
ObjSignature * s = new ObjSignature(id, image, filename);
|
ObjSignature * s = new ObjSignature(id, image, filePath);
|
||||||
if(!this->addObject(s))
|
if(!this->addObject(s))
|
||||||
{
|
{
|
||||||
delete s;
|
delete s;
|
||||||
@ -245,9 +270,9 @@ void FindObject::removeAllObjects()
|
|||||||
clearVocabulary();
|
clearVocabulary();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FindObject::addObjectAndUpdate(const cv::Mat & image, int id, const QString & filename)
|
void FindObject::addObjectAndUpdate(const cv::Mat & image, int id, const QString & filePath)
|
||||||
{
|
{
|
||||||
const ObjSignature * s = this->addObject(image, id, filename);
|
const ObjSignature * s = this->addObject(image, id, filePath);
|
||||||
if(s)
|
if(s)
|
||||||
{
|
{
|
||||||
QList<int> ids;
|
QList<int> ids;
|
||||||
@ -1449,7 +1474,7 @@ bool FindObject::detect(const cv::Mat & image, find_object::DetectionInfo & info
|
|||||||
info.objDetectedOutliers_.insert(id, threads[j]->getOutliers());
|
info.objDetectedOutliers_.insert(id, threads[j]->getOutliers());
|
||||||
info.objDetectedInliersCount_.insert(id, threads[j]->getInliers().size());
|
info.objDetectedInliersCount_.insert(id, threads[j]->getInliers().size());
|
||||||
info.objDetectedOutliersCount_.insert(id, threads[j]->getOutliers().size());
|
info.objDetectedOutliersCount_.insert(id, threads[j]->getOutliers().size());
|
||||||
info.objDetectedFilenames_.insert(id, objects_.value(id)->filename());
|
info.objDetectedFilePaths_.insert(id, objects_.value(id)->filePath());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
#include <QtCore/QTextStream>
|
#include <QtCore/QTextStream>
|
||||||
|
#include <QtCore/QFileInfo>
|
||||||
|
|
||||||
#include "json/json.h"
|
#include "json/json.h"
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ void JsonWriter::write(const DetectionInfo & info, const QString & path)
|
|||||||
QMultiMap<int, int>::const_iterator iterInliers = info.objDetectedInliersCount_.constBegin();
|
QMultiMap<int, int>::const_iterator iterInliers = info.objDetectedInliersCount_.constBegin();
|
||||||
QMultiMap<int, int>::const_iterator iterOutliers = info.objDetectedOutliersCount_.constBegin();
|
QMultiMap<int, int>::const_iterator iterOutliers = info.objDetectedOutliersCount_.constBegin();
|
||||||
QMultiMap<int, QSize>::const_iterator iterSizes = info.objDetectedSizes_.constBegin();
|
QMultiMap<int, QSize>::const_iterator iterSizes = info.objDetectedSizes_.constBegin();
|
||||||
QMultiMap<int, QString>::const_iterator iterFilenames = info.objDetectedFilenames_.constBegin();
|
QMultiMap<int, QString>::const_iterator iterFilePaths = info.objDetectedFilePaths_.constBegin();
|
||||||
for(QMultiMap<int, QTransform>::const_iterator iter = info.objDetected_.constBegin(); iter!= info.objDetected_.end();)
|
for(QMultiMap<int, QTransform>::const_iterator iter = info.objDetected_.constBegin(); iter!= info.objDetected_.end();)
|
||||||
{
|
{
|
||||||
char index = 'a';
|
char index = 'a';
|
||||||
@ -73,13 +74,20 @@ void JsonWriter::write(const DetectionInfo & info, const QString & path)
|
|||||||
root[name.toStdString()]["homography"] = homography;
|
root[name.toStdString()]["homography"] = homography;
|
||||||
root[name.toStdString()]["inliers"] = iterInliers.value();
|
root[name.toStdString()]["inliers"] = iterInliers.value();
|
||||||
root[name.toStdString()]["outliers"] = iterOutliers.value();
|
root[name.toStdString()]["outliers"] = iterOutliers.value();
|
||||||
root[name.toStdString()]["filename"] = iterFilenames.value().toStdString();
|
root[name.toStdString()]["filepath"] = iterFilePaths.value().toStdString();
|
||||||
|
QString filename;
|
||||||
|
if(!iterFilePaths.value().isEmpty())
|
||||||
|
{
|
||||||
|
QFileInfo file(iterFilePaths.value());
|
||||||
|
filename=file.fileName();
|
||||||
|
}
|
||||||
|
root[name.toStdString()]["filename"] = filename.toStdString();
|
||||||
|
|
||||||
++iter;
|
++iter;
|
||||||
++iterInliers;
|
++iterInliers;
|
||||||
++iterOutliers;
|
++iterOutliers;
|
||||||
++iterSizes;
|
++iterSizes;
|
||||||
++iterFilenames;
|
++iterFilePaths;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
root["objects"] = detections;
|
root["objects"] = detections;
|
||||||
|
|||||||
@ -460,27 +460,49 @@ bool MainWindow::saveSettings(const QString & path) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MainWindow::loadObjects(const QString & dirPath)
|
int MainWindow::loadObjects(const QString & dirPath, bool recursive)
|
||||||
{
|
{
|
||||||
QList<int> loadedObjects;
|
QList<int> loadedObjects;
|
||||||
QString formats = Settings::getGeneral_imageFormats().remove('*').remove('.');
|
QString formats = Settings::getGeneral_imageFormats().remove('*').remove('.');
|
||||||
UDirectory dir(dirPath.toStdString(), formats.toStdString());
|
|
||||||
|
QStringList paths;
|
||||||
|
paths.append(dirPath);
|
||||||
|
|
||||||
|
while(paths.size())
|
||||||
|
{
|
||||||
|
QString currentDir = paths.front();
|
||||||
|
UDirectory dir(currentDir.toStdString(), formats.toStdString());
|
||||||
if(dir.isValid())
|
if(dir.isValid())
|
||||||
{
|
{
|
||||||
const std::list<std::string> & names = dir.getFileNames(); // sorted in natural order
|
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)
|
for(std::list<std::string>::const_iterator iter=names.begin(); iter!=names.end(); ++iter)
|
||||||
{
|
{
|
||||||
int id = this->addObjectFromFile((dirPath.toStdString()+dir.separator()+*iter).c_str());
|
int id = this->addObjectFromFile((currentDir.toStdString()+dir.separator()+*iter).c_str());
|
||||||
if(id >= 0)
|
if(id >= 0)
|
||||||
{
|
{
|
||||||
loadedObjects.push_back(id);
|
loadedObjects.push_back(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
paths.pop_front();
|
||||||
|
|
||||||
|
if(recursive)
|
||||||
|
{
|
||||||
|
QDir d(currentDir);
|
||||||
|
QStringList subDirs = d.entryList(QDir::AllDirs|QDir::NoDotAndDotDot, QDir::Name);
|
||||||
|
for(int i=subDirs.size()-1; i>=0; --i)
|
||||||
|
{
|
||||||
|
paths.prepend(currentDir + QDir::separator() + subDirs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(loadedObjects.size())
|
if(loadedObjects.size())
|
||||||
{
|
{
|
||||||
this->updateObjects(loadedObjects);
|
this->updateObjects(loadedObjects);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return loadedObjects.size();
|
return loadedObjects.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,7 +533,20 @@ void MainWindow::loadObjects()
|
|||||||
QString dirPath = QFileDialog::getExistingDirectory(this, tr("Loading objects... Select a directory."), Settings::workingDirectory());
|
QString dirPath = QFileDialog::getExistingDirectory(this, tr("Loading objects... Select a directory."), Settings::workingDirectory());
|
||||||
if(!dirPath.isEmpty())
|
if(!dirPath.isEmpty())
|
||||||
{
|
{
|
||||||
int count = loadObjects(dirPath);
|
QDir d(dirPath);
|
||||||
|
bool recursive = false;
|
||||||
|
if(d.entryList(QDir::AllDirs).size())
|
||||||
|
{
|
||||||
|
QMessageBox::StandardButton b = QMessageBox::question(
|
||||||
|
this,
|
||||||
|
tr("Loading objects..."),
|
||||||
|
tr("The current directory contains subdirectories. Load objects recursively?"),
|
||||||
|
QMessageBox::Yes|QMessageBox::No,
|
||||||
|
QMessageBox::No);
|
||||||
|
recursive = b == QMessageBox::Yes;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = loadObjects(dirPath, recursive);
|
||||||
if(count)
|
if(count)
|
||||||
{
|
{
|
||||||
QMessageBox::information(this, tr("Loading..."), tr("%1 objects loaded from \"%2\".").arg(count).arg(dirPath));
|
QMessageBox::information(this, tr("Loading..."), tr("%1 objects loaded from \"%2\".").arg(count).arg(dirPath));
|
||||||
|
|||||||
@ -42,10 +42,10 @@ public:
|
|||||||
ObjSignature() :
|
ObjSignature() :
|
||||||
id_(-1)
|
id_(-1)
|
||||||
{}
|
{}
|
||||||
ObjSignature(int id, const cv::Mat & image, const QString & filename) :
|
ObjSignature(int id, const cv::Mat & image, const QString & filePath) :
|
||||||
id_(id),
|
id_(id),
|
||||||
image_(image),
|
image_(image),
|
||||||
filename_(filename)
|
filePath_(filePath)
|
||||||
{}
|
{}
|
||||||
virtual ~ObjSignature() {}
|
virtual ~ObjSignature() {}
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ public:
|
|||||||
QRect rect() const {return QRect(0,0,image_.cols, image_.rows);}
|
QRect rect() const {return QRect(0,0,image_.cols, image_.rows);}
|
||||||
|
|
||||||
int id() const {return id_;}
|
int id() const {return id_;}
|
||||||
const QString & filename() const {return filename_;}
|
const QString & filePath() const {return filePath_;}
|
||||||
const cv::Mat & image() const {return image_;}
|
const cv::Mat & image() const {return image_;}
|
||||||
const std::vector<cv::KeyPoint> & keypoints() const {return keypoints_;}
|
const std::vector<cv::KeyPoint> & keypoints() const {return keypoints_;}
|
||||||
const cv::Mat & descriptors() const {return descriptors_;}
|
const cv::Mat & descriptors() const {return descriptors_;}
|
||||||
@ -69,7 +69,7 @@ public:
|
|||||||
void save(QDataStream & streamPtr) const
|
void save(QDataStream & streamPtr) const
|
||||||
{
|
{
|
||||||
streamPtr << id_;
|
streamPtr << id_;
|
||||||
streamPtr << filename_;
|
streamPtr << filePath_;
|
||||||
streamPtr << (int)keypoints_.size();
|
streamPtr << (int)keypoints_.size();
|
||||||
for(unsigned int j=0; j<keypoints_.size(); ++j)
|
for(unsigned int j=0; j<keypoints_.size(); ++j)
|
||||||
{
|
{
|
||||||
@ -99,7 +99,7 @@ public:
|
|||||||
void load(QDataStream & streamPtr)
|
void load(QDataStream & streamPtr)
|
||||||
{
|
{
|
||||||
int nKpts;
|
int nKpts;
|
||||||
streamPtr >> id_ >> filename_ >> nKpts;
|
streamPtr >> id_ >> filePath_ >> nKpts;
|
||||||
keypoints_.resize(nKpts);
|
keypoints_.resize(nKpts);
|
||||||
for(int i=0;i<nKpts;++i)
|
for(int i=0;i<nKpts;++i)
|
||||||
{
|
{
|
||||||
@ -132,7 +132,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
int id_;
|
int id_;
|
||||||
cv::Mat image_;
|
cv::Mat image_;
|
||||||
QString filename_;
|
QString filePath_;
|
||||||
std::vector<cv::KeyPoint> keypoints_;
|
std::vector<cv::KeyPoint> keypoints_;
|
||||||
cv::Mat descriptors_;
|
cv::Mat descriptors_;
|
||||||
QMultiMap<int, int> words_; // <word id, keypoint indexes>
|
QMultiMap<int, int> words_; // <word id, keypoint indexes>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user