SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
WAIFrame.cpp
Go to the documentation of this file.
1 /**
2  * \file WAIFrame.cpp
3  * \authors Raúl Mur-Artal, Michael Goettlicher
4  * \date Dez 2017
5 // Codestyle: https://github.com/cpvrlab/SLProject/wiki/Coding-Style-Guidelines
6  * \authors Marcus Hudritsch, Michael Goettlicher
7  * \copyright http://opensource.org/licenses/GPL-3.0
8 */
9 /**
10  * This file is part of ORB-SLAM2.
11  *
12  * Copyright (C) 2014-2016 Raúl Mur-Artal <raulmur at unizar dot es> (University of Zaragoza)
13  * For more information see <https://github.com/raulmur/ORB_SLAM2>
14  *
15  * ORB-SLAM2 is free software: you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation, either version 3 of the License, or
18  * (at your option) any later version.
19  *
20  * ORB-SLAM2 is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with ORB-SLAM2. If not, see <http://www.gnu.org/licenses/>.
27  */
28 
29 #include <WAIFrame.h>
30 #include <WAIMapPoint.h>
31 #include <orb_slam/Converter.h>
32 #include <AverageTiming.h>
33 
34 using namespace cv;
35 
36 //static data members
37 float WAIFrame::fx = 0.0f;
38 float WAIFrame::fy = 0.0f;
39 float WAIFrame::cx = 0.0f;
40 float WAIFrame::cy = 0.0f;
41 float WAIFrame::invfx = 0.0f;
42 float WAIFrame::invfy = 0.0f;
45 long unsigned int WAIFrame::nNextId = 0;
46 float WAIFrame::mnMinX = 0.0f;
47 float WAIFrame::mnMaxX = 0.0f;
48 float WAIFrame::mnMinY = 0.0f;
49 float WAIFrame::mnMaxY = 0.0f;
51 
52 //-----------------------------------------------------------------------------
54 {
55 }
56 //-----------------------------------------------------------------------------
57 //Copy Constructor
59  : mVocabulary(frame.mVocabulary),
60  mpORBextractorLeft(frame.mpORBextractorLeft),
61  mTimeStamp(frame.mTimeStamp),
62  mK(frame.mK.clone()),
63  mDistCoef(frame.mDistCoef.clone()),
64  N(frame.N),
65  mvKeys(frame.mvKeys),
66  mvKeysUn(frame.mvKeysUn), /*mvuRight(frame.mvuRight),
67  mvDepth(frame.mvDepth),*/
68  mBowVec(frame.mBowVec),
69  mFeatVec(frame.mFeatVec),
70  mDescriptors(frame.mDescriptors.clone()),
71  mvpMapPoints(frame.mvpMapPoints),
72  mnId(frame.mnId),
73  mpReferenceKF(frame.mpReferenceKF),
74  mnScaleLevels(frame.mnScaleLevels),
75  mfScaleFactor(frame.mfScaleFactor),
76  mfLogScaleFactor(frame.mfLogScaleFactor),
77  mvScaleFactors(frame.mvScaleFactors),
78  mvInvScaleFactors(frame.mvInvScaleFactors),
79  mvLevelSigma2(frame.mvLevelSigma2),
80  mvInvLevelSigma2(frame.mvInvLevelSigma2)
81 {
82  for (int i = 0; i < FRAME_GRID_COLS; i++)
83  for (int j = 0; j < FRAME_GRID_ROWS; j++)
84  mGrid[i][j] = frame.mGrid[i][j];
85 
86  if (!frame.mTcw.empty())
87  SetPose(frame.mTcw);
88 
89  if (!frame.imgGray.empty())
90  imgGray = frame.imgGray.clone();
91 }
92 //-----------------------------------------------------------------------------
93 WAIFrame::WAIFrame(const cv::Mat& imGray, const double& timeStamp, KPextractor* extractor, cv::Mat& K, cv::Mat& distCoef, WAIOrbVocabulary* vocabulary, bool retainImg)
94  : mpORBextractorLeft(extractor), mTimeStamp(timeStamp), /*mK(K.clone()),*/ /*mDistCoef(distCoef.clone()),*/
95  mVocabulary(vocabulary)
96 {
97  AVERAGE_TIMING_START("WAIFrame");
98  //ghm1: ORB_SLAM uses float precision
99  K.convertTo(mK, CV_32F);
100  distCoef.convertTo(mDistCoef, CV_32F);
101 
102  // Frame ID
103  mnId = nNextId++;
104 
105  // Scale Level Info
106  mnScaleLevels = mpORBextractorLeft->GetLevels();
107  mfScaleFactor = mpORBextractorLeft->GetScaleFactor();
109  mvScaleFactors = mpORBextractorLeft->GetScaleFactors();
110  mvInvScaleFactors = mpORBextractorLeft->GetInverseScaleFactors();
111  mvLevelSigma2 = mpORBextractorLeft->GetScaleSigmaSquares();
112  mvInvLevelSigma2 = mpORBextractorLeft->GetInverseScaleSigmaSquares();
113 
114  // ORB extraction
115  ExtractFeaturePoints(imGray);
116 
117  N = (int)mvKeys.size();
118 
119  if (mvKeys.empty())
120  {
121  AVERAGE_TIMING_STOP("WAIFrame");
122  return;
123  }
124 
126 
127  mvpMapPoints = vector<WAIMapPoint*>(N, static_cast<WAIMapPoint*>(NULL));
128 
129  // This is done only for the first Frame (or after a change in the calibration)
131  {
132  ComputeImageBounds(imGray);
133 
134  mfGridElementWidthInv = static_cast<float>(FRAME_GRID_COLS) / (mnMaxX - mnMinX);
135  mfGridElementHeightInv = static_cast<float>(FRAME_GRID_ROWS) / (mnMaxY - mnMinY);
136 
137  fx = mK.at<float>(0, 0);
138  fy = mK.at<float>(1, 1);
139  cx = mK.at<float>(0, 2);
140  cy = mK.at<float>(1, 2);
141  invfx = 1.0f / fx;
142  invfy = 1.0f / fy;
143 
144  mbInitialComputations = false;
145  }
146 
148 
149  //store image reference if required
150  if (retainImg)
151  imgGray = imGray.clone();
152 
153  AVERAGE_TIMING_STOP("WAIFrame");
154 }
155 //-----------------------------------------------------------------------------
157 {
158  int nReserve = (int)(0.5f * N / (FRAME_GRID_COLS * FRAME_GRID_ROWS));
159  for (unsigned int i = 0; i < FRAME_GRID_COLS; i++)
160  for (unsigned int j = 0; j < FRAME_GRID_ROWS; j++)
161  mGrid[i][j].reserve(nReserve);
162 
163  for (int i = 0; i < N; i++)
164  {
165  const cv::KeyPoint& kp = mvKeysUn[i];
166 
167  int nGridPosX, nGridPosY;
168  if (PosInGrid(kp, nGridPosX, nGridPosY))
169  mGrid[nGridPosX][nGridPosY].push_back(i);
170  }
171 }
172 //-----------------------------------------------------------------------------
173 void WAIFrame::ExtractFeaturePoints(const cv::Mat& im)
174 {
175  (*mpORBextractorLeft)(im, mvKeys, mDescriptors);
176 }
177 //-----------------------------------------------------------------------------
178 void WAIFrame::SetPose(cv::Mat Tcw)
179 {
180  mTcw = Tcw.clone();
182 }
183 //-----------------------------------------------------------------------------
185 {
186  mRcw = mTcw.rowRange(0, 3).colRange(0, 3);
187  mRwc = mRcw.t();
188  mtcw = mTcw.rowRange(0, 3).col(3);
189  mOw = -mRwc * mtcw;
190 }
191 //-----------------------------------------------------------------------------
192 bool WAIFrame::isInFrustum(WAIMapPoint* pMP, float viewingCosLimit)
193 {
194  pMP->mbTrackInView = false;
195 
196  // 3D in absolute coordinates
197  cv::Mat P = pMP->GetWorldPos();
198 
199  // 3D in camera coordinates
200  const cv::Mat Pc = mRcw * P + mtcw;
201  const float& PcX = Pc.at<float>(0);
202  const float& PcY = Pc.at<float>(1);
203  const float& PcZ = Pc.at<float>(2);
204 
205  // Check positive depth
206  if (PcZ < 0.0f)
207  return false;
208 
209  // Project in image and check it is not outside
210  const float invz = 1.0f / PcZ;
211  const float u = fx * PcX * invz + cx;
212  const float v = fy * PcY * invz + cy;
213 
214  if (u < mnMinX || u > mnMaxX)
215  return false;
216  if (v < mnMinY || v > mnMaxY)
217  return false;
218 
219  // Check distance is in the scale invariance region of the WAIMapPoint
220  const float maxDistance = pMP->GetMaxDistanceInvariance();
221  const float minDistance = pMP->GetMinDistanceInvariance();
222  const cv::Mat PO = P - mOw;
223  const float dist = (float)cv::norm(PO);
224 
225  if (dist < minDistance || dist > maxDistance)
226  return false;
227 
228  // Check viewing angle
229  cv::Mat Pn = pMP->GetNormal();
230 
231  const float viewCos = (float)(PO.dot(Pn) / dist);
232 
233  if (viewCos < viewingCosLimit)
234  return false;
235 
236  // Predict scale in the image
237  const int nPredictedLevel = pMP->PredictScale(dist, this);
238 
239  // Data used by the tracking
240  pMP->mbTrackInView = true;
241  pMP->mTrackProjX = u;
242  //pMP->mTrackProjXR = u - mbf*invz;
243  pMP->mTrackProjY = v;
244  pMP->mnTrackScaleLevel = nPredictedLevel;
245  pMP->mTrackViewCos = viewCos;
246 
247  return true;
248 }
249 //-----------------------------------------------------------------------------
250 vector<size_t> WAIFrame::GetFeaturesInArea(const float& x, const float& y, const float& r, const int minLevel, const int maxLevel) const
251 {
252  vector<size_t> vIndices;
253  vIndices.reserve(N);
254 
255  const int nMinCellX = max(0, (int)floor((x - mnMinX - r) * mfGridElementWidthInv));
256  if (nMinCellX >= FRAME_GRID_COLS)
257  return vIndices;
258 
259  const int nMaxCellX = min((int)FRAME_GRID_COLS - 1, (int)ceil((x - mnMinX + r) * mfGridElementWidthInv));
260  if (nMaxCellX < 0)
261  return vIndices;
262 
263  const int nMinCellY = max(0, (int)floor((y - mnMinY - r) * mfGridElementHeightInv));
264  if (nMinCellY >= FRAME_GRID_ROWS)
265  return vIndices;
266 
267  const int nMaxCellY = min((int)FRAME_GRID_ROWS - 1, (int)ceil((y - mnMinY + r) * mfGridElementHeightInv));
268  if (nMaxCellY < 0)
269  return vIndices;
270 
271  const bool bCheckLevels = (minLevel > 0) || (maxLevel >= 0);
272 
273  for (int ix = nMinCellX; ix <= nMaxCellX; ix++)
274  {
275  for (int iy = nMinCellY; iy <= nMaxCellY; iy++)
276  {
277  const vector<size_t> vCell = mGrid[ix][iy];
278  if (vCell.empty())
279  continue;
280 
281  for (size_t j = 0, jend = vCell.size(); j < jend; j++)
282  {
283  const cv::KeyPoint& kpUn = mvKeysUn[vCell[j]];
284  if (bCheckLevels)
285  {
286  if (kpUn.octave < minLevel)
287  continue;
288  if (maxLevel >= 0)
289  if (kpUn.octave > maxLevel)
290  continue;
291  }
292 
293  const float distx = kpUn.pt.x - x;
294  const float disty = kpUn.pt.y - y;
295 
296  if (fabs(distx) < r && fabs(disty) < r)
297  vIndices.push_back(vCell[j]);
298  }
299  }
300  }
301 
302  return vIndices;
303 }
304 //-----------------------------------------------------------------------------
305 bool WAIFrame::PosInGrid(const cv::KeyPoint& kp, int& posX, int& posY)
306 {
307  posX = (int)round((kp.pt.x - mnMinX) * mfGridElementWidthInv);
308  posY = (int)round((kp.pt.y - mnMinY) * mfGridElementHeightInv);
309 
310  //Keypoint's coordinates are undistorted, which could cause to go out of the image
311  if (posX < 0 || posX >= FRAME_GRID_COLS || posY < 0 || posY >= FRAME_GRID_ROWS)
312  return false;
313 
314  return true;
315 }
316 //-----------------------------------------------------------------------------
318 {
319  if (!mBowVec.isFill)
320  {
321  //vector<cv::Mat> vCurrentDesc = Converter::toDescriptorVector(mDescriptors);
322  // Luc: In a 6 levels and 10 branch per level voc, 4 levelup mean the 2nd level from the top
323  // that make a total of 100 words. More words means more variance between keyframe and less
324  // preselected keyframe but that will make also the relocalization less invariant to changes
325 
327  }
328 }
329 //-----------------------------------------------------------------------------
331 {
332  if (mDistCoef.at<float>(0) == 0.0f)
333  {
334  mvKeysUn = mvKeys;
335  return;
336  }
337 
338  // Fill matrix with points
339  cv::Mat mat(N, 2, CV_32F);
340  for (int i = 0; i < N; i++)
341  {
342  mat.at<float>(i, 0) = mvKeys[i].pt.x;
343  mat.at<float>(i, 1) = mvKeys[i].pt.y;
344  }
345 
346  // Undistort points
347  mat = mat.reshape(2);
348  cv::undistortPoints(mat, mat, mK, mDistCoef, cv::Mat(), mK);
349  mat = mat.reshape(1);
350 
351  // Fill undistorted keypoint vector
352  mvKeysUn.resize(N);
353  for (int i = 0; i < N; i++)
354  {
355  cv::KeyPoint kp = mvKeys[i];
356  kp.pt.x = mat.at<float>(i, 0);
357  kp.pt.y = mat.at<float>(i, 1);
358  mvKeysUn[i] = kp;
359  }
360 }
361 //-----------------------------------------------------------------------------
362 void WAIFrame::ComputeImageBounds(const cv::Mat& imLeft)
363 {
364  if (mDistCoef.at<float>(0) != 0.0)
365  {
366  cv::Mat mat(4, 2, CV_32F);
367  mat.at<float>(0, 0) = 0.0;
368  mat.at<float>(0, 1) = 0.0;
369  mat.at<float>(1, 0) = (float)imLeft.cols;
370  mat.at<float>(1, 1) = 0.0;
371  mat.at<float>(2, 0) = 0.0;
372  mat.at<float>(2, 1) = (float)imLeft.rows;
373  mat.at<float>(3, 0) = (float)imLeft.cols;
374  mat.at<float>(3, 1) = (float)imLeft.rows;
375 
376  // Undistort corners
377  mat = mat.reshape(2);
378  cv::undistortPoints(mat, mat, mK, mDistCoef, cv::Mat(), mK);
379  mat = mat.reshape(1);
380 
381  mnMinX = (float)min(mat.at<float>(0, 0), mat.at<float>(2, 0));
382  mnMaxX = (float)max(mat.at<float>(1, 0), mat.at<float>(3, 0));
383  mnMinY = (float)min(mat.at<float>(0, 1), mat.at<float>(1, 1));
384  mnMaxY = (float)max(mat.at<float>(2, 1), mat.at<float>(3, 1));
385  }
386  else
387  {
388  mnMinX = 0.0f;
389  mnMaxX = (float)imLeft.cols;
390  mnMinY = 0.0f;
391  mnMaxY = (float)imLeft.rows;
392  }
393 }
394 //-----------------------------------------------------------------------------
#define AVERAGE_TIMING_STOP(name)
Definition: AverageTiming.h:97
#define AVERAGE_TIMING_START(name)
Definition: AverageTiming.h:96
#define FRAME_GRID_COLS
Definition: WAIFrame.h:44
#define FRAME_GRID_ROWS
Definition: WAIFrame.h:43
cv::Mat mTcw
Definition: WAIFrame.h:155
float mfScaleFactor
Definition: WAIFrame.h:169
void UpdatePoseMatrices()
Definition: WAIFrame.cpp:184
static float cx
Definition: WAIFrame.h:116
WAIFeatVector mFeatVec
Definition: WAIFrame.h:138
static float fx
Definition: WAIFrame.h:114
cv::Mat mDescriptors
Definition: WAIFrame.h:141
cv::Mat mtcw
Definition: WAIFrame.h:201
cv::Mat mRcw
Definition: WAIFrame.h:200
int mnScaleLevels
Definition: WAIFrame.h:168
std::vector< float > mvScaleFactors
Definition: WAIFrame.h:171
static float mnMaxX
Definition: WAIFrame.h:178
static float fy
Definition: WAIFrame.h:115
static float cy
Definition: WAIFrame.h:117
cv::Mat mDistCoef
Definition: WAIFrame.h:120
std::vector< float > mvLevelSigma2
Definition: WAIFrame.h:173
static float mnMinY
Definition: WAIFrame.h:179
std::vector< WAIMapPoint * > mvpMapPoints
Definition: WAIFrame.h:147
long unsigned int mnId
Definition: WAIFrame.h:159
bool isInFrustum(WAIMapPoint *pMP, float viewingCosLimit)
Definition: WAIFrame.cpp:192
WAIBowVector mBowVec
Definition: WAIFrame.h:137
static float mfGridElementHeightInv
Definition: WAIFrame.h:151
cv::Mat imgGray
Definition: WAIFrame.h:185
static float invfx
Definition: WAIFrame.h:118
std::vector< float > mvInvScaleFactors
Definition: WAIFrame.h:172
std::vector< cv::KeyPoint > mvKeys
Definition: WAIFrame.h:128
std::vector< size_t > GetFeaturesInArea(const float &x, const float &y, const float &r, const int minLevel=-1, const int maxLevel=-1) const
Definition: WAIFrame.cpp:250
std::vector< std::size_t > mGrid[64][36]
Definition: WAIFrame.h:152
static float mnMaxY
Definition: WAIFrame.h:180
void AssignFeaturesToGrid()
Definition: WAIFrame.cpp:156
static long unsigned int nNextId
Definition: WAIFrame.h:158
std::vector< float > mvInvLevelSigma2
Definition: WAIFrame.h:174
void ComputeBoW()
Definition: WAIFrame.cpp:317
WAIOrbVocabulary * mVocabulary
Definition: WAIFrame.h:104
KPextractor * mpORBextractorLeft
Definition: WAIFrame.h:107
WAIFrame()
Definition: WAIFrame.cpp:53
void ExtractFeaturePoints(const cv::Mat &im)
Definition: WAIFrame.cpp:173
cv::Mat mK
Definition: WAIFrame.h:113
static float mnMinX
Definition: WAIFrame.h:177
void UndistortKeyPoints()
Definition: WAIFrame.cpp:330
int N
Definition: WAIFrame.h:123
static float mfGridElementWidthInv
Definition: WAIFrame.h:150
bool PosInGrid(const cv::KeyPoint &kp, int &posX, int &posY)
Definition: WAIFrame.cpp:305
std::vector< cv::KeyPoint > mvKeysUn
Definition: WAIFrame.h:129
cv::Mat mRwc
Definition: WAIFrame.h:202
float mfLogScaleFactor
Definition: WAIFrame.h:170
void ComputeImageBounds(const cv::Mat &imLeft)
Definition: WAIFrame.cpp:362
void SetPose(cv::Mat Tcw)
Definition: WAIFrame.cpp:178
static bool mbInitialComputations
Definition: WAIFrame.h:182
cv::Mat mOw
Definition: WAIFrame.h:203
static float invfy
Definition: WAIFrame.h:119
float GetMaxDistanceInvariance()
int PredictScale(const float &currentDist, WAIKeyFrame *pF)
cv::Mat GetNormal()
int mnTrackScaleLevel
Definition: WAIMapPoint.h:121
float mTrackProjX
Definition: WAIMapPoint.h:116
float GetMinDistanceInvariance()
float mTrackProjY
Definition: WAIMapPoint.h:117
float mTrackViewCos
Definition: WAIMapPoint.h:122
cv::Mat GetWorldPos()
bool mbTrackInView
Definition: WAIMapPoint.h:120
void transform(const cv::Mat &descriptors, WAIBowVector &bow, WAIFeatVector &feat)
T ceil(T a)
Definition: Utils.h:247
T floor(T a)
Definition: Utils.h:246
void log(const char *tag, const char *format,...)
logs a formatted string platform independently
Definition: Utils.cpp:1103