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
|
||||
QMultiMap<int, QTransform> objDetected_;
|
||||
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> 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
|
||||
@ -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 iterOutliers = info.objDetectedOutliersCount_.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();
|
||||
iter!=info.objDetected_.constEnd();
|
||||
++iter)
|
||||
@ -148,7 +148,7 @@ inline QDataStream & operator>>(QDataStream &in, DetectionInfo & info)
|
||||
in >> id >> size >> homography >> filename >> inliers >> outliers;
|
||||
info.objDetected_.insert(id, homography);
|
||||
info.objDetectedSizes_.insert(id, size);
|
||||
info.objDetectedFilenames_.insert(id, filename);
|
||||
info.objDetectedFilePaths_.insert(id, filename);
|
||||
info.objDetectedInliersCount_.insert(id, inliers);
|
||||
info.objDetectedOutliersCount_.insert(id, outliers);
|
||||
}
|
||||
|
||||
@ -69,9 +69,9 @@ public:
|
||||
bool saveSession(const QString & path);
|
||||
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 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
|
||||
void removeObject(int id);
|
||||
void removeAllObjects();
|
||||
@ -86,7 +86,7 @@ public:
|
||||
const Vocabulary * vocabulary() const {return vocabulary_;}
|
||||
|
||||
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 detect(const cv::Mat & image); // emit objectsFound()
|
||||
|
||||
|
||||
@ -115,7 +115,7 @@ Q_SIGNALS:
|
||||
private:
|
||||
bool loadSettings(const QString & path);
|
||||
bool saveSettings(const QString & path) const;
|
||||
int loadObjects(const QString & dirPath);
|
||||
int loadObjects(const QString & dirPath, bool recursive = false);
|
||||
int saveObjects(const QString & dirPath);
|
||||
void setupTCPServer();
|
||||
int addObjectFromFile(const QString & filePath);
|
||||
|
||||
@ -37,6 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QTime>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtGui/QGraphicsRectItem>
|
||||
#include <stdio.h>
|
||||
|
||||
@ -140,25 +141,49 @@ bool FindObject::saveSession(const QString & path)
|
||||
return false;
|
||||
}
|
||||
|
||||
int FindObject::loadObjects(const QString & dirPath)
|
||||
int FindObject::loadObjects(const QString & dirPath, bool recursive)
|
||||
{
|
||||
int loadedObjects = 0;
|
||||
QString formats = Settings::getGeneral_imageFormats().remove('*').remove('.');
|
||||
UDirectory dir(dirPath.toStdString(), formats.toStdString());
|
||||
if(dir.isValid())
|
||||
|
||||
QStringList paths;
|
||||
paths.append(dirPath);
|
||||
|
||||
while(paths.size())
|
||||
{
|
||||
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)
|
||||
QString currentDir = paths.front();
|
||||
UDirectory dir(currentDir.toStdString(), formats.toStdString());
|
||||
if(dir.isValid())
|
||||
{
|
||||
this->addObject((dirPath.toStdString()+dir.separator()+*iter).c_str());
|
||||
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()))
|
||||
{
|
||||
++loadedObjects;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(names.size())
|
||||
|
||||
paths.pop_front();
|
||||
|
||||
if(recursive)
|
||||
{
|
||||
this->updateObjects();
|
||||
this->updateVocabulary();
|
||||
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]);
|
||||
}
|
||||
}
|
||||
loadedObjects = (int)names.size();
|
||||
}
|
||||
|
||||
if(loadedObjects)
|
||||
{
|
||||
this->updateObjects();
|
||||
this->updateVocabulary();
|
||||
}
|
||||
|
||||
return loadedObjects;
|
||||
}
|
||||
|
||||
@ -190,16 +215,16 @@ const ObjSignature * FindObject::addObject(const QString & filePath)
|
||||
id = 0;
|
||||
}
|
||||
}
|
||||
return this->addObject(img, id, file.fileName());
|
||||
return this->addObject(img, id, filePath);
|
||||
}
|
||||
}
|
||||
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);
|
||||
ObjSignature * s = new ObjSignature(id, image, filename);
|
||||
ObjSignature * s = new ObjSignature(id, image, filePath);
|
||||
if(!this->addObject(s))
|
||||
{
|
||||
delete s;
|
||||
@ -245,9 +270,9 @@ void FindObject::removeAllObjects()
|
||||
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)
|
||||
{
|
||||
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.objDetectedInliersCount_.insert(id, threads[j]->getInliers().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
|
||||
{
|
||||
|
||||
@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QFileInfo>
|
||||
|
||||
#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 iterOutliers = info.objDetectedOutliersCount_.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();)
|
||||
{
|
||||
char index = 'a';
|
||||
@ -73,13 +74,20 @@ void JsonWriter::write(const DetectionInfo & info, const QString & path)
|
||||
root[name.toStdString()]["homography"] = homography;
|
||||
root[name.toStdString()]["inliers"] = iterInliers.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;
|
||||
++iterInliers;
|
||||
++iterOutliers;
|
||||
++iterSizes;
|
||||
++iterFilenames;
|
||||
++iterFilePaths;
|
||||
}
|
||||
}
|
||||
root["objects"] = detections;
|
||||
|
||||
@ -460,27 +460,49 @@ bool MainWindow::saveSettings(const QString & path) const
|
||||
return false;
|
||||
}
|
||||
|
||||
int MainWindow::loadObjects(const QString & dirPath)
|
||||
int MainWindow::loadObjects(const QString & dirPath, bool recursive)
|
||||
{
|
||||
QList<int> loadedObjects;
|
||||
QString formats = Settings::getGeneral_imageFormats().remove('*').remove('.');
|
||||
UDirectory dir(dirPath.toStdString(), formats.toStdString());
|
||||
if(dir.isValid())
|
||||
|
||||
QStringList paths;
|
||||
paths.append(dirPath);
|
||||
|
||||
while(paths.size())
|
||||
{
|
||||
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)
|
||||
QString currentDir = paths.front();
|
||||
UDirectory dir(currentDir.toStdString(), formats.toStdString());
|
||||
if(dir.isValid())
|
||||
{
|
||||
int id = this->addObjectFromFile((dirPath.toStdString()+dir.separator()+*iter).c_str());
|
||||
if(id >= 0)
|
||||
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)
|
||||
{
|
||||
loadedObjects.push_back(id);
|
||||
int id = this->addObjectFromFile((currentDir.toStdString()+dir.separator()+*iter).c_str());
|
||||
if(id >= 0)
|
||||
{
|
||||
loadedObjects.push_back(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(loadedObjects.size())
|
||||
|
||||
paths.pop_front();
|
||||
|
||||
if(recursive)
|
||||
{
|
||||
this->updateObjects(loadedObjects);
|
||||
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())
|
||||
{
|
||||
this->updateObjects(loadedObjects);
|
||||
}
|
||||
|
||||
return loadedObjects.size();
|
||||
}
|
||||
|
||||
@ -511,7 +533,20 @@ void MainWindow::loadObjects()
|
||||
QString dirPath = QFileDialog::getExistingDirectory(this, tr("Loading objects... Select a directory."), Settings::workingDirectory());
|
||||
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)
|
||||
{
|
||||
QMessageBox::information(this, tr("Loading..."), tr("%1 objects loaded from \"%2\".").arg(count).arg(dirPath));
|
||||
|
||||
@ -42,10 +42,10 @@ public:
|
||||
ObjSignature() :
|
||||
id_(-1)
|
||||
{}
|
||||
ObjSignature(int id, const cv::Mat & image, const QString & filename) :
|
||||
ObjSignature(int id, const cv::Mat & image, const QString & filePath) :
|
||||
id_(id),
|
||||
image_(image),
|
||||
filename_(filename)
|
||||
filePath_(filePath)
|
||||
{}
|
||||
virtual ~ObjSignature() {}
|
||||
|
||||
@ -60,7 +60,7 @@ public:
|
||||
QRect rect() const {return QRect(0,0,image_.cols, image_.rows);}
|
||||
|
||||
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 std::vector<cv::KeyPoint> & keypoints() const {return keypoints_;}
|
||||
const cv::Mat & descriptors() const {return descriptors_;}
|
||||
@ -69,7 +69,7 @@ public:
|
||||
void save(QDataStream & streamPtr) const
|
||||
{
|
||||
streamPtr << id_;
|
||||
streamPtr << filename_;
|
||||
streamPtr << filePath_;
|
||||
streamPtr << (int)keypoints_.size();
|
||||
for(unsigned int j=0; j<keypoints_.size(); ++j)
|
||||
{
|
||||
@ -99,7 +99,7 @@ public:
|
||||
void load(QDataStream & streamPtr)
|
||||
{
|
||||
int nKpts;
|
||||
streamPtr >> id_ >> filename_ >> nKpts;
|
||||
streamPtr >> id_ >> filePath_ >> nKpts;
|
||||
keypoints_.resize(nKpts);
|
||||
for(int i=0;i<nKpts;++i)
|
||||
{
|
||||
@ -132,7 +132,7 @@ public:
|
||||
private:
|
||||
int id_;
|
||||
cv::Mat image_;
|
||||
QString filename_;
|
||||
QString filePath_;
|
||||
std::vector<cv::KeyPoint> keypoints_;
|
||||
cv::Mat descriptors_;
|
||||
QMultiMap<int, int> words_; // <word id, keypoint indexes>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user