mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 17:40:23 +08:00
Memory: Fixed features with no id (-1) ignored for triangulation from motion. Dictionary: matching with negative word ids is now allowed
This commit is contained in:
@@ -106,6 +106,7 @@ class RTABMAP_EXP Statistics
|
||||
RTABMAP_STATS(Memory, Odometry_variance_lin,);
|
||||
RTABMAP_STATS(Memory, Distance_travelled, m);
|
||||
RTABMAP_STATS(Memory, RAM_usage, MB);
|
||||
RTABMAP_STATS(Memory, Triangulated_points, );
|
||||
|
||||
RTABMAP_STATS(Timing, Memory_update, ms);
|
||||
RTABMAP_STATS(Timing, Neighbor_link_refining, ms);
|
||||
|
||||
@@ -3990,6 +3990,13 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
|
||||
allWordIds[quantizedToRawIndices[i]] = *iter;
|
||||
++i;
|
||||
}
|
||||
for(i=0; i<(int)allWordIds.size(); ++i)
|
||||
{
|
||||
if(allWordIds[i] < 0)
|
||||
{
|
||||
allWordIds[i] = -1*(i+1);
|
||||
}
|
||||
}
|
||||
wordIds = uVectorToList(allWordIds);
|
||||
}
|
||||
|
||||
@@ -4049,22 +4056,25 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
|
||||
Signature * previousS = _signatures.rbegin()->second;
|
||||
if(previousS->getWords().size() > 8 && words.size() > 8 && !previousS->getPose().isNull())
|
||||
{
|
||||
UDEBUG("Previous pose(%d) = %s", previousS->id(), previousS->getPose().prettyPrint().c_str());
|
||||
UDEBUG("Current pose(%d) = %s", id, pose.prettyPrint().c_str());
|
||||
Transform cameraTransform = pose.inverse() * previousS->getPose();
|
||||
|
||||
Signature cpPrevious(-2);
|
||||
Signature cpPrevious(2);
|
||||
// IDs should be unique so that registration doesn't override them
|
||||
std::map<int, cv::KeyPoint> uniqueWords = uMultimapToMapUnique(previousS->getWords());
|
||||
std::map<int, cv::Mat> uniqueWordsDescriptors = uMultimapToMapUnique(previousS->getWordsDescriptors());
|
||||
cpPrevious.sensorData().setCameraModels(previousS->sensorData().cameraModels());
|
||||
cpPrevious.setWords(std::multimap<int, cv::KeyPoint>(uniqueWords.begin(), uniqueWords.end()));
|
||||
cpPrevious.setWordsDescriptors(std::multimap<int, cv::Mat>(uniqueWordsDescriptors.begin(), uniqueWordsDescriptors.end()));
|
||||
Signature cpCurrent(-1);
|
||||
Signature cpCurrent(1);
|
||||
uniqueWords = uMultimapToMapUnique(words);
|
||||
uniqueWordsDescriptors = uMultimapToMapUnique(wordsDescriptors);
|
||||
cpCurrent.sensorData().setCameraModels(data.cameraModels());
|
||||
cpCurrent.setWords(std::multimap<int, cv::KeyPoint>(uniqueWords.begin(), uniqueWords.end()));
|
||||
cpCurrent.setWordsDescriptors(std::multimap<int, cv::Mat>(uniqueWordsDescriptors.begin(), uniqueWordsDescriptors.end()));
|
||||
// This will force comparing descriptors between both images directly
|
||||
Transform tmpt = _registrationPipeline->computeTransformation(cpCurrent, cpPrevious, cameraTransform);
|
||||
Transform tmpt = _registrationPipeline->computeTransformationMod(cpCurrent, cpPrevious, cameraTransform);
|
||||
UDEBUG("t=%s", tmpt.prettyPrint().c_str());
|
||||
|
||||
// compute 3D words by epipolar geometry with the previous signature
|
||||
@@ -4077,32 +4087,21 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
|
||||
UDEBUG("inliers=%d", (int)inliers.size());
|
||||
|
||||
// words3D should have the same size than words
|
||||
float bad_point = std::numeric_limits<float>::quiet_NaN ();
|
||||
UASSERT(words.size() == words3D.size());
|
||||
int added3DPointsWithoutDepth = 0;
|
||||
for(std::multimap<int, cv::KeyPoint>::const_iterator iter=words.begin(); iter!=words.end(); ++iter)
|
||||
{
|
||||
std::map<int, cv::Point3f>::iterator jter=inliers.find(iter->first);
|
||||
std::multimap<int, cv::Point3f>::iterator iter3D = words3D.find(iter->first);
|
||||
if(iter3D == words3D.end())
|
||||
{
|
||||
if(jter != inliers.end())
|
||||
{
|
||||
words3D.insert(std::make_pair(iter->first, jter->second));
|
||||
++added3DPointsWithoutDepth;
|
||||
}
|
||||
else
|
||||
{
|
||||
words3D.insert(std::make_pair(iter->first, cv::Point3f(bad_point,bad_point,bad_point)));
|
||||
}
|
||||
}
|
||||
else if(!util3d::isFinite(iter3D->second) && jter != inliers.end())
|
||||
UASSERT(iter3D!=words3D.end());
|
||||
if(!util3d::isFinite(iter3D->second) && jter != inliers.end())
|
||||
{
|
||||
iter3D->second = jter->second;
|
||||
++added3DPointsWithoutDepth;
|
||||
}
|
||||
}
|
||||
UDEBUG("added3DPointsWithoutDepth=%d", added3DPointsWithoutDepth);
|
||||
if(stats) stats->addStatistic(Statistics::kMemoryTriangulated_points(), (float)added3DPointsWithoutDepth);
|
||||
|
||||
t = timer.ticks();
|
||||
UASSERT(words3D.size() == words.size());
|
||||
|
||||
@@ -601,21 +601,18 @@ int VWDictionary::getNextId()
|
||||
|
||||
void VWDictionary::addWordRef(int wordId, int signatureId)
|
||||
{
|
||||
if(signatureId > 0)
|
||||
VisualWord * vw = 0;
|
||||
vw = uValue(_visualWords, wordId, vw);
|
||||
if(vw)
|
||||
{
|
||||
VisualWord * vw = 0;
|
||||
vw = uValue(_visualWords, wordId, vw);
|
||||
if(vw)
|
||||
{
|
||||
vw->addRef(signatureId);
|
||||
_totalActiveReferences += 1;
|
||||
vw->addRef(signatureId);
|
||||
_totalActiveReferences += 1;
|
||||
|
||||
_unusedWords.erase(vw->id());
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("Not found word %d (dict size=%d)", wordId, (int)_visualWords.size());
|
||||
}
|
||||
_unusedWords.erase(vw->id());
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("Not found word %d (dict size=%d)", wordId, (int)_visualWords.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -636,8 +633,6 @@ void VWDictionary::removeAllWordRef(int wordId, int signatureId)
|
||||
std::list<int> VWDictionary::addNewWords(const cv::Mat & descriptorsIn,
|
||||
int signatureId)
|
||||
{
|
||||
UASSERT(signatureId > 0);
|
||||
|
||||
UDEBUG("id=%d descriptors=%d", signatureId, descriptorsIn.rows);
|
||||
UTimer timer;
|
||||
std::list<int> wordIds;
|
||||
@@ -818,7 +813,7 @@ std::list<int> VWDictionary::addNewWords(const cv::Mat & descriptorsIn,
|
||||
index = *((size_t*)&results.at<int>(i, j));
|
||||
}
|
||||
int id = uValue(_mapIndexId, index);
|
||||
if(d >= 0.0f && id > 0)
|
||||
if(d >= 0.0f && id != 0)
|
||||
{
|
||||
fullResults.insert(std::pair<float, int>(d, id));
|
||||
}
|
||||
@@ -834,7 +829,7 @@ std::list<int> VWDictionary::addNewWords(const cv::Mat & descriptorsIn,
|
||||
{
|
||||
float d = matches.at(i).at(j).distance;
|
||||
int id = uValue(_mapIndexId, matches.at(i).at(j).trainIdx);
|
||||
if(d >= 0.0f && id > 0)
|
||||
if(d >= 0.0f && id != 0)
|
||||
{
|
||||
fullResults.insert(std::pair<float, int>(d, id));
|
||||
}
|
||||
@@ -857,7 +852,7 @@ std::list<int> VWDictionary::addNewWords(const cv::Mat & descriptorsIn,
|
||||
{
|
||||
float d = matchesNewWords.at(0).at(j).distance;
|
||||
int id = newWordsId[matchesNewWords.at(0).at(j).trainIdx];
|
||||
if(d >= 0.0f && id > 0)
|
||||
if(d >= 0.0f && id != 0)
|
||||
{
|
||||
fullResults.insert(std::pair<float, int>(d, id));
|
||||
}
|
||||
@@ -1176,7 +1171,7 @@ std::vector<int> VWDictionary::findNN(const cv::Mat & queryIn) const
|
||||
index = *((size_t*)&results.at<int>(i, j));
|
||||
}
|
||||
int id = uValue(_mapIndexId, index);
|
||||
if(d >= 0.0f && id > 0)
|
||||
if(d >= 0.0f && id != 0)
|
||||
{
|
||||
fullResults.insert(std::pair<float, int>(d, id));
|
||||
}
|
||||
@@ -1188,7 +1183,7 @@ std::vector<int> VWDictionary::findNN(const cv::Mat & queryIn) const
|
||||
{
|
||||
float d = matches.at(i).at(j).distance;
|
||||
int id = uValue(_mapIndexId, matches.at(i).at(j).trainIdx);
|
||||
if(d >= 0.0f && id > 0)
|
||||
if(d >= 0.0f && id != 0)
|
||||
{
|
||||
fullResults.insert(std::pair<float, int>(d, id));
|
||||
}
|
||||
@@ -1202,7 +1197,7 @@ std::vector<int> VWDictionary::findNN(const cv::Mat & queryIn) const
|
||||
{
|
||||
float d = matchesNotIndexed.at(i).at(j).distance;
|
||||
int id = uValue(mapIndexIdNotIndexed, matchesNotIndexed.at(i).at(j).trainIdx);
|
||||
if(d >= 0.0f && id > 0)
|
||||
if(d >= 0.0f && id != 0)
|
||||
{
|
||||
fullResults.insert(std::pair<float, int>(d, id));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user