OpenCV學習筆記(11)OpenCV+MFC的雙目視覺測距與景深實現 之 問題探討

http://blog.csdn.net/chenyusiyuan/article/details/5072597

robot_vision

學習OpenCV快3個月了,主要是根據課題需要實現雙目視覺測距、景深重建和目標(障礙物)檢測。目前已經能實現攝像頭定標和校正、雙目匹配、獲取視差圖和環境景深圖像,但是在測距方面還沒有精確實現,主要是還沒徹底弄清楚攝像頭定標,有幾個問題希望能和大家探討下:

1、進行攝像頭定標時,棋盤方格的實際大小 square_size (默認為 1.0f )的設置對定標參數是否有影響? 
具體地,假如棋盤方格大小的 3 cm,那麼 square_size 就應該設置為 30.0f 吧? 
另外,定標所得的攝像頭內參數,即焦距和原點坐標,其數值單位都是一致的嗎? 
怎麼把焦距數值換算為實際的物理量? 

2、在使用 cvStereoCalibrate 進行雙攝像頭定標時,flags 的設置怎樣才是最優? 
我目前的設置是 CV_CALIB_FIX_ASPECT_RATIO + 
                      CV_CALIB_FIX_PRINCIPAL_POINT + 
                      CV_CALIB_SAME_FOCAL_LENGTH 
同樣地,怎麼把定標得到的兩個攝像頭之間的平移矩陣參數 Transaction_matrix 轉換為實際的物理量?其中的 Tx 值應該是兩個攝像頭成像原點之間的距離,根據公式 Z = f*Tx/(d-(Cxl-Cxr)) 來測算目標距離。 

3、關於 cvStereoRectify 函數 
在雙目校正(Stereo Rectification)上,我目前使用的是 BOUGUET 方法,即 cvStereoRectify 函數,因為要獲取景深圖像,所以 cvStereoRectify 函數要輸出一個變換矩陣 Q,並且最後的參數 flag 我設置為0,而不是 CV_CALIB_ZERO_DISPARITY。這樣設置應該沒問題吧?

Q_matrix

(1)校正後得到的變換矩陣Q,Q[0][3]、Q[1][3]存儲的是校正後左攝像頭的原點坐標(principal point)cx和cy,Q[2][3]是焦距,Learning OpenCV 書中說是「Here the parameters are from the left image」,但為什麼與 cvStereoCalibrate 得到的左攝像頭內參數據不同呢? 
(2)如上圖公式所示,按照 Learning OpenCV P435給出的 Q 矩陣,計算距離 Z 的公式是帶負號的,但這與 P436 給出的對應公式剛好是反號了的! 

4、關於雙目匹配求取視差圖 
OpenCV提供了兩個函數來進行雙目匹配、獲取視差:cvFindStereoCorrespondenceBM 和 cvFindStereoCorrespondenceGC。 
BM 的執行速度快,我用30幀/秒的速度讀入352*288的攝像頭畫面,用 BM 方法不會卡,算是實時了,但 BM 方法得到的視差不精確,所得的視差圖只是大致上與實物輪廓相似;而GC 方法則能得到非常好的視差圖,但是速度極慢,大概4、5秒才能處理完一幀畫面。 
我的 BMState 是這樣設置的:

      // 創建 CvStereoBMState 類的一個實例 BMState,進行雙目匹配
      BMState = cvCreateStereoBMState();
      assert(BMState != 0);
      BMState->preFilterSize=13;
      BMState->preFilterCap=13;
      BMState->SADWindowSize=13;
      BMState->minDisparity=-16;
      BMState->numberOfDisparities=64;
      BMState->textureThreshold=10;
      BMState->uniquenessRatio=15;

視差矩陣是 CV_16S 數據類型。目前的問題是,所得的視差數值范圍是從 -272 到 800 左右,不明白是怎麼算出來的。原理上,對於左視圖的一個特征點,應該是從右視圖對應的同一行像素點上,在設定的 numberOfDisparities 和 minDisparity 范圍內,尋找匹配的特征點、並求出視差值,這樣的話,視差數據的數值范圍應該是在[minDisparity, numberOfDisparities]內的(例如這裡應該是[-16, 64]范圍)。

下面是攝像頭定標所得的參數,有興趣的朋友麻煩幫忙看看、分析一下 O(∩_∩)O~

xml version="1.0"?>
<opencv_storage>
<num_frames>40num_frames>
<image_size>
  352 288image_size>
<lfCamMat_tM_1 type_id="opencv-matrix">
  <rows>3rows>
  <cols>3cols>
  <dt>ddt>
  <data>
    466.1152304250040900 0. 175.5000000000000000 0. 466.1152304250040900
    143.5000000000000000 0. 0. 1.data>lfCamMat_tM_1>
