ORB SLAM2 關鍵問題之特徵匹配

2021-10-06 08:27:33 字數 3312 閱讀 2996

在單目初始化中用來尋找初始化兩幀匹配的函式.

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...