在單目初始化中用來尋找初始化兩幀匹配的函式.
int orbmatcher::searchforinitialization(frame &f1, frame &f2, vectorcv::point2f &vbprevmatched, vector &vnmatches12, int windowsize)
引數:vbprevmatched 輸入是f1中特徵點的座標 , 在函式執行完畢後 修改為與f1的特徵點匹配的f2特徵點的座標.
vnmatches12 兩幀之間的匹配關係 ???
windowsize 搜尋視窗的大小
return int 匹配成功的點的個數
流程:構建旋轉直方圖,用於篩選錯誤匹配
對於兩幀影象匹配的特徵點, 匹配的特徵點之間的旋轉也應該非常接近,
// 構建旋轉直方圖
vector<
int> rothist[
histo_length];
for(
int i=
0;i) rothist[i]
.reserve
(500);
const
float factor = histo_length/
360.0f
;
遍歷幀1所有特徵點 為幀1 每個特徵點尋找與幀二特徵點的匹配
首先獲取幀1特徵點以及所在的金字塔層數
// 遍歷幀1所有特徵點 為幀1 每個特徵點尋找匹配
for(size_t i1=
0, iend1=f1.mvkeysun.
size()
; i1)else
if(dist}
這裡有個細節, vmatcheddistance記錄了當前f2幀所有特徵點匹配的最近距離,
所以每次求得與f2某特徵點匹配距離後, 都去vmatcheddistance查詢一下是否小於該特徵點匹配的最優距離,
如果距離大於最優距離,就可以直接跳過了.
4. 檢查匹配的最近距離是否小於閾值, 同時最優距離應該遠小於次優距離 ,
接著:更新 vnmatches21 vnmatches12 vmatcheddistance 容器.
雖然,之前已經有匹配了,但是現在的匹配更好,那麼就要把原配給剔掉,換乙個新的.
// 如果該特徵點已經有匹配了 則將該匹配丟棄 因為 當前匹配的距離肯定小於之前匹配的距離
if(vnmatches21[bestidx2]
>=0)
// 設定為本次的匹配
vnmatches12[i1]
=bestidx2;
vnmatches21[bestidx2]
=i1;
// idx 為匹配的f2上特徵點的序號
vmatcheddistance[bestidx2]
=bestdist;
nmatches++
;
構建旋轉直方圖,後面要進行檢查篩選匹配
// 每乙個匹配點對都統一記錄一下旋轉差
if(mbcheckorientation)
檢查旋轉直方圖 , 將直方圖中旋轉值最多的3個index的特徵點保留,其他的認為有誤直接剔除.
更新 vbprevmatched ,vbprevmatched 儲存與f1的特徵點匹配的f2特徵點的座標
找到當前frame中, 在 以x,y為中心,半徑為r的圓形內且在[minlevel, maxlevel]的特徵點, 返回值是 特徵點在 該幀
mvkeysun容器中的序號.
vectorframe::getfeaturesinarea(const float &x, const float &y, const float &r, const int minlevel, const int maxlevel) const
還記得在構建frame的時候要將特徵點放置到 std::vector< std::size_t> mgrid 中吧, 下面就是它發揮作用的時候了, 將包圍搜尋圓的全部cell找出來, 那麼我們要匹配的特徵點就一定在這些cell中了.
// floor() 返回小於引數的最大整數
const
int nmincellx =
max(0,
(int
)floor
((x-mnminx-r)
*mfgridelementwidthinv));
if(nmincellx>=frame_grid_cols)
return vindices;
const
int nmaxcellx =
min(
(int
)frame_grid_cols-1,
(int
)ceil
((x-mnminx+r)
*mfgridelementwidthinv));
if(nmaxcellx<0)
return vindices;
const
int nmincelly =
max(0,
(int
)floor
((y-mnminy-r)
*mfgridelementheightinv));
if(nmincelly>=frame_grid_rows)
return vindices;
const
int nmaxcelly =
min(
(int
)frame_grid_rows-1,
(int
)ceil
((y-mnminy+r)
*mfgridelementheightinv));
if(nmaxcelly<0)
return vindices;
遍歷之前找出的全部cell, 找出合適的匹配.
// 遍歷該圓區域所在的cell
for(
int ix = nmincellx; ix<=nmaxcellx; ix++
)// 檢查距離
const
float distx = kpun.pt.x-x;
const
float disty = kpun.pt.y-y;if(
fabs
(distx)
fabs
(disty)
vindices.
push_back
(vcell[j]);
}}}
ORB SLAM2 關鍵問題之初始化
初始化在tracking執行緒的track 函式中完成.void tracking stereoinitialization 步驟 1 特徵點數大於500才開始初始化,構建初始關鍵幀,並設定pose為單位陣,並將初始關鍵幀新增到map中.整個函式只有在當前幀的特徵點超過500的時候才會進行 if m...
ORBSLAM2之LocalMapping執行緒
一 處理新關鍵幀processnewkeyframe 五 區域性ba 六 刪除冗餘關鍵幀keyframeculling 七 將當前關鍵幀插入閉環檢測佇列 更新當前關鍵幀的共檢視updateconnections a 遍歷當前關鍵幀的mp,更新共檢視 b 更新當前關鍵幀的子關鍵幀與父關鍵幀 i.與當前...
ORB SLAM2安裝問題總結
rosbuild building package orb slam master rosbuild error from directory check opt ros kinetic share ros core rosbuild bin check same directories.py ho...