<riCamMat_tM_2 type_id="opencv-matrix">
  <rows>3rows>
  <cols>3cols>
  <dt>ddt>
  <data>
    466.1152304250040900 0. 175.5000000000000000 0. 466.1152304250040900
    143.5000000000000000 0. 0. 1.data>riCamMat_tM_2>
<lfDistCoef_tD_1 type_id="opencv-matrix">
  <rows>1rows>
  <cols>5cols>
  <dt>ddt>
  <data>
    -0.2573650855216149 -1.8434093222735448 -3.0112808382708931e-003
    -6.4644827216197836e-003 6.8034878625006252data>lfDistCoef_tD_1>
<riDistCoef_tD_2 type_id="opencv-matrix">
  <rows>1rows>
  <cols>5cols>
  <dt>ddt>
  <data>
    -0.2243951326136464 0.3568495067121301 0.0165299920785396
    -0.0150102576251246 -11.3185299056116850data>riDistCoef_tD_2>
<Rotation_matrix type_id="opencv-matrix">
  <rows>3rows>
  <cols>3cols>
  <dt>ddt>
  <data>
    0.9995520693887151 1.2173722340566046e-003 0.0299028190239849
    -9.9571078893194204e-004 0.9999719274362870 -7.4264998069014671e-003
    -0.0299110203898538 7.3933986907815975e-003 0.9995252215502303data>Rotation_matrix>
<Transaction_matrix type_id="opencv-matrix">
  <rows>3rows>
  <cols>1cols>
  <dt>ddt>
  <data>
    -62.4046095533341470 2.2541399055670328 4.0660224235033873data>Transaction_matrix>
<Foundation_matrix type_id="opencv-matrix">
  <rows>3rows>
  <cols>3cols>
  <dt>ddt>
  <data>
    -1.8956412948785254e-006 -1.2111883584794274e-004 0.0495469807761968
    6.5733933919231557e-005 1.3948680821461410e-005 0.8578014591819361
    -0.0396473926165904 -0.8508164298132787 1.data>Foundation_matrix>
<Rectif_LfCamMat type_id="opencv-matrix">
  <rows>3rows>
  <cols>4cols>
  <dt>ddt>
  <data>
    437.5624983240625700 0. 191.6575660705566400 0. 0.
    437.5624983240625700 145.4007148742675800 0. 0. 0. 1. 0.data>Calib_LfCamMat>
<Rectif_RiCamMat type_id="opencv-matrix">
  <rows>3rows>
  <cols>4cols>
  <dt>ddt>
  <data>
    437.5624983240625700 0. 205.8338241577148400
    -2.7329986601713106e+004 0. 437.5624983240625700
    145.4007148742675800 0. 0. 0. 1. 0.data>Calib_RiCamMat>
<Q_matrix type_id="opencv-matrix">
  <rows>4rows>
  <cols>4cols>
  <dt>ddt>
  <data>
    1. 0. 0. -191.6575660705566400 0. 1. 0. -145.4007148742675800 0. 0.
    0. 437.5624983240625700 0. 0. -0.0160103444140231 0.2269667744774826data>Q_matrix>
opencv_storage>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV C双目相机三维重建是基于OpenCV库的功能来实现的。双目相机指的是由两个摄像头组成的系统,通过同时拍摄两个视角的图像来获取深度信息,从而实现三维重建。 首先,需要利用OpenCV的摄像头功能获取左右摄像头的图像。可以使用cv::VideoCapture类来实现这个功能。通过该类的成员函数read()来获取实时的图像帧。 接下来,需要对这两个图像进行一系列的处理。首先,需要对图像进行校正,消除由于摄像头位置和参数不同产生的畸变。可以使用OpenCV的cv::undistort函数来实现图像的校正。 接着,需要将左右图像进行立体匹配,找到对应的像素点。OpenCV提供了一些立体匹配算法,如Semi-Global Block Matching(SGBM)、Graph Cuts等。需要根据实际情况选择合适的算法,并使用cv::StereoSGBM或cv::StereoGC函数进行立体匹配。 匹配完成后,还需要计算视差值(disparity),即左右图像对应像素的水平偏移量。视差值可以表示两个像素点之间的距离,可以根据标定参数和摄像头间距来计算三维空间的点坐标。 最后,可以使用OpenCV的cv::reprojectImageTo3D函数将视差图转换为三维点云。将视差值与相机内外参数结合,可以将像素坐标转换为三维坐标,从而实现三维重建。 需要注意的是,在进行双目相机三维重建时,需要进行相机标定和参数配置。相机标定可以使用OpenCV的cv::calibrateCamera函数来实现,该函数可以计算出相机的内外参数。参数配置包括设置立体匹配算法的参数、校正参数等。 总结来说,OpenCV C双目相机三维重建是通过获取双目图像、进行校正和立体匹配,最后根据标定参数计算出三维点云的过程。通过合理配置参数和选择合适的算法,可以实现精确的三维重建。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值