SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
WAIMapPoint.cpp
Go to the documentation of this file.
1 /**
2  * \file WAIMapPoint.cpp
3  * \authors Michael Goettlicher
4  * \date October 2017
5 // Codestyle: https://github.com/cpvrlab/SLProject/wiki/Coding-Style-Guidelines
6  * \authors Marcus Hudritsch
7  * \copyright http://opensource.org/licenses/GPL-3.0
8 */
9 
10 #include <WAIMapPoint.h>
11 #include <WAIKeyFrame.h>
12 #include <WAIFrame.h>
13 #include <orb_slam/ORBmatcher.h>
14 #include <mutex>
15 
16 long unsigned int WAIMapPoint::nNextId = 0;
19 
20 //-----------------------------------------------------------------------------
21 //!constructor used during map loading
22 WAIMapPoint::WAIMapPoint(int id, const cv::Mat& Pos, bool fixMp)
23  : mnId(id),
24  mnFirstKFid(-1),
25  /* mnFirstFrame(pRefKF->mnFrameId), */ nObs(0),
26  mnLastFrameSeen(0),
27  mnCorrectedByKF(0),
28  mnCorrectedReference(0),
29  mpRefKF(NULL),
30  mnVisible(1),
31  mnFound(1),
32  mbBad(false),
33  mpReplaced(static_cast<WAIMapPoint*>(NULL)),
34  mfMinDistance(0),
35  mfMaxDistance(0),
36  _fixed(fixMp),
37  _loadedFromMap(true)
38 {
39 
40  mnMarker[0] = 0;
41  mnMarker[1] = 0;
42  mnMarker[2] = 0;
43  mnMarker[3] = 0;
44  mnMarker[4] = 0;
45  mnMarker[5] = 0;
46  mnMarker[6] = 0;
47 
48  SetWorldPos(Pos);
49  mNormalVector = cv::Mat::zeros(3, 1, CV_32F);
50 
51  //update highest used id for new map point generation
52  if (id >= (int)nNextId)
53  nNextId = id + 1;
54 }
55 //-----------------------------------------------------------------------------
56 WAIMapPoint::WAIMapPoint(const cv::Mat& Pos,
57  WAIKeyFrame* pRefKF)
58  : mnFirstKFid((long)pRefKF->mnId),
59  /* mnFirstFrame(pRefKF->mnFrameId), */
60  nObs(0),
61  mnLastFrameSeen(0),
62  mnCorrectedByKF(0),
63  mnCorrectedReference(0),
64  mpRefKF(pRefKF),
65  mnVisible(1),
66  mnFound(1),
67  mbBad(false),
68  mpReplaced(static_cast<WAIMapPoint*>(NULL)),
69  mfMinDistance(0),
70  mfMaxDistance(0),
71  _fixed(false),
72  _loadedFromMap(false)
73 {
74  mnMarker[0] = 0;
75  mnMarker[1] = 0;
76  mnMarker[2] = 0;
77  mnMarker[3] = 0;
78  mnMarker[4] = 0;
79  mnMarker[5] = 0;
80  mnMarker[6] = 0;
81 
82  SetWorldPos(Pos);
83  //Pos.copyTo(mWorldPos);
84  mNormalVector = cv::Mat::zeros(3, 1, CV_32F);
85 
86  //TODO(Luluc) remove mMutexPointCreaton on WAIMap
87  // MapPoints can be created from Tracking and Local Mapping. This mutex avoid conflicts with id.
88  unique_lock<mutex> lock(mMutexMapPointCreation);
89  mnId = nNextId++;
90 
92 }
93 
94 //-----------------------------------------------------------------------------
96 {
97  unique_lock<mutex> lock(mMutexPos);
98  WAI::V3 vec;
99  vec.x = mWorldPos.at<float>(0, 0);
100  vec.y = mWorldPos.at<float>(1, 0);
101  vec.z = mWorldPos.at<float>(2, 0);
102  return vec;
103 }
104 //-----------------------------------------------------------------------------
106 {
107  unique_lock<mutex> lock(mMutexPos);
108  mWorldPos.at<float>(0, 0) = vec.x;
109  mWorldPos.at<float>(1, 0) = vec.y;
110  mWorldPos.at<float>(2, 0) = vec.z;
111 }
112 //-----------------------------------------------------------------------------
114 {
115  WAI::V3 vec = {};
116 
117  if (!mNormalVector.empty())
118  {
119  vec.x = mNormalVector.at<float>(0, 0);
120  vec.y = mNormalVector.at<float>(1, 0);
121  vec.z = mNormalVector.at<float>(2, 0);
122  }
123  return vec;
124 }
125 //-----------------------------------------------------------------------------
126 void WAIMapPoint::SetWorldPos(const cv::Mat& Pos)
127 {
128  unique_lock<mutex> lock2(mGlobalMutex);
129  unique_lock<mutex> lock(mMutexPos);
130  Pos.copyTo(mWorldPos);
131 }
132 //-----------------------------------------------------------------------------
134 {
135  unique_lock<mutex> lock(mMutexPos);
136  return mWorldPos.clone();
137 }
138 //-----------------------------------------------------------------------------
140 {
141  unique_lock<mutex> lock(mMutexPos);
142  return mNormalVector.clone();
143 }
144 //-----------------------------------------------------------------------------
145 void WAIMapPoint::SetNormal(const cv::Mat& normal)
146 {
147  unique_lock<mutex> lock(mMutexPos);
148  normal.copyTo(mNormalVector);
149 }
150 //-----------------------------------------------------------------------------
152 {
153  unique_lock<mutex> lock(mMutexFeatures);
154  return mpRefKF;
155 }
156 //-----------------------------------------------------------------------------
158 {
159  unique_lock<mutex> lock(mMutexFeatures);
160  if (mObservations.count(pKF))
161  return;
162  mObservations[pKF] = idx;
163  nObs++;
164 }
165 //-----------------------------------------------------------------------------
167 {
168  bool bBad = false;
169  {
170  unique_lock<mutex> lock(mMutexFeatures);
171  if (mObservations.count(pKF))
172  {
173  //int idx = mObservations[pKF];
174  //if (pKF->mvuRight[idx] >= 0)
175  // nObs -= 2;
176  //else
177  // nObs--;
178  nObs--;
179 
180  mObservations.erase(pKF);
181 
182  if (mpRefKF == pKF)
183  {
184  for (auto it = mObservations.begin(); it != mObservations.end(); it++)
185  {
186  WAIKeyFrame* kf = it->first;
187  if (!kf->isBad())
188  {
189  mpRefKF = kf;
190  break;
191  }
192  else
193  {
194  continue;
195  }
196  }
197  if (mpRefKF == pKF)
198  {
199  bBad = true;
200  }
202  }
203 
204  // If only 2 observations or less, discard point
205  if (nObs <= 2)
206  bBad = true;
207  }
208  }
209 
210  if (bBad)
211  SetBadFlag();
212 }
213 //-----------------------------------------------------------------------------
214 std::map<WAIKeyFrame*, size_t> WAIMapPoint::GetObservations()
215 {
216  unique_lock<mutex> lock(mMutexFeatures);
217  return mObservations;
218 }
219 //-----------------------------------------------------------------------------
221 {
222  unique_lock<mutex> lock(mMutexFeatures);
223  return nObs;
224 }
225 //-----------------------------------------------------------------------------
227 {
228  map<WAIKeyFrame*, size_t> obs;
229  {
230  unique_lock<mutex> lock1(mMutexFeatures);
231  unique_lock<mutex> lock2(mMutexPos);
232  mbBad = true;
233  obs = mObservations;
234  mObservations.clear();
235  }
236  for (map<WAIKeyFrame*, size_t>::iterator mit = obs.begin(), mend = obs.end(); mit != mend; mit++)
237  {
238  WAIKeyFrame* pKF = mit->first;
239  pKF->EraseMapPointMatch(mit->second);
240  }
241 }
242 //-----------------------------------------------------------------------------
244 {
245  unique_lock<mutex> lock1(mMutexFeatures);
246  unique_lock<mutex> lock2(mMutexPos);
247  return mpReplaced;
248 }
249 //-----------------------------------------------------------------------------
251 {
252  if (pMP->mnId == this->mnId)
253  return;
254 
255  int nvisible, nfound;
256  map<WAIKeyFrame*, size_t> obs;
257  {
258  unique_lock<mutex> lock1(mMutexFeatures);
259  unique_lock<mutex> lock2(mMutexPos);
260  obs = mObservations;
261  mObservations.clear();
262  mbBad = true;
263  nvisible = mnVisible;
264  nfound = mnFound;
265  mpReplaced = pMP;
266  }
267 
268  for (map<WAIKeyFrame*, size_t>::iterator mit = obs.begin(), mend = obs.end(); mit != mend; mit++)
269  {
270  // Replace measurement in keyframe
271  WAIKeyFrame* pKF = mit->first;
272 
273  if (!pMP->IsInKeyFrame(pKF))
274  {
275  pKF->ReplaceMapPointMatch(mit->second, pMP);
276  pMP->AddObservation(pKF, mit->second);
277  }
278  else
279  {
280  pKF->EraseMapPointMatch(mit->second);
281  }
282  }
283  pMP->IncreaseFound(nfound);
284  pMP->IncreaseVisible(nvisible);
286 }
287 //-----------------------------------------------------------------------------
289 {
290  unique_lock<mutex> lock(mMutexFeatures);
291  unique_lock<mutex> lock2(mMutexPos);
292  return mbBad;
293 }
294 //-----------------------------------------------------------------------------
296 {
297  unique_lock<mutex> lock(mMutexFeatures);
298  mnVisible += n;
299 }
300 //-----------------------------------------------------------------------------
302 {
303  unique_lock<mutex> lock(mMutexFeatures);
304  mnFound += n;
305 }
306 //-----------------------------------------------------------------------------
308 {
309  unique_lock<mutex> lock(mMutexFeatures);
310  return static_cast<float>(mnFound) / (float)mnVisible;
311 }
312 //-----------------------------------------------------------------------------
314 {
315  // Retrieve all observed descriptors
316  vector<cv::Mat> vDescriptors;
317 
318  map<WAIKeyFrame*, size_t> observations;
319 
320  {
321  unique_lock<mutex> lock1(mMutexFeatures);
322  if (mbBad)
323  return;
324  observations = mObservations;
325  }
326 
327  if (observations.empty())
328  return;
329 
330  vDescriptors.reserve(observations.size());
331 
332  for (map<WAIKeyFrame*, size_t>::iterator mit = observations.begin(), mend = observations.end(); mit != mend; mit++)
333  {
334  WAIKeyFrame* pKF = mit->first;
335 
336  if (pKF && !pKF->isBad())
337  vDescriptors.push_back(pKF->mDescriptors.row((int)mit->second));
338  }
339 
340  if (vDescriptors.empty())
341  return;
342 
343  // Compute distances between them
344  size_t N = vDescriptors.size();
345 
346  float** Distances = new float*[N];
347  for (size_t i = 0; i < N; ++i)
348  Distances[i] = new float[N];
349 
350  for (size_t i = 0; i < N; i++)
351  {
352  Distances[i][i] = 0;
353  for (size_t j = i + 1; j < N; j++)
354  {
355  int distij = ORBmatcher::DescriptorDistance(vDescriptors[i], vDescriptors[j]);
356  Distances[i][j] = (float)distij;
357  Distances[j][i] = (float)distij;
358  }
359  }
360 
361  // Take the descriptor with least median distance to the rest
362  int BestMedian = INT_MAX;
363  int BestIdx = 0;
364  for (size_t i = 0; i < N; i++)
365  {
366  vector<int> vDists(Distances[i], Distances[i] + N);
367  sort(vDists.begin(), vDists.end());
368  int median = vDists[(uint64_t)(0.5f * (N - 1))];
369 
370  if (median < BestMedian)
371  {
372  BestMedian = median;
373  BestIdx = (int)i;
374  }
375  }
376 
377  //free Distances
378  for (size_t i = 0; i < N; ++i)
379  delete Distances[i];
380  delete[] Distances;
381 
382  {
383  unique_lock<mutex> lock(mMutexFeatures);
384  mDescriptor = vDescriptors[BestIdx].clone();
385  }
386 }
387 //-----------------------------------------------------------------------------
389 {
390  unique_lock<mutex> lock(mMutexFeatures);
391  return mDescriptor.clone();
392 }
393 //-----------------------------------------------------------------------------
394 void WAIMapPoint::SetDescriptor(const cv::Mat& descriptor)
395 {
396  unique_lock<mutex> lock(mMutexFeatures);
397  descriptor.copyTo(mDescriptor);
398 }
399 //-----------------------------------------------------------------------------
401 {
402  unique_lock<mutex> lock(mMutexFeatures);
403  if (mObservations.count(pKF))
404  return (int)mObservations[pKF];
405  else
406  return -1;
407 }
408 //-----------------------------------------------------------------------------
410 {
411  unique_lock<mutex> lock(mMutexFeatures);
412  return (mObservations.count(pKF));
413 }
414 //-----------------------------------------------------------------------------
415 //we calculate normal and depth from
417 {
418  map<WAIKeyFrame*, size_t> observations;
419  WAIKeyFrame* pRefKF;
420  cv::Mat Pos;
421  {
422  unique_lock<mutex> lock1(mMutexFeatures);
423  unique_lock<mutex> lock2(mMutexPos);
424  if (mbBad)
425  return;
426  observations = mObservations;
427  pRefKF = mpRefKF;
428  Pos = mWorldPos.clone();
429  }
430 
431  if (observations.empty())
432  return;
433 
434  cv::Mat normal = cv::Mat::zeros(3, 1, CV_32F);
435  int n = 0;
436  for (map<WAIKeyFrame*, size_t>::iterator mit = observations.begin(), mend = observations.end(); mit != mend; mit++)
437  {
438  WAIKeyFrame* pKF = mit->first;
439  cv::Mat Owi = pKF->GetCameraCenter();
440  cv::Mat normali = mWorldPos - Owi;
441  normal = normal + normali / cv::norm(normali);
442  n++;
443  }
444 
445  cv::Mat PC = Pos - pRefKF->GetCameraCenter();
446  const float dist = (float)cv::norm(PC);
447  const int level = pRefKF->mvKeysUn[observations[pRefKF]].octave;
448  const float levelScaleFactor = pRefKF->mvScaleFactors[level];
449  const int nLevels = pRefKF->mnScaleLevels;
450 
451  {
452  unique_lock<mutex> lock3(mMutexPos);
453  mfMaxDistance = dist * levelScaleFactor;
454  mfMinDistance = mfMaxDistance / pRefKF->mvScaleFactors[nLevels - 1];
455  mNormalVector = normal / n;
456  }
457 }
458 //-----------------------------------------------------------------------------
460 {
461  unique_lock<mutex> lock(mMutexPos);
462  return 0.8f * mfMinDistance;
463 }
464 //-----------------------------------------------------------------------------
466 {
467  unique_lock<mutex> lock(mMutexPos);
468  return 1.2f * mfMaxDistance;
469 }
470 //-----------------------------------------------------------------------------
472 {
473  return mfMinDistance;
474 }
475 //-----------------------------------------------------------------------------
477 {
478  return mfMaxDistance;
479 }
480 //-----------------------------------------------------------------------------
481 void WAIMapPoint::SetMaxDistance(float maxDist)
482 {
483  mfMaxDistance = maxDist;
484 }
485 //-----------------------------------------------------------------------------
486 void WAIMapPoint::SetMinDistance(float minDist)
487 {
488  mfMinDistance = minDist;
489 }
490 //-----------------------------------------------------------------------------
491 int WAIMapPoint::PredictScale(const float& currentDist, WAIKeyFrame* pKF)
492 {
493  float ratio;
494  {
495  unique_lock<mutex> lock(mMutexPos);
496  ratio = mfMaxDistance / currentDist;
497  }
498 
499  int nScale = (int)ceil(log(ratio) / pKF->mfLogScaleFactor);
500  if (nScale < 0)
501  nScale = 0;
502  else if (nScale >= pKF->mnScaleLevels)
503  nScale = pKF->mnScaleLevels - 1;
504 
505  return nScale;
506 }
507 //-----------------------------------------------------------------------------
508 int WAIMapPoint::PredictScale(const float& currentDist, WAIFrame* pF)
509 {
510  float ratio;
511  {
512  unique_lock<mutex> lock(mMutexPos);
513  ratio = mfMaxDistance / currentDist;
514  }
515 
516  int nScale = (int)ceil(log(ratio) / pF->mfLogScaleFactor);
517  if (nScale < 0)
518  nScale = 0;
519  else if (nScale >= pF->mnScaleLevels)
520  nScale = pF->mnScaleLevels - 1;
521 
522  return nScale;
523 }
524 //-----------------------------------------------------------------------------
525 size_t WAIMapPoint::getSizeOfCvMat(const cv::Mat& mat)
526 {
527  size_t size = 0;
528  if (mat.isContinuous())
529  size = mat.total() * mat.elemSize();
530  else
531  {
532  size = mat.step[0] * mat.rows;
533  }
534  return size;
535 }
536 //-----------------------------------------------------------------------------
538 {
539  size_t size = 0;
540 
541  size += sizeof(*this);
542  size += getSizeOfCvMat(mWorldPos);
543  size += getSizeOfCvMat(mNormalVector);
544  size += getSizeOfCvMat(mDescriptor);
545  size += getSizeOfCvMat(mPosGBA);
546 
547  return size;
548 }
int mnScaleLevels
Definition: WAIFrame.h:168
float mfLogScaleFactor
Definition: WAIFrame.h:170
AR Keyframe node class.
Definition: WAIKeyFrame.h:60
cv::Mat GetCameraCenter()
const int mnScaleLevels
Definition: WAIKeyFrame.h:233
const std::vector< float > mvScaleFactors
Definition: WAIKeyFrame.h:236
const std::vector< cv::KeyPoint > mvKeysUn
Definition: WAIKeyFrame.h:220
void EraseMapPointMatch(WAIMapPoint *pMP)
const cv::Mat mDescriptors
Definition: WAIKeyFrame.h:223
const float mfLogScaleFactor
Definition: WAIKeyFrame.h:235
void ReplaceMapPointMatch(const size_t &idx, WAIMapPoint *pMP)
cv::Mat mWorldPos
Definition: WAIMapPoint.h:154
std::mutex mMutexFeatures
Definition: WAIMapPoint.h:181
float GetFoundRatio()
@ RefKfSource_Constructor
Definition: WAIMapPoint.h:96
@ RefKfSource_EraseObservation
Definition: WAIMapPoint.h:97
void SetMinDistance(float minDist)
RefKfSource refKfSource
Definition: WAIMapPoint.h:100
void AddObservation(WAIKeyFrame *pKF, size_t idx)
void SetBadFlag()
std::map< WAIKeyFrame *, size_t > mObservations
Definition: WAIMapPoint.h:157
long unsigned int mnId
Definition: WAIMapPoint.h:108
static long unsigned int nNextId
Definition: WAIMapPoint.h:110
std::map< WAIKeyFrame *, size_t > GetObservations()
int Observations()
cv::Mat mDescriptor
Definition: WAIMapPoint.h:163
float mfMaxDistance
Definition: WAIMapPoint.h:178
float GetMaxDistanceInvariance()
size_t getSizeOfCvMat(const cv::Mat &mat)
cv::Mat mNormalVector
Definition: WAIMapPoint.h:160
std::mutex mMutexPos
Definition: WAIMapPoint.h:180
void UpdateNormalAndDepth()
int PredictScale(const float &currentDist, WAIKeyFrame *pF)
WAI::V3 normalVec()
int GetIndexInKeyFrame(WAIKeyFrame *pKF)
cv::Mat GetNormal()
WAIKeyFrame * mpRefKF
Definition: WAIMapPoint.h:166
static std::mutex mGlobalMutex
Definition: WAIMapPoint.h:137
void SetDescriptor(const cv::Mat &descriptor)
void Replace(WAIMapPoint *pMP)
cv::Mat mPosGBA
Definition: WAIMapPoint.h:134
WAIMapPoint * mpReplaced
Definition: WAIMapPoint.h:174
cv::Mat GetDescriptor()
float GetMinDistanceInvariance()
static std::mutex mMutexMapPointCreation
Definition: WAIMapPoint.h:138
void SetNormal(const cv::Mat &normal)
float mfMinDistance
Definition: WAIMapPoint.h:177
void EraseObservation(WAIKeyFrame *pKF)
size_t getSizeOf()
WAIKeyFrame * GetReferenceKeyFrame()
bool IsInKeyFrame(WAIKeyFrame *pKF)
void IncreaseVisible(int n=1)
void ComputeDistinctiveDescriptors()
WAIMapPoint(int id, const cv::Mat &Pos, bool fixMp)
constructor used during map loading
Definition: WAIMapPoint.cpp:22
float GetMaxDistance()
int mnMarker[7]
Definition: WAIMapPoint.h:128
float GetMinDistance()
cv::Mat GetWorldPos()
void SetMaxDistance(float maxDist)
void IncreaseFound(int n=1)
void SetWorldPos(const cv::Mat &Pos)
WAI::V3 worldPosVec()
Definition: WAIMapPoint.cpp:95
WAIMapPoint * GetReplaced()
T ceil(T a)
Definition: Utils.h:247
void log(const char *tag, const char *format,...)
logs a formatted string platform independently
Definition: Utils.cpp:1103
float x
Definition: WAIMath.h:33
float z
Definition: WAIMath.h:33
float y
Definition: WAIMath.h:33