ORB-SLAM2代碼閱讀筆記:PnPSolver

  • PnPsolver::PnPsolver(const Frame &F, const vector<MapPoint*> &vpMapPointMatches):
    pws(0), us(0), alphas(0), pcs(0), //這里的四個變量都是指針啊,直接這樣子寫的原因可以參考函數(shù) set_maximum_number_of_correspondences()
    maximum_number_of_correspondences(0), number_of_correspondences(0), mnInliersi(0),
    mnIterations(0), mnBestInliers(0), N(0)
    構(gòu)造函數(shù)取出2維特征點系宫,世界坐標系下的3D點兵志,只記錄坐標,特征點在哪一層取出來的,調(diào)用SetRansacParameters(),設(shè)置默認的RANSAC參數(shù),這個和Sim3Solver中的操作是相同的
  • void PnPsolver::SetRansacParameters(double probability, int minInliers, int maxIterations, int minSet, float epsilon, float th2)
    設(shè)置RANSAC迭代的參數(shù):
    • 獲取給定的參數(shù)
    • 計算理論內(nèi)點數(shù)
    • 調(diào)整內(nèi)點數(shù)/總體數(shù)比例
    • 計算理論迭代次數(shù)
    • 計算不同圖層上的特征點在進行內(nèi)點檢驗時使用的不同判斷誤差閾值
  • double PnPsolver::compute_pose(double R[3][3], double t[3])
    根據(jù)類成員變量中給出的匹配點,計算相機位姿
    • 獲取EPnP算法中的四個控制點
    • 計算世界坐標系下每個3D點用4個控制點線性表達時的系數(shù)alphas
    • 構(gòu)造M矩陣,EPnP原始論文中公式(3)(4)-->(5)(6)(7); 矩陣的大小為 2n*12 ,n 為使用的匹配點的對數(shù)
    • 求解Mx = 0,x是控制點在相機坐標系下組成的向量
    • x=\sum_{i=1}^N\beta_iv_i,v_i是M特征向量,beta需要分N=1、2孽锥、3、4計算
    • 根據(jù)匹配點在相機坐標系下的坐標以及在世界坐標系下的坐標细层,然后根據(jù)ICP算法求得相機位姿惜辑。
  • void PnPsolver::choose_control_points(void)
    從給定的匹配點中計算出四個控制點
    • 第一個控制點為所有3D點幾何中心
    // 遍歷每個匹配點中的3D點,然后對每個坐標軸加和
  for(int i = 0; i < number_of_correspondences; i++)
    for(int j = 0; j < 3; j++)
      cws[0][j] += pws[3 * i + j];
  // 再對每個軸上取均值
  for(int j = 0; j < 3; j++)
    cws[0][j] /= number_of_correspondences;
- 其它三個控制點疫赎,C1, C2, C3通過PCA分解得到
// 將所有的3D參考點寫成矩陣盛撑,(number_of_correspondences * 3)的矩陣
  CvMat * PW0 = cvCreateMat(number_of_correspondences, 3, CV_64F);

  double pw0tpw0[3 * 3], dc[3], uct[3 * 3];         // 下面變量的數(shù)據(jù)區(qū)
  CvMat PW0tPW0 = cvMat(3, 3, CV_64F, pw0tpw0);     // 如變量名所示.其實這里使用cv::Mat格式主要是為了進行SVD分解
  CvMat DC      = cvMat(3, 1, CV_64F, dc);          // 分解上面矩陣得到的奇異值組成的矩陣
  CvMat UCt     = cvMat(3, 3, CV_64F, uct);         // 分解上面矩陣得到的左奇異矩陣

  // step 2.1:將存在pws中的參考3D點減去第一個控制點的坐標(相當于把第一個控制點作為原點), 并存入PW0
  for(int i = 0; i < number_of_correspondences; i++)
    for(int j = 0; j < 3; j++)
      PW0->data.db[3 * i + j] = pws[3 * i + j] - cws[0][j];

  // step 2.2:利用SVD分解P'P可以獲得P的主分量
  cvMulTransposed(PW0, &PW0tPW0, 1);
  cvSVD(&PW0tPW0,                         // A
        &DC,                              // W
        &UCt,                             // U
        0,                                // V
        CV_SVD_MODIFY_A | CV_SVD_U_T);    // flags

  cvReleaseMat(&PW0);

  // step 2.3:得到C1, C2, C3三個3D控制點,最后加上之前減掉的第一個控制點這個偏移量
  // 講道理這里的條件不應寫成4,而應該是變量 number_of_correspondences 啊
  for(int i = 1; i < 4; i++) {
    // 這里也是只有前三個奇異值 
    double k = sqrt(dc[i - 1] / number_of_correspondences);
    for(int j = 0; j < 3; j++)
      //? 但是這里為什么要乘k捧搞?
      cws[i][j] = cws[0][j] + k * uct[3 * (i - 1) + j];
  • void PnPsolver::compute_barycentric_coordinates(void)
    求解四個控制點的系數(shù)alphas
    每個三維點可以通過下面式子算出和控制點之間的關(guān)系:


    image

具體推導過程見 https://blog.csdn.net/qq_30356613/article/details/80588134

  • void PnPsolver::fill_M(CvMat * M,
    const int row, const double * as, const double u, const double v)
    填充最小二乘的M矩陣抵卫,對每一個3D參考點,Mx=0胎撇,x為四個控制點組成的向量1*12:


    image

M推導過程見 https://blog.csdn.net/qq_30356613/article/details/80588134

double PnPsolver::compute_R_and_t(const double * ut, const double * betas,double R[3][3], double t[3])
根據(jù)已經(jīng)得到的控制點在當前相機坐標系下的坐標來恢復出相機的位姿

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末介粘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子晚树,更是在濱河造成了極大的恐慌姻采,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件爵憎,死亡現(xiàn)場離奇詭異慨亲,居然都是意外死亡,警方通過查閱死者的電腦和手機宝鼓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門刑棵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人愚铡,你說我怎么就攤上這事铐望。” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵正蛙,是天一觀的道長。 經(jīng)常有香客問我营曼,道長乒验,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任蒂阱,我火速辦了婚禮锻全,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘录煤。我一直安慰自己鳄厌,他們只是感情好,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布妈踊。 她就那樣靜靜地躺著了嚎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪廊营。 梳的紋絲不亂的頭發(fā)上歪泳,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天,我揣著相機與錄音露筒,去河邊找鬼呐伞。 笑死,一個胖子當著我的面吹牛慎式,可吹牛的內(nèi)容都是我干的伶氢。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼瘪吏,長吁一口氣:“原來是場噩夢啊……” “哼癣防!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起肪虎,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤劣砍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后扇救,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體刑枝,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年迅腔,在試婚紗的時候發(fā)現(xiàn)自己被綠了装畅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡沧烈,死狀恐怖掠兄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤蚂夕,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布迅诬,位于F島的核電站,受9級特大地震影響婿牍,放射性物質(zhì)發(fā)生泄漏侈贷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一等脂、第九天 我趴在偏房一處隱蔽的房頂上張望俏蛮。 院中可真熱鬧,春花似錦上遥、人聲如沸搏屑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辣恋。三九已至,卻和暖如春解幼,著一層夾襖步出監(jiān)牢的瞬間抑党,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工撵摆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留底靠,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓特铝,卻偏偏與公主長得像暑中,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子鲫剿,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容