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(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) / 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 #ifdef _WINDOWS
345  size_t N = vDescriptors.size();
346 
347  float** Distances = new float*[N];
348  for (size_t i = 0; i < N; ++i)
349  Distances[i] = new float[N];
350 
351  for (size_t i = 0; i < N; i++)
352  {
353  Distances[i][i] = 0;
354  for (size_t j = i + 1; j < N; j++)
355  {
356  int distij = ORBmatcher::DescriptorDistance(vDescriptors[i], vDescriptors[j]);
357  Distances[i][j] = (float)distij;
358  Distances[j][i] = (float)distij;
359  }
360  }
361 #else
362  const size_t N = vDescriptors.size();
363 
364  float Distances[N][N];
365  for (size_t i = 0; i < N; i++)
366  {
367  Distances[i][i] = 0;
368  for (size_t j = i + 1; j < N; j++)
369  {
370  int distij = ORBmatcher::DescriptorDistance(vDescriptors[i], vDescriptors[j]);
371  Distances[i][j] = distij;
372  Distances[j][i] = distij;
373  }
374  }
375 #endif
376  // Take the descriptor with least median distance to the rest
377  int BestMedian = INT_MAX;
378  int BestIdx = 0;
379  for (size_t i = 0; i < N; i++)
380  {
381  vector<int> vDists(Distances[i], Distances[i] + N);
382  sort(vDists.begin(), vDists.end());
383  int median = vDists[(uint64_t)(0.5 * (N - 1))];
384 
385  if (median < BestMedian)
386  {
387  BestMedian = median;
388  BestIdx = (int)i;
389  }
390  }
391 
392  //free Distances
393 #ifdef _WINDOWS
394  for (size_t i = 0; i < N; ++i)
395  delete Distances[i];
396  delete[] Distances;
397 #endif
398 
399  {
400  unique_lock<mutex> lock(mMutexFeatures);
401  mDescriptor = vDescriptors[BestIdx].clone();
402  }
403 }
404 //-----------------------------------------------------------------------------
406 {
407  unique_lock<mutex> lock(mMutexFeatures);
408  return mDescriptor.clone();
409 }
410 //-----------------------------------------------------------------------------
411 void WAIMapPoint::SetDescriptor(const cv::Mat& descriptor)
412 {
413  unique_lock<mutex> lock(mMutexFeatures);
414  descriptor.copyTo(mDescriptor);
415 }
416 //-----------------------------------------------------------------------------
418 {
419  unique_lock<mutex> lock(mMutexFeatures);
420  if (mObservations.count(pKF))
421  return (int)mObservations[pKF];
422  else
423  return -1;
424 }
425 //-----------------------------------------------------------------------------
427 {
428  unique_lock<mutex> lock(mMutexFeatures);
429  return (mObservations.count(pKF));
430 }
431 //-----------------------------------------------------------------------------
432 //we calculate normal and depth from
434 {
435  map<WAIKeyFrame*, size_t> observations;
436  WAIKeyFrame* pRefKF;
437  cv::Mat Pos;
438  {
439  unique_lock<mutex> lock1(mMutexFeatures);
440  unique_lock<mutex> lock2(mMutexPos);
441  if (mbBad)
442  return;
443  observations = mObservations;
444  pRefKF = mpRefKF;
445  Pos = mWorldPos.clone();
446  }
447 
448  if (observations.empty())
449  return;
450 
451  cv::Mat normal = cv::Mat::zeros(3, 1, CV_32F);
452  int n = 0;
453  for (map<WAIKeyFrame*, size_t>::iterator mit = observations.begin(), mend = observations.end(); mit != mend; mit++)
454  {
455  WAIKeyFrame* pKF = mit->first;
456  cv::Mat Owi = pKF->GetCameraCenter();
457  cv::Mat normali = mWorldPos - Owi;
458  normal = normal + normali / cv::norm(normali);
459  n++;
460  }
461 
462  cv::Mat PC = Pos - pRefKF->GetCameraCenter();
463  const float dist = (float)cv::norm(PC);
464  const int level = pRefKF->mvKeysUn[observations[pRefKF]].octave;
465  const float levelScaleFactor = pRefKF->mvScaleFactors[level];
466  const int nLevels = pRefKF->mnScaleLevels;
467 
468  {
469  unique_lock<mutex> lock3(mMutexPos);
470  mfMaxDistance = dist * levelScaleFactor;
471  mfMinDistance = mfMaxDistance / pRefKF->mvScaleFactors[nLevels - 1];
472  mNormalVector = normal / n;
473  }
474 }
475 //-----------------------------------------------------------------------------
477 {
478  unique_lock<mutex> lock(mMutexPos);
479  return 0.8f * mfMinDistance;
480 }
481 //-----------------------------------------------------------------------------
483 {
484  unique_lock<mutex> lock(mMutexPos);
485  return 1.2f * mfMaxDistance;
486 }
487 //-----------------------------------------------------------------------------
489 {
490  return mfMinDistance;
491 }
492 //-----------------------------------------------------------------------------
494 {
495  return mfMaxDistance;
496 }
497 //-----------------------------------------------------------------------------
498 void WAIMapPoint::SetMaxDistance(float maxDist)
499 {
500  mfMaxDistance = maxDist;
501 }
502 //-----------------------------------------------------------------------------
503 void WAIMapPoint::SetMinDistance(float minDist)
504 {
505  mfMinDistance = minDist;
506 }
507 //-----------------------------------------------------------------------------
508 int WAIMapPoint::PredictScale(const float& currentDist, WAIKeyFrame* pKF)
509 {
510  float ratio;
511  {
512  unique_lock<mutex> lock(mMutexPos);
513  ratio = mfMaxDistance / currentDist;
514  }
515 
516  int nScale = (int)ceil(log(ratio) / pKF->mfLogScaleFactor);
517  if (nScale < 0)
518  nScale = 0;
519  else if (nScale >= pKF->mnScaleLevels)
520  nScale = pKF->mnScaleLevels - 1;
521 
522  return nScale;
523 }
524 //-----------------------------------------------------------------------------
525 int WAIMapPoint::PredictScale(const float& currentDist, WAIFrame* pF)
526 {
527  float ratio;
528  {
529  unique_lock<mutex> lock(mMutexPos);
530  ratio = mfMaxDistance / currentDist;
531  }
532 
533  int nScale = (int)ceil(log(ratio) / pF->mfLogScaleFactor);
534  if (nScale < 0)
535  nScale = 0;
536  else if (nScale >= pF->mnScaleLevels)
537  nScale = pF->mnScaleLevels - 1;
538 
539  return nScale;
540 }
541 //-----------------------------------------------------------------------------
542 size_t WAIMapPoint::getSizeOfCvMat(const cv::Mat& mat)
543 {
544  size_t size = 0;
545  if (mat.isContinuous())
546  size = mat.total() * mat.elemSize();
547  else
548  {
549  size = mat.step[0] * mat.rows;
550  }
551  return size;
552 }
553 //-----------------------------------------------------------------------------
555 {
556  size_t size = 0;
557 
558  size += sizeof(*this);
559  size += getSizeOfCvMat(mWorldPos);
560  size += getSizeOfCvMat(mNormalVector);
561  size += getSizeOfCvMat(mDescriptor);
562  size += getSizeOfCvMat(mPosGBA);
563 
564  return size;
565 }
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