雙目相機標定在OpenCV中提供了示例程序,本來是非常簡單的事情,但是當標定自己的雙目相機的時候卻發現同樣的程序最后標出的結果卻很差勁,直接表現就是最后進行行對齊的時候獲得圖像根本不能看,所以從新梳理了雙目標定的過程,並給出了對雙目標定結果的應用,比如在ORB-SLAM中,雙目模式是需要進行雙目圖像矯正和對齊的,這時就可以使用OpenCV提供的函數接口完成這個過程,其過程如圖所示:
1.標定過程:
由於我的雙目圖像分辨率只有320*240,在進行角點檢測時,檢測的一點都不准,因此借鑒示例對圖像進行的放大(縮放同理)處理,得到640*480的圖像,然后再進行角點檢測,完成亞像素精確化之后再將特征點坐標反算回320*240,這個過程基本使得角點檢測的結果用肉眼看不出有誤差,主要程序過程:
//改變圖像尺寸;
cv::resize(imageL, sFrame0, cv::Size(640, 480)); cv::resize(imageR, sFrame1, cv::Size(640, 480));
//改變角點坐標值; if (scale) { for (size_t j = 0; j < tmpPointsL.size(); j++) { tmpPointsL[j].x = tmpPointsL[j].x / 2.; tmpPointsL[j].y = tmpPointsL[j].y / 2.; tmpPointsR[j].x = tmpPointsR[j].x / 2.; tmpPointsR[j].y = tmpPointsR[j].y / 2.; } }
效果圖:
第二個問題就是關於標定函數stereoCalibrate,在OpenCV2和OpenCV3中的參數定義的順序是不同的,OpenCV2:
double rms = cv::stereoCalibrate(objectPoints, imagePoints[0], imagePoints[1], cameraMatrix[0], distCoeffs[0], cameraMatrix[1], distCoeffs[1], imageSize, R, T, E, F, TermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 100, 1e-5), CV_CALIB_FIX_ASPECT_RATIO + CV_CALIB_ZERO_TANGENT_DIST + CV_CALIB_SAME_FOCAL_LENGTH + CV_CALIB_RATIONAL_MODEL + CV_CALIB_FIX_K3 + CV_CALIB_FIX_K4 + CV_CALIB_FIX_K5);
第三個問題就是標定結果,注意T矩陣中的第一個元素通常是兩個相機的基線距離,其他標定結果包括兩個相機的內參和畸變矩陣,以及相對的R,T和R1,P1等;另外就是極線的顯示,如下圖所示:
需要注意,兩幅圖像對應的點應該在同一條極線上,上圖中每條綠線應近似表示兩幅圖像上對應的點。
2.標定結果的使用:主要就是使雙目相機輸出的圖像獲得矯正和對齊
cv::Mat R1, R2, P1, P2, Q; cv::stereoRectify(K1, D1, K2, D2, cv::Size(320, 240), R, T, R1, R2, P1, P2, Q, CALIB_ZERO_DISPARITY, 0, cv::Size(320, 240)); Mat rmap[2][2]; initUndistortRectifyMap(K1, D1, R1, P1, cv::Size(320, 240), CV_16SC2, rmap[0][0], rmap[0][1]); initUndistortRectifyMap(K2, D2, R2, P2, cv::Size(320, 240), CV_16SC2, rmap[1][0], rmap[1][1]); //圖像顯示循環過程; remap(frame0, remapFrame0, rmap[0][0], rmap[0][1], CV_INTER_LINEAR); remap(frame1, remapFrame1, rmap[1][0], rmap[1][1], CV_INTER_LINEAR);
其中最重要的就是stereoRectify函數的使用,倒數第二個參數alpha的取值使得輸出的圖像不同,當alpha=0時,輸出經過剪裁之后的圖:
當alpha=1時,表示圖像不經任何剪裁,保持原始尺度:
當alpha=-1時,表示取默認值:
官方對於alpha參數的解釋為:
因此,在使用過程中應設alpha=0作為輸出,下面給出視頻輸出結果:
請注意,正確的雙目矯正結果不僅需要將圖像畸變進行矯正,還需要進行行對齊,如同上面的綠線所示,它們表示兩個相機已經達到了正視平行狀態,只有y上的差別。