雙目匹配過程記錄

此文章參考如下博客:
http://blog.csdn.net/wangchao7281/article/details/52506691
感謝子非魚大大提供的寶貴的理論知識和代碼。

雙目匹配的過程無非是包括雙目相機的標定、矯正以及最后得出視差圖這么幾個步驟。具體的理論知識可以參考上文的博客地址中的講述或者自行搜索。

1. 雙目相機的標定

雙目相機的標定我使用的是Matlab的APP,Matlab自帶Stereo Camera Calibration工具,位置如下截圖

Matlab工具箱截圖

點擊下拉按鈕,在圖像處理和計算機視覺中找到Stereo Camera Calibration模塊并打開它,點擊Add images按鈕,分別把左右相機拍攝的圖片傳入Matlab中,其中的Size of checkerboard square的大小是標定板的方格的長度,單位是mm。

標定截圖

之后Matlab就會自動識別角點,點擊上方菜單欄的Calibrate就會自動計算相關的參數(shù),點擊Export Camera Parameters之后就會把相關的參數(shù)Matlab的工作區(qū),在這里就可以查看相關的參數(shù)了。

參數(shù)截圖(1)

紅色方框圈起來的是左右相機的各種參數(shù),點進去之后可以看到相機的內參數(shù)以及畸變參數(shù)等等,紅色箭頭指向的是旋轉矩陣,藍色箭頭指向的是平移矩陣。
至此標定部分全部完成,具體的參數(shù)可以直接在Matlab的工作區(qū)中查看即可。

2. 雙目相機的矯正

在步驟1中,我們通過標定得到了相機的各種參數(shù),現(xiàn)在把它傳入OpenCV。代碼如下

Mat cameraMatrixL = (Mat_<double>(3, 3) << 1.289608025726931e+03, 0, 6.437248258682027e+02,
    0, 1.290358173802592e+03, 5.321046969048958e+02,
    0, 0, 1);
Mat distCoeffL = (Mat_<double>(5, 1) << -0.447270756264546, 0.248847254828889, 0, 0, 0.00000);

Mat cameraMatrixR = (Mat_<double>(3, 3) << 1.289350232644886e+03, 0, 6.443163387389753e+02,
    0, 1.289962540201652e+03, 5.284409180695891e+02,
    0, 0, 1);
Mat distCoeffR = (Mat_<double>(5, 1) << -0.444499341518694, 0.234760627512454, 0, 0, 0.00000);

Mat T = (Mat_<double>(3, 1) << -2.383757790772444e+02, 2.938085768248284, -1.249386542211461);//T平移向量
                                                            
Mat R = (Mat_<double>(3, 3) << 0.999188845533377, 0.013112400390036, -0.038075135163100,
    -0.012563847364096, 0.999814319377252, 0.014610835281208,
    0.038259648470532, -0.014120613450352, 0.999168057723373);//R 旋轉矩陣

這樣,左右兩個相機的內參數(shù)以及畸變參數(shù)已經(jīng)傳入到OpenCV,下面就可以進行矯正了。

//校正
    stereoRectify(cameraMatrixL, distCoeffL, cameraMatrixR, distCoeffR, imageSize, R, T, Rl, Rr, Pl, Pr, Q, CALIB_ZERO_DISPARITY,
        0, imageSize, &validROIL, &validROIR);
    initUndistortRectifyMap(cameraMatrixL, distCoeffL, Rl, Pr, imageSize, CV_32FC1, mapLx, mapLy);
    initUndistortRectifyMap(cameraMatrixR, distCoeffR, Rr, Pr, imageSize, CV_32FC1, mapRx, mapRy);
        
//讀取需要矯正的圖片,矯正的圖片只能是灰色圖
    rgbImageL = imread("left24.png", CV_LOAD_IMAGE_COLOR);
    cvtColor(rgbImageL, grayImageL, CV_BGR2GRAY);
    rgbImageR = imread("right24.png", CV_LOAD_IMAGE_COLOR);
    cvtColor(rgbImageR, grayImageR, CV_BGR2GRAY);

    namedWindow("ImageL Before Rectify", 0);
    namedWindow("ImageR Before Rectify", 0);
    imshow("ImageL Before Rectify", grayImageL);
    imshow("ImageR Before Rectify", grayImageR);
//矯正
    remap(grayImageL, rectifyImageL, mapLx, mapLy, INTER_LINEAR);
    remap(grayImageR, rectifyImageR, mapRx, mapRy, INTER_LINEAR);

    Mat rgbRectifyImageL, rgbRectifyImageR;
    cvtColor(rectifyImageL, rgbRectifyImageL, CV_GRAY2BGR);  //偽彩色圖
    cvtColor(rectifyImageR, rgbRectifyImageR, CV_GRAY2BGR);

    namedWindow("ImageL After Rectify", 0);
    namedWindow("ImageR After Rectify", 0);
    imshow("ImageL After Rectify", rgbRectifyImageL);
    imshow("ImageR After Rectify", rgbRectifyImageR);

3. 雙目的匹配

經(jīng)過步驟1和步驟2之后,雙目匹配的實驗也已經(jīng)完成了大部分的工作,最后一步的匹配則就簡單得多了,可以選擇適合自己的匹配算法來完成立體匹配的結果,這里我選用的是OpenCV自帶的SGBM算法。

int blockSize = 0, uniquenessRatio = 0, numDisparities = 0;
Ptr<StereoSGBM> sgbm = StereoSGBM::create(0, 16, 3);
void stereo_match(int, void*)
{
        int SADWindowSize = 5;
        sgbm->setPreFilterCap(63);
        int sgbmWinSize = SADWindowSize > 0 ? SADWindowSize : 3;
        sgbm->setBlockSize(sgbmWinSize);
    
        int cn = rgbImageL.channels();
        
        sgbm->setP1(8 * cn*sgbmWinSize*sgbmWinSize);
        sgbm->setP2(32 * cn*sgbmWinSize*sgbmWinSize);
        sgbm->setMinDisparity(0);
    
    
        numberOfDisparities = numberOfDisparities > 0 ? numberOfDisparities : ((imageSize.width / 8) + 15) & -16;
    
        sgbm->setNumDisparities(numberOfDisparities);
        sgbm->setUniquenessRatio(10);
        sgbm->setSpeckleWindowSize(100);
        sgbm->setSpeckleRange(32);
        sgbm->setDisp12MaxDiff(1);
        sgbm->setMode(StereoSGBM::MODE_SGBM_3WAY);
        Mat disp, disp8;
        sgbm->compute(rectifyImageL, rectifyImageR, disp);
        disp.convertTo(disp8, CV_8U, 255 / (numberOfDisparities *16.));
        imwrite("disp.png", disp8);
        imshow("disp8", disp8);
}

匹配的算法有很多種,OpenCV自帶的有BM,SGBM,GC,HH等等。

4. 結束語

對于雙目匹配的相關的東西,我也是剛剛接觸不到半個月,深感這個東西網(wǎng)上的資料很繁雜,且大多數(shù)資料不給出具體的步驟,理論的東西過多,亦或是版本過于陳舊。本篇文章如有問題,可以留言或者私信我,我很樂意探討相關的問題。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容