2012-06-25 38 views
5

我一直在尝试纠正和建立使用OpenCV stereoRectifyUncalibrated一对图像的差异映射,但我没有得到很好的结果。我的代码是:opencv stereoRectifyUncalibrated问题

template<class T> 
T convertNumber(string& number) 
{ 
    istringstream ss(number); 
    T t; 
    ss >> t; 
    return t; 
} 

void readPoints(vector<Point2f>& points, string filename) 
{ 
    fstream filest(filename.c_str(), ios::in); 
    string line; 

    assert(filest != NULL); 

    getline(filest, line); 
    do{ 
     int posEsp = line.find_first_of(' '); 
     string posX = line.substr(0, posEsp); 
     string posY = line.substr(posEsp+1, line.size() - posEsp); 

     float X = convertNumber<float>(posX); 
     float Y = convertNumber<float>(posY); 

     Point2f pnt = Point2f(X, Y); 
     points.push_back(pnt); 
     getline(filest, line); 
    }while(!filest.eof()); 

    filest.close(); 
} 

void drawKeypointSequence(Mat lFrame, Mat rFrame, vector<KeyPoint>& lKeyp, vector<KeyPoint>& rKeyp) 
{ 
    namedWindow("prevFrame", WINDOW_AUTOSIZE); 
    namedWindow("currFrame", WINDOW_AUTOSIZE); 
    moveWindow("prevFrame", 0, 300); 
    moveWindow("currFrame", 650, 300); 
    Mat rFrameAux; 
    rFrame.copyTo(rFrameAux); 
    Mat lFrameAux; 
    lFrame.copyTo(lFrameAux); 

    int size = rKeyp.size(); 
    for(int i=0; i<size; i++) 
    { 
     vector<KeyPoint> drawRightKeyp; 
     vector<KeyPoint> drawleftKeyp; 

     drawRightKeyp.push_back(rKeyp[i]); 
     drawleftKeyp.push_back(lKeyp[i]); 

     cout << rKeyp[i].pt << " <<<>>> " << lKeyp[i].pt << endl; 

     drawKeypoints(rFrameAux, drawRightKeyp, rFrameAux, Scalar::all(255), DrawMatchesFlags::DRAW_OVER_OUTIMG); 
     drawKeypoints(lFrameAux, drawleftKeyp, lFrameAux, Scalar::all(255), DrawMatchesFlags::DRAW_OVER_OUTIMG); 

     imshow("currFrame", rFrameAux); 
     imshow("prevFrame", lFrameAux); 
     waitKey(0); 
    } 
    imwrite("RightKeypFrame.jpg", rFrameAux); 
    imwrite("LeftKeypFrame.jpg", lFrameAux); 
} 
int main(int argc, char* argv[]) 
{ 
    StereoBM stereo(StereoBM::BASIC_PRESET, 16*5, 21); 
    double ndisp = 16*4; 
    assert(argc == 5); 
    string rightImgFilename(argv[1]);  // Right image (current frame) 
    string leftImgFilename(argv[2]);  // Left image (previous frame) 
    string rightPointsFilename(argv[3]); // Right image points file 
    string leftPointsFilename(argv[4]);  // Left image points file 

    Mat rightFrame = imread(rightImgFilename.c_str(), 0); 
    Mat leftFrame = imread(leftImgFilename.c_str(), 0); 

    vector<Point2f> rightPoints; 
    vector<Point2f> leftPoints; 

    vector<KeyPoint> rightKeyp; 
    vector<KeyPoint> leftKeyp; 

    readPoints(rightPoints, rightPointsFilename); 
    readPoints(leftPoints, leftPointsFilename); 
    assert(rightPoints.size() == leftPoints.size()); 

    KeyPoint::convert(rightPoints, rightKeyp); 
    KeyPoint::convert(leftPoints, leftKeyp); 

    // Desenha os keypoints sequencialmente, de forma a testar a consistência do matching 
    drawKeypointSequence(leftFrame, rightFrame, leftKeyp, rightKeyp); 

    Mat fundMatrix = findFundamentalMat(leftPoints, rightPoints, CV_FM_8POINT); 
    Mat homRight; 
    Mat homLeft; 
    Mat disp16 = Mat(rightFrame.rows, leftFrame.cols, CV_16S); 
    Mat disp8 = Mat(rightFrame.rows, leftFrame.cols, CV_8UC1); 
    stereoRectifyUncalibrated(leftPoints, rightPoints, fundMatrix, rightFrame.size(), homLeft, homRight); 

    warpPerspective(rightFrame, rightFrame, homRight, rightFrame.size()); 
    warpPerspective(leftFrame, leftFrame, homLeft, leftFrame.size()); 


    namedWindow("currFrame", WINDOW_AUTOSIZE); 
    namedWindow("prevFrame", WINDOW_AUTOSIZE); 
    moveWindow("currFrame", 650, 300); 
    moveWindow("prevFrame", 0, 300); 
    imshow("currFrame", rightFrame); 
    imshow("prevFrame", leftFrame); 

    imwrite("RectfRight.jpg", rightFrame); 
    imwrite("RectfLeft.jpg", leftFrame); 

    waitKey(0); 

    stereo(rightFrame, leftFrame, disp16, CV_16S); 

    disp16.convertTo(disp8, CV_8UC1, 255/ndisp); 
    FileStorage file("disp_map.xml", FileStorage::WRITE); 
    file << "disparity" << disp8; 
    file.release(); 
    imshow("disparity", disp8); 
    imwrite("disparity.jpg", disp8); 
    moveWindow("disparity", 0, 0); 

    waitKey(0); 
} 

drawKeyPoint序列是我可视化检查两个图像所具有的点的一致性的方式。通过依次绘制每个关键点,我可以确定,关于图像A的关键点i是关于图像B的关键点。

我也试着玩过ndisp参数,但没有多大帮助。

我尝试了以下对图像:

LeftImage

RightImage

得到以下纠正对:

RectifiedLeft

RectifiedRight

最后,下面视差图

DisparityMap

哪像你所看到的,是相当糟糕。我还尝试了以下stereoRectifyUncalibrated示例的同一对图像:http://programmingexamples.net/wiki/OpenCV/WishList/StereoRectifyUncalibrated和来自opencv教程代码示例的SBM_Sample.cpp构建视差图,并得到了非常相似的结果。

我使用的是opencv 2.4

在此先感谢!

+0

我面临着非常类似的问题。你找到解决方案吗? –

回答

0

我会建议使用棋盘进行立体校准,或者用棋盘拍摄多张照片,并在您的计算机上使用stereocalibrate.cpp。我在说,因为您使用的是stereorectifyuncalibrated,虽然算法不需要知道相机的内部参数,但它很大程度上取决于极线几何。因此,如果相机镜头有明显的失真,最好在计算基本矩阵并调用此函数之前对其进行纠正。例如,可以通过使用calibrateCamera()分别为立体相机的每个头部估计失真系数。然后,可以使用undistort()来校正图像,或者只需使用undistortPoints()就可以校正点坐标。

2

除了可能存在的校准问题,您的图像显然缺乏一些用于立体块匹配工作的纹理。 该算法会在扁平(非tetxured)部件上看到许多歧义和太大的差异。

但是请注意,关键点似乎匹配得很好,所以即使整流输出看起来很奇怪,它也许是正确的。

您可以根据Middlebury stereo page的标准图像测试您的代码以进行完整性检查。