2016-10-16 3 views
0

私はステレオカメラを初めて使っています(あるいはopencvの新機能かもしれません)。しかし、選択されたオブジェクトの距離を測定するためにステレオカメラが必要なFYPを行う必要があります。リアルタイムの視差マップが不正確です。

正確な視差マップを取得するための手順は何ですか?私が知る限り、内在的なパラメータを固有のものとするためにキャリブレーションを行い、それを歪ませないように調整し、次にそれを整理してからディスパリティマッピングを計算するだけです。

私は、内在値と外因性値を得るためにキャリブレーションを行っています。それから私はそれを修正しようとしたと私はこれを得るRMS value_and_reprojection_error_value.jpg。問題は、視差マッピングのためにどのような値が許容​​されるかです。

その後、ブロックマッチングを使用して視差マッピングを開始します。ここに私のコードがある `

int main(void) 
{ 

    VideoCapture camLeft(0); 
    VideoCapture camRight(2); 

    camLeft.set(CV_CAP_PROP_FRAME_WIDTH, 500); 
    camLeft.set(CV_CAP_PROP_FRAME_HEIGHT, 500); 
    camRight.set(CV_CAP_PROP_FRAME_WIDTH, 500); 
    camRight.set(CV_CAP_PROP_FRAME_HEIGHT, 500); 



    if (!camLeft.isOpened() || !camRight.isOpened()) { 
     cout << "Error: Stereo Cameras not found or there is some problem  connecting them. Please check your cameras.\n"; 
     exit(-1); 
    } 


//Read intrinsice parameters 
string intrinsic_filepath = "C:/Users/Jerry/Documents/Visual Studio 2015/Projects/OctStereoCalibration/OctStereoCalibration/intrinsics.yml"; 
FileStorage fs(intrinsic_filepath, FileStorage::READ); 
if (!fs.isOpened()) 
{ 
    printf("Failed to open intrinsics.yml"); 
    return -1; 
} 
Mat M1, D1, M2, D2; 
fs["M1"] >> M1; 
fs["D1"] >> D1; 
fs["M2"] >> M2; 
fs["D2"] >> D2; 

//Read Extrinsic Parameters 
string extrinsic_filepath = "C:/Users/Jerry/Documents/Visual Studio 2015/Projects/OctStereoCalibration/OctStereoCalibration/extrinsics.yml"; 
fs.open(extrinsic_filepath, FileStorage::READ); 
if (!fs.isOpened()) 
{ 
    printf("Failed to open extrinsics"); 
    return -1; 
} 

Mat R, T, R1, P1, R2, P2; 
fs["R"] >> R; 
fs["T"] >> T; 

Mat frame1, frame2, gray1, gray2, copyImageLeft, copyImageRight; 
int counter = 0; 

camLeft >> frame1; 
camRight >> frame2; 

Size img_size = frame1.size(); 
Rect roi1, roi2; 
Mat Q; 

stereoRectify(M1, D1, M2, D2, img_size, R, T, R1, R2, P1, P2, Q, CALIB_ZERO_DISPARITY, -1, img_size, &roi1, &roi2); 

Mat map11, map12, map21, map22; 
initUndistortRectifyMap(M1, D1, R1, P1, img_size, CV_16SC2, map11, map12); 
initUndistortRectifyMap(M2, D2, R2, P2, img_size, CV_16SC2, map21, map22); 



while (1) { 
    createTrackbars(); 
    on_trackbar(0, 0); 

    bm->setROI1(roi1); 
    bm->setROI2(roi2); 
    bm->setPreFilterCap(PreFilterCap); 
    bm->setPreFilterSize(PrefilterSize); 
    bm->setBlockSize(SADWindowSize); 
    bm->setMinDisparity(MinDisparity); //0 
    bm->setNumDisparities(numberOfDisparities); 
    bm->setTextureThreshold(TextureThreshold); 
    bm->setUniquenessRatio(UniquenessRatio); 
    bm->setSpeckleWindowSize(SpeckleWindowSize); 
    bm->setSpeckleRange(SpeckleRange); 
    bm->setDisp12MaxDiff(Disp12MaxDiff); //1 

    camLeft >> frame1; 
    camRight >> frame2; 
    if ((frame1.rows != frame2.rows) || (frame1.cols != frame2.cols)) { 
     cout << "Error: Images from both cameras are not of some size. Please check the size of each camera.\n"; 
     exit(-1); 
    } 
    //frame1.copyTo(copyImageLeft); 
    //frame2.copyTo(copyImageRight); 
    imshow("Cam1", frame1); 
    imshow("Cam2", frame2); 

    /************************* STEREO ***********************/ 

    cvtColor(frame1, gray1, CV_RGB2GRAY); 
    cvtColor(frame2, gray2, CV_RGB2GRAY); 

    int64 t = getTickCount(); 

    Mat img1r, img2r; 
    remap(gray1, img1r, map11, map12, INTER_LINEAR); 
    remap(gray2, img2r, map21, map22, INTER_LINEAR); 

    Mat disp, disp8; 
    Mat XYZ; 
    bm->compute(img1r, img2r, disp); 
    t = getTickCount() - t; 
    printf("Time elapsed: %fms\n", t * 1000/getTickFrequency()); 

    disp.convertTo(disp8, CV_8U, 255/(numberOfDisparities*16.)); 
    //normalize(disp, disp8, 0, 255, CV_MINMAX, CV_8U); 
    imshow("disparity", disp8); 

    //reprojectImageTo3D(disp8, XYZ, Q, false, CV_32F); 

    char keyBoardInput = (char)waitKey(50); 
    if (keyBoardInput == 'q' || keyBoardInput == 'Q') { 
     break; 
     return(0); 
    } 
} 

} `

マイBMのパラメータは次のとおりです。

int PreFilterCap = 31; int PrefilterSize = 21; int SADWindowSize = 33; int MinDisparity = 0; int numberOfDisparities = 48; int TextureThreshold = 29; int UniquenessRatio = 15; int SpeckleWindowSize = 32; int SpeckleRange = 32; int Disp12MaxDiff = 0; 私が取得視差マップは次のとおりです。 Disparity map

より良い品質を得るためにどのように視差マッピングの?おかげで

答えて

0

あなたは、パラメータウィンドウのサイズと視差の数を変更することができます。異なる深さの異なる値のセットが動作します。
2番目のオプションは、sbmの代わりにSGBMを使用することです。私が気づいている3番目の方法は、左と右のカメラの低解像度で視差を計算するためにガウスピラミッドを使用して、単純なロジックでそれらを融合することです。視差マップを低レベルで計算すると、ピラミッドレベルの穴が下に行くほど、最終的な視差マップをよりよく作成できるようになるという利点があります。

関連する問題