Added DetectionInfo object for easier serialization/deserialization of the detection results.

Added filename property in json files
Added JsonWritter class for convenience

git-svn-id: http://find-object.googlecode.com/svn/trunk/find_object@369 620bd6b2-0a58-f614-fd9a-1bd335dccda9
This commit is contained in:
matlabbe
2014-08-04 01:33:52 +00:00
parent cd8368f0de
commit e6fcc961b8
24 changed files with 486 additions and 426 deletions
+1 -1
View File
@@ -332,7 +332,7 @@ void AddObjectDialog::setState(int state)
delete objSignature_;
objSignature_ = 0;
}
objSignature_ = new ObjSignature(0, imgRoi.clone());
objSignature_ = new ObjSignature(0, imgRoi.clone(), "");
objSignature_->setData(keypoints, descriptors, Settings::currentDetectorType(), Settings::currentDescriptorType());
objWidget_ = new ObjWidget(0, keypoints, cvtCvMat2QImage(imgRoi.clone()));
+13 -3
View File
@@ -36,9 +36,6 @@ QT4_WRAP_UI(moc_uis ${uis})
QT4_WRAP_CPP(moc_srcs ${headers_ui})
### Qt Gui stuff end###
SET(SRC_FILES
./MainWindow.cpp
./AddObjectDialog.cpp
@@ -54,6 +51,7 @@ SET(SRC_FILES
./AboutDialog.cpp
./TcpServer.cpp
./Vocabulary.cpp
./JsonWriter.cpp
./utilite/ULogger.cpp
./utilite/UPlot.cpp
./utilite/UDirectory.cpp
@@ -79,6 +77,18 @@ SET(LIBRARIES
${OpenCV_LIBS}
)
IF(JSONCPP_FOUND)
SET(INCLUDE_DIRS
${INCLUDE_DIRS}
${JSONCPP_INCLUDE_DIRS}
)
SET(LIBRARIES
${LIBRARIES}
${JSONCPP_LIBRARIES}
)
ADD_DEFINITIONS("-DWITH_JSONCPP")
ENDIF(JSONCPP_FOUND)
#include files
INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
+70 -77
View File
@@ -23,10 +23,9 @@ FindObject::FindObject(QObject * parent) :
QObject(parent),
vocabulary_(new Vocabulary()),
detector_(Settings::createKeypointDetector()),
extractor_(Settings::createDescriptorExtractor()),
minMatchedDistance_(-1),
maxMatchedDistance_(-1)
extractor_(Settings::createDescriptorExtractor())
{
qRegisterMetaType<DetectionInfo>("DetectionInfo");
Q_ASSERT(detector_ != 0 && extractor_ != 0);
}
@@ -87,16 +86,16 @@ const ObjSignature * FindObject::addObject(const QString & filePath)
id = 0;
}
}
return this->addObject(img, id);
return this->addObject(img, id, file.fileName());
}
}
return 0;
}
const ObjSignature * FindObject::addObject(const cv::Mat & image, int id)
const ObjSignature * FindObject::addObject(const cv::Mat & image, int id, const QString & filename)
{
Q_ASSERT(id >= 0);
ObjSignature * s = new ObjSignature(id, image);
ObjSignature * s = new ObjSignature(id, image, filename);
if(!this->addObject(s))
{
delete s;
@@ -596,25 +595,25 @@ void FindObject::detect(const cv::Mat & image)
{
QTime time;
time.start();
QMultiMap<int,QPair<QRect,QTransform> > objects;
this->detect(image, objects);
if(objects.size() > 0 || Settings::getGeneral_sendNoObjDetectedEvents())
DetectionInfo info;
this->detect(image, info);
if(info.objDetected_.size() > 0 || Settings::getGeneral_sendNoObjDetectedEvents())
{
Q_EMIT objectsFound(objects);
Q_EMIT objectsFound(info);
}
if(objects.size() > 1)
if(info.objDetected_.size() > 1)
{
UINFO("(%s) %d objects detected! (%d ms)",
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(),
(int)objects.size(),
(int)info.objDetected_.size(),
time.elapsed());
}
else if(objects.size() == 1)
else if(info.objDetected_.size() == 1)
{
UINFO("(%s) Object %d detected! (%d ms)",
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(),
(int)objects.begin().key(),
(int)info.objDetected_.begin().key(),
time.elapsed());
}
else if(Settings::getGeneral_sendNoObjDetectedEvents())
@@ -625,22 +624,13 @@ void FindObject::detect(const cv::Mat & image)
}
}
bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransform> > & objectsDetected)
bool FindObject::detect(const cv::Mat & image, DetectionInfo & info)
{
QTime totalTime;
totalTime.start();
// reset statistics
objectsDetected_.clear();
timeStamps_.clear();
sceneKeypoints_.clear();
sceneDescriptors_ = cv::Mat();
sceneWords_.clear();
matches_.clear();
inliers_.clear();
outliers_.clear();
minMatchedDistance_ = -1.0f;
maxMatchedDistance_ = -1.0f;
info = DetectionInfo();
bool success = false;
if(!image.empty())
@@ -660,36 +650,36 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
time.start();
// EXTRACT KEYPOINTS
detector_->detect(grayscaleImg, sceneKeypoints_);
timeStamps_.insert(kTimeKeypointDetection, time.restart());
detector_->detect(grayscaleImg, info.sceneKeypoints_);
info.timeStamps_.insert(DetectionInfo::kTimeKeypointDetection, time.restart());
bool emptyScene = sceneKeypoints_.size() == 0;
if(sceneKeypoints_.size())
bool emptyScene = info.sceneKeypoints_.size() == 0;
if(info.sceneKeypoints_.size())
{
int maxFeatures = Settings::getFeature2D_3MaxFeatures();
if(maxFeatures > 0 && (int)sceneKeypoints_.size() > maxFeatures)
if(maxFeatures > 0 && (int)info.sceneKeypoints_.size() > maxFeatures)
{
sceneKeypoints_ = limitKeypoints(sceneKeypoints_, maxFeatures);
info.sceneKeypoints_ = limitKeypoints(info.sceneKeypoints_, maxFeatures);
}
// EXTRACT DESCRIPTORS
extractor_->compute(grayscaleImg, sceneKeypoints_, sceneDescriptors_);
if((int)sceneKeypoints_.size() != sceneDescriptors_.rows)
extractor_->compute(grayscaleImg, info.sceneKeypoints_, info.sceneDescriptors_);
if((int)info.sceneKeypoints_.size() != info.sceneDescriptors_.rows)
{
UERROR("kpt=%d != descriptors=%d", (int)sceneKeypoints_.size(), sceneDescriptors_.rows);
UERROR("kpt=%d != descriptors=%d", (int)info.sceneKeypoints_.size(), info.sceneDescriptors_.rows);
}
}
timeStamps_.insert(kTimeDescriptorExtraction, time.restart());
info.timeStamps_.insert(DetectionInfo::kTimeDescriptorExtraction, time.restart());
bool consistentNNData = (vocabulary_->size()!=0 && vocabulary_->wordToObjects().begin().value()!=-1 && Settings::getGeneral_invertedSearch()) ||
((vocabulary_->size()==0 || vocabulary_->wordToObjects().begin().value()==-1) && !Settings::getGeneral_invertedSearch());
// COMPARE
if(!objectsDescriptors_.empty() &&
sceneKeypoints_.size() &&
info.sceneKeypoints_.size() &&
consistentNNData &&
objectsDescriptors_.begin().value().cols == sceneDescriptors_.cols &&
objectsDescriptors_.begin().value().type() == sceneDescriptors_.type()) // binary descriptor issue, if the dataTree is not yet updated with modified settings
objectsDescriptors_.begin().value().cols == info.sceneDescriptors_.cols &&
objectsDescriptors_.begin().value().type() == info.sceneDescriptors_.type()) // binary descriptor issue, if the dataTree is not yet updated with modified settings
{
success = true;
@@ -699,17 +689,17 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
{
// CREATE INDEX for the scene
vocabulary_->clear();
words = vocabulary_->addWords(sceneDescriptors_, -1, Settings::getGeneral_vocabularyIncremental());
words = vocabulary_->addWords(info.sceneDescriptors_, -1, Settings::getGeneral_vocabularyIncremental());
if(!Settings::getGeneral_vocabularyIncremental())
{
vocabulary_->update();
}
timeStamps_.insert(kTimeIndexing, time.restart());
info.timeStamps_.insert(DetectionInfo::kTimeIndexing, time.restart());
}
for(QMap<int, ObjSignature*>::iterator iter=objects_.begin(); iter!=objects_.end(); ++iter)
{
matches_.insert(iter.key(), QMultiMap<int, int>());
info.matches_.insert(iter.key(), QMultiMap<int, int>());
}
if(Settings::getGeneral_invertedSearch() || Settings::getGeneral_threads() == 1)
@@ -728,9 +718,9 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
else
{
//match scene to objects
results = cv::Mat(sceneDescriptors_.rows, k, CV_32SC1); // results index
dists = cv::Mat(sceneDescriptors_.rows, k, CV_32FC1); // Distance results are CV_32FC1
vocabulary_->search(sceneDescriptors_, results, dists, k);
results = cv::Mat(info.sceneDescriptors_.rows, k, CV_32SC1); // results index
dists = cv::Mat(info.sceneDescriptors_.rows, k, CV_32FC1); // Distance results are CV_32FC1
vocabulary_->search(info.sceneDescriptors_, results, dists, k);
}
// PROCESS RESULTS
@@ -761,13 +751,13 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
{
matched = true; // no criterion, match to the nearest descriptor
}
if(minMatchedDistance_ == -1 || minMatchedDistance_ > dists.at<float>(i,0))
if(info.minMatchedDistance_ == -1 || info.minMatchedDistance_ > dists.at<float>(i,0))
{
minMatchedDistance_ = dists.at<float>(i,0);
info.minMatchedDistance_ = dists.at<float>(i,0);
}
if(maxMatchedDistance_ == -1 || maxMatchedDistance_ < dists.at<float>(i,0))
if(info.maxMatchedDistance_ == -1 || info.maxMatchedDistance_ < dists.at<float>(i,0))
{
maxMatchedDistance_ = dists.at<float>(i,0);
info.maxMatchedDistance_ = dists.at<float>(i,0);
}
if(matched)
@@ -781,7 +771,7 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
// just add unique matches
if(vocabulary_->wordToObjects().count(wordId, objIds[j]) == 1)
{
matches_.find(objIds[j]).value().insert(objects_.value(objIds[j])->words().value(wordId), i);
info.matches_.find(objIds[j]).value().insert(objects_.value(objIds[j])->words().value(wordId), i);
}
}
}
@@ -795,7 +785,7 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
int wordId = results.at<int>(i,0);
if(words.count(wordId) == 1)
{
matches_.find(objectId).value().insert(objectDescriptorIndex, words.value(wordId));
info.matches_.find(objectId).value().insert(objectDescriptorIndex, words.value(wordId));
}
}
}
@@ -825,15 +815,15 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
for(int k=0; k<threads.size(); ++k)
{
threads[k]->wait();
matches_[threads[k]->getObjectId()] = threads[k]->getMatches();
info.matches_[threads[k]->getObjectId()] = threads[k]->getMatches();
if(minMatchedDistance_ == -1 || minMatchedDistance_ > threads[k]->getMinMatchedDistance())
if(info.minMatchedDistance_ == -1 || info.minMatchedDistance_ > threads[k]->getMinMatchedDistance())
{
minMatchedDistance_ = threads[k]->getMinMatchedDistance();
info.minMatchedDistance_ = threads[k]->getMinMatchedDistance();
}
if(maxMatchedDistance_ == -1 || maxMatchedDistance_ < threads[k]->getMaxMatchedDistance())
if(info.maxMatchedDistance_ == -1 || info.maxMatchedDistance_ < threads[k]->getMaxMatchedDistance())
{
maxMatchedDistance_ = threads[k]->getMaxMatchedDistance();
info.maxMatchedDistance_ = threads[k]->getMaxMatchedDistance();
}
delete threads[k];
}
@@ -841,7 +831,7 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
}
}
timeStamps_.insert(kTimeMatching, time.restart());
info.timeStamps_.insert(DetectionInfo::kTimeMatching, time.restart());
// Homographies
if(Settings::getHomography_homographyComputed())
@@ -850,10 +840,10 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
int threadCounts = Settings::getGeneral_threads();
if(threadCounts == 0)
{
threadCounts = matches_.size();
threadCounts = info.matches_.size();
}
QList<int> matchesId = matches_.keys();
QList<QMultiMap<int, int> > matchesList = matches_.values();
QList<int> matchesId = info.matches_.keys();
QList<QMultiMap<int, int> > matchesList = info.matches_.values();
for(int i=0; i<matchesList.size(); i+=threadCounts)
{
QVector<HomographyThread*> threads;
@@ -861,7 +851,7 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
for(int k=i; k<i+threadCounts && k<matchesList.size(); ++k)
{
int objectId = matchesId[k];
threads.push_back(new HomographyThread(&matchesList[k], objectId, &objects_.value(objectId)->keypoints(), &sceneKeypoints_));
threads.push_back(new HomographyThread(&matchesList[k], objectId, &objects_.value(objectId)->keypoints(), &info.sceneKeypoints_));
threads.back()->start();
}
@@ -889,11 +879,11 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
matchesId.push_back(id);
// compute distance from previous added same objects...
QMultiMap<int, QPair<QRect, QTransform> >::iterator objIter = objectsDetected.find(id);
for(;objIter!=objectsDetected.end() && objIter.key() == id; ++objIter)
QMultiMap<int, QTransform>::iterator objIter = info.objDetected_.find(id);
for(;objIter!=info.objDetected_.end() && objIter.key() == id; ++objIter)
{
qreal dx = objIter.value().second.m31() - hTransform.m31();
qreal dy = objIter.value().second.m32() - hTransform.m32();
qreal dx = objIter.value().m31() - hTransform.m31();
qreal dy = objIter.value().m32() - hTransform.m32();
int d = (int)sqrt(dx*dx + dy*dy);
if(d < distance)
{
@@ -905,33 +895,37 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
if(distance >= Settings::getGeneral_multiDetectionRadius())
{
QRect rect = objects_.value(id)->rect();
objectsDetected.insert(id, QPair<QRect, QTransform>(rect, hTransform));
inliers_.insert(id, threads[j]->getInliers());
outliers_.insert(id, threads[j]->getOutliers());
info.objDetected_.insert(id, hTransform);
info.objDetectedSizes_.insert(id, rect.size());
info.objDetectedInliers_.insert(id, threads[j]->getInliers());
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());
}
else
{
rejectedInliers_.insert(id, threads[j]->getInliers());
rejectedOutliers_.insert(id, threads[j]->getOutliers());
info.rejectedInliers_.insert(id, threads[j]->getInliers());
info.rejectedOutliers_.insert(id, threads[j]->getOutliers());
}
}
else
{
rejectedInliers_.insert(id, threads[j]->getInliers());
rejectedOutliers_.insert(id, threads[j]->getOutliers());
info.rejectedInliers_.insert(id, threads[j]->getInliers());
info.rejectedOutliers_.insert(id, threads[j]->getOutliers());
}
}
else
{
rejectedInliers_.insert(id, threads[j]->getInliers());
rejectedOutliers_.insert(id, threads[j]->getOutliers());
info.rejectedInliers_.insert(id, threads[j]->getInliers());
info.rejectedOutliers_.insert(id, threads[j]->getOutliers());
}
}
}
timeStamps_.insert(kTimeHomography, time.restart());
info.timeStamps_.insert(DetectionInfo::kTimeHomography, time.restart());
}
}
else if(!objectsDescriptors_.empty() && sceneKeypoints_.size())
else if(!objectsDescriptors_.empty() && info.sceneKeypoints_.size())
{
UWARN("Cannot search, objects must be updated");
}
@@ -943,8 +937,7 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
}
}
objectsDetected_ = objectsDetected;
timeStamps_.insert(kTimeTotal, totalTime.elapsed());
info.timeStamps_.insert(DetectionInfo::kTimeTotal, totalTime.elapsed());
return success;
}
+106
View File
@@ -0,0 +1,106 @@
/*
* JsonWriter.cpp
*
* Created on: 2014-08-03
* Author: mathieu
*/
#include "find_object/JsonWriter.h"
#include "find_object/utilite/ULogger.h"
#include <QtCore/QFile>
#include <QtCore/QTextStream>
#ifdef WITH_JSONCPP
#include <jsoncpp/json/writer.h>
#endif
bool JsonWriter::available()
{
#ifdef WITH_JSONCPP
return true;
#else
return false;
#endif
}
void JsonWriter::write(const DetectionInfo & info, const QString & path)
{
#ifdef WITH_JSONCPP
if(!path.isEmpty())
{
Json::Value root;
if(info.objDetected_.size())
{
Json::Value detections;
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();
for(QMultiMap<int, QTransform>::const_iterator iter = info.objDetected_.constBegin(); iter!= info.objDetected_.end();)
{
char index = 'a';
int id = iter.key();
while(iter != info.objDetected_.constEnd() && id == iter.key())
{
QString name = QString("object_%1%2").arg(id).arg(info.objDetected_.count(id)>1?QString(index++):"");
detections.append(name.toStdString());
Json::Value homography;
homography.append(iter.value().m11());
homography.append(iter.value().m12());
homography.append(iter.value().m13());
homography.append(iter.value().m21());
homography.append(iter.value().m22());
homography.append(iter.value().m23());
homography.append(iter.value().m31()); // dx
homography.append(iter.value().m32()); // dy
homography.append(iter.value().m33());
root[name.toStdString()]["width"] = iterSizes.value().width();
root[name.toStdString()]["height"] = iterSizes.value().height();
root[name.toStdString()]["homography"] = homography;
root[name.toStdString()]["inliers"] = iterInliers.value();
root[name.toStdString()]["outliers"] = iterOutliers.value();
root[name.toStdString()]["filename"] = iterFilenames.value().toStdString();
++iter;
++iterInliers;
++iterOutliers;
++iterSizes;
++iterFilenames;
}
}
root["objects"] = detections;
}
if(info.matches_.size())
{
Json::Value matchesValues;
const QMap<int, QMultiMap<int, int> > & matches = info.matches_;
for(QMap<int, QMultiMap<int, int> >::const_iterator iter = matches.constBegin();
iter != matches.end();
++iter)
{
QString name = QString("matches_%1").arg(iter.key());
root[name.toStdString()] = iter.value().size();
matchesValues.append(name.toStdString());
}
root["matches"] = matchesValues;
}
// write in a nice readible way
Json::StyledWriter styledWriter;
//std::cout << styledWriter.write(root);
QFile file(path);
file.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream out(&file);
out << styledWriter.write(root).c_str();
file.close();
}
#else
UERROR("Not built with JSON support!");
#endif
}
+37 -36
View File
@@ -268,7 +268,7 @@ void MainWindow::setupTCPServer()
delete tcpServer_;
}
tcpServer_ = new TcpServer(Settings::getGeneral_port(), this);
connect(this, SIGNAL(objectsFound(QMultiMap<int,QPair<QRect,QTransform> >)), tcpServer_, SLOT(publishObjects(QMultiMap<int,QPair<QRect,QTransform> >)));
connect(this, SIGNAL(objectsFound(DetectionInfo)), tcpServer_, SLOT(publishDetectionInfo(DetectionInfo)));
ui_->label_ipAddress->setText(tcpServer_->getHostAddress().toString());
ui_->label_port->setNum(tcpServer_->getPort());
UINFO("Detection sent on port: %d (IP=%s)", tcpServer_->getPort(), tcpServer_->getHostAddress().toString().toStdString().c_str());
@@ -916,19 +916,20 @@ void MainWindow::update(const cv::Mat & image)
iter.value()->resetKptsColor();
}
QMultiMap<int,QPair<QRect,QTransform> > objectsDetected;
if(findObject_->detect(sceneImage_, objectsDetected))
DetectionInfo info;
if(findObject_->detect(sceneImage_, info))
{
ui_->label_timeDetection->setNum(findObject_->timeStamps().value(FindObject::kTimeKeypointDetection, 0));
ui_->label_timeExtraction->setNum(findObject_->timeStamps().value(FindObject::kTimeDescriptorExtraction, 0));
ui_->imageView_source->setData(findObject_->sceneKeypoints(), cvtCvMat2QImage(sceneImage_));
ui_->label_timeIndexing->setNum(findObject_->timeStamps().value(FindObject::kTimeIndexing, 0));
ui_->label_timeDetection->setNum(info.timeStamps_.value(DetectionInfo::kTimeKeypointDetection, 0));
ui_->label_timeExtraction->setNum(info.timeStamps_.value(DetectionInfo::kTimeDescriptorExtraction, 0));
ui_->imageView_source->setData(info.sceneKeypoints_, cvtCvMat2QImage(sceneImage_));
ui_->label_timeIndexing->setNum(info.timeStamps_.value(DetectionInfo::kTimeIndexing, 0));
ui_->label_timeMatching->setNum(info.timeStamps_.value(DetectionInfo::kTimeMatching, 0));
ui_->label_timeHomographies->setNum(info.timeStamps_.value(DetectionInfo::kTimeHomography, 0));
ui_->label_vocabularySize->setNum(findObject_->vocabulary()->size());
ui_->label_timeMatching->setNum(findObject_->timeStamps().value(FindObject::kTimeMatching, 0));
ui_->label_timeHomographies->setNum(findObject_->timeStamps().value(FindObject::kTimeHomography, 0));
// Colorize features matched
const QMap<int, QMultiMap<int, int> > & matches = findObject_->matches();
const QMap<int, QMultiMap<int, int> > & matches = info.matches_;
QMap<int, int> scores;
int maxScoreId = -1;
int maxScore = 0;
@@ -956,12 +957,12 @@ void MainWindow::update(const cv::Mat & image)
ui_->imageView_source->setKptColor(iter.value(), obj->color());
}
}
else if(!objectsDetected.contains(id))
else if(!info.objDetected_.contains(id))
{
// Homography could not be computed...
QLabel * label = ui_->dockWidget_objects->findChild<QLabel*>(QString("%1detection").arg(id));
QMultiMap<int, int> rejectedInliers = findObject_->rejectedInliers().value(id);
QMultiMap<int, int> rejectedOutliers = findObject_->rejectedOutliers().value(id);
QMultiMap<int, int> rejectedInliers = info.rejectedInliers_.value(id);
QMultiMap<int, int> rejectedOutliers = info.rejectedOutliers_.value(id);
if(jter.value().size() < Settings::getHomography_minimumInliers())
{
label->setText(QString("Too low matches (%1)").arg(jter.value().size()));
@@ -979,18 +980,18 @@ void MainWindow::update(const cv::Mat & image)
}
// Add homography rectangles when homographies are computed
QMultiMap<int, QMultiMap<int,int> >::const_iterator inliersIter = findObject_->inliers().constBegin();
QMultiMap<int, QMultiMap<int,int> >::const_iterator outliersIter = findObject_->outliers().constBegin();
for(QMultiMap<int,QPair<QRect,QTransform> >::iterator iter = objectsDetected.begin();
iter!=objectsDetected.end() && inliersIter!=findObject_->inliers().constEnd();
++iter, ++inliersIter)
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();
iter!=info.objDetected_.end();
++iter, ++inliersIter, ++outliersIter)
{
int id = iter.key();
ObjWidget * obj = objWidgets_.value(id);
Q_ASSERT(obj != 0);
// COLORIZE (should be done in the GUI thread)
QTransform hTransform = iter.value().second;
QTransform hTransform = iter.value();
QRect rect = obj->pixmap().rect();
// add rectangle
@@ -1013,10 +1014,10 @@ void MainWindow::update(const cv::Mat & image)
}
QLabel * label = ui_->dockWidget_objects->findChild<QLabel*>(QString("%1detection").arg(id));
if(objectsDetected.count(id) > 1)
if(info.objDetected_.count(id) > 1)
{
// if a homography is already found, set the objects count
label->setText(QString("%1 objects found").arg(objectsDetected.count(id)));
label->setText(QString("%1 objects found").arg(info.objDetected_.count(id)));
}
else
{
@@ -1030,7 +1031,7 @@ void MainWindow::update(const cv::Mat & image)
QMap<int, int> inlierScores;
for(QMap<int, int>::iterator iter=scores.begin(); iter!=scores.end(); ++iter)
{
QList<QMultiMap<int, int> > values = findObject_->inliers().values(iter.key());
QList<QMultiMap<int, int> > values = info.objDetectedInliers_.values(iter.key());
int maxValue = 0;
if(values.size())
{
@@ -1051,8 +1052,8 @@ void MainWindow::update(const cv::Mat & image)
ui_->likelihoodPlot->update();
}
ui_->label_minMatchedDistance->setNum(findObject_->minMatchedDistance());
ui_->label_maxMatchedDistance->setNum(findObject_->maxMatchedDistance());
ui_->label_minMatchedDistance->setNum(info.minMatchedDistance_);
ui_->label_maxMatchedDistance->setNum(info.maxMatchedDistance_);
//Scroll objects slider to the best score
if(maxScoreId>=0 && Settings::getGeneral_autoScroll())
@@ -1065,17 +1066,17 @@ void MainWindow::update(const cv::Mat & image)
}
// Emit homographies
if(objectsDetected.size() > 1)
if(info.objDetected_.size() > 1)
{
UINFO("(%s) %d objects detected!",
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(),
(int)objectsDetected.size());
(int)info.objDetected_.size());
}
else if(objectsDetected.size() == 1)
else if(info.objDetected_.size() == 1)
{
UINFO("(%s) Object %d detected!",
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(),
(int)objectsDetected.begin().key());
(int)info.objDetected_.begin().key());
}
else if(Settings::getGeneral_sendNoObjDetectedEvents())
{
@@ -1083,16 +1084,16 @@ void MainWindow::update(const cv::Mat & image)
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str());
}
if(objectsDetected.size() > 0 || Settings::getGeneral_sendNoObjDetectedEvents())
if(info.objDetected_.size() > 0 || Settings::getGeneral_sendNoObjDetectedEvents())
{
Q_EMIT objectsFound(objectsDetected);
Q_EMIT objectsFound(info);
}
ui_->label_objectsDetected->setNum(objectsDetected.size());
ui_->label_objectsDetected->setNum(info.objDetected_.size());
}
else
{
this->statusBar()->showMessage(tr("Cannot search, objects must be updated!"));
ui_->imageView_source->setData(findObject_->sceneKeypoints(), cvtCvMat2QImage(sceneImage_));
ui_->imageView_source->setData(info.sceneKeypoints_, cvtCvMat2QImage(sceneImage_));
}
@@ -1102,7 +1103,7 @@ void MainWindow::update(const cv::Mat & image)
iter.value()->update();
}
ui_->label_nfeatures->setNum((int)findObject_->sceneKeypoints().size());
ui_->label_nfeatures->setNum((int)info.sceneKeypoints_.size());
ui_->imageView_source->update();
ui_->label_detectorDescriptorType->setText(QString("%1/%2").arg(Settings::currentDetectorType()).arg(Settings::currentDescriptorType()));
@@ -1116,7 +1117,7 @@ void MainWindow::update(const cv::Mat & image)
ui_->horizontalSlider_frames->blockSignals(false);
}
ui_->label_timeTotal->setNum(findObject_->timeStamps().value(FindObject::kTimeTotal, 0));
ui_->label_timeTotal->setNum(info.timeStamps_.value(DetectionInfo::kTimeTotal, 0));
int refreshRate = qRound(1000.0f/float(updateRate_.restart()));
if(refreshRate > 0 && refreshRate < lowestRefreshRate_)
{
@@ -1200,7 +1201,7 @@ void MainWindow::notifyParametersChanged(const QStringList & paramChanged)
ui_->label_timeRefreshRate->setVisible(false);
}
ui_->actionCamera_from_video_file->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && !UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()));
ui_->actionCamera_from_directory_of_images->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()));
ui_->actionCamera_from_video_file->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && !UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()) && !Settings::getCamera_6useTcpCamera());
ui_->actionCamera_from_directory_of_images->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()) && !Settings::getCamera_6useTcpCamera());
ui_->actionCamera_from_TCP_IP->setChecked(Settings::getCamera_6useTcpCamera());
}
+5 -2
View File
@@ -15,9 +15,10 @@
class ObjSignature {
public:
ObjSignature(int id, const cv::Mat & image) :
ObjSignature(int id, const cv::Mat & image, const QString & filename) :
id_(id),
image_(image)
image_(image),
filename_(filename)
{}
virtual ~ObjSignature() {}
@@ -37,6 +38,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 cv::Mat & image() const {return image_;}
const std::vector<cv::KeyPoint> & keypoints() const {return keypoints_;}
const cv::Mat & descriptors() const {return descriptors_;}
@@ -47,6 +49,7 @@ public:
private:
int id_;
cv::Mat image_;
QString filename_;
std::vector<cv::KeyPoint> keypoints_;
cv::Mat descriptors_;
QMultiMap<int, int> words_; // <word id, keypoint indexes>
+10 -25
View File
@@ -53,38 +53,23 @@ quint16 TcpServer::getPort() const
return this->serverPort();
}
void TcpServer::publishObjects(const QMultiMap<int, QPair<QRect, QTransform> > & objects)
void TcpServer::publishDetectionInfo(const DetectionInfo & info)
{
QList<QTcpSocket*> clients = this->findChildren<QTcpSocket*>();
if(clients.size())
{
QVector<float> data(objects.size()*12);
int i=0;
for(QMultiMap<int, QPair<QRect, QTransform> >::const_iterator iter=objects.constBegin(); iter!=objects.constEnd(); ++iter)
{
data[i++] = iter.key();
data[i++] = iter.value().first.width();
data[i++] = iter.value().first.height();
data[i++] = iter.value().second.m11();
data[i++] = iter.value().second.m12();
data[i++] = iter.value().second.m13();
data[i++] = iter.value().second.m21();
data[i++] = iter.value().second.m22();
data[i++] = iter.value().second.m23();
data[i++] = iter.value().second.m31(); // dx
data[i++] = iter.value().second.m32(); // dy
data[i++] = iter.value().second.m33();
}
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << (quint16)0;
out << info;
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16));
for(QList<QTcpSocket*>::iterator iter = clients.begin(); iter!=clients.end(); ++iter)
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << (quint16)0;
out << data;
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16));
(*iter)->write(block);
}
}
+2 -2
View File
@@ -53,13 +53,13 @@ bool ULogger::printWhereFullPath_ = false;
bool ULogger::limitWhereLength_ = false;
bool ULogger::buffered_ = false;
bool ULogger::exitingState_ = false;
ULogger::Level ULogger::level_ = kInfo; // By default, we show all info msgs + upper level (Warning, Error)
ULogger::Level ULogger::level_ = kWarning;
ULogger::Level ULogger::exitLevel_ = kFatal;
ULogger::Level ULogger::eventLevel_ = kFatal;
const char * ULogger::levelName_[5] = {"DEBUG", " INFO", " WARN", "ERROR", "FATAL"};
ULogger* ULogger::instance_ = 0;
UDestroyer<ULogger> ULogger::destroyer_;
ULogger::Type ULogger::type_ = ULogger::kTypeNoLog; // Default nothing
ULogger::Type ULogger::type_ = ULogger::kTypeConsole;
UMutex ULogger::loggerMutex_;
const std::string ULogger::kDefaultLogFileName = "./ULog.txt";
std::string ULogger::logFileName_;