2012-06-25 15 views
5

Ho cercato di rettificare e creare il mapping di disparità per una coppia di immagini utilizzando OpenCV stereoRectifyUncalibrated, ma non ottengo risultati molto buoni. Il mio codice è:Problemi con 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); 
} 

sequenza drawKeyPoint è il mio modo di controllare visivamente la consistenza dei punti che ho per entrambe le immagini. Disegnando ciascuno dei loro punti chiave in sequenza, posso essere sicuro che il punto chiave sull'immagine A è keypoint i sull'immagine B.

Ho anche provato a giocare con il parametro ndisp, ma non è stato di grande aiuto.

ho provato per la seguente coppia di immagini:

LeftImage

RightImage

ottenuto la seguente coppia rettificato:

RectifiedLeft

RectifiedRight

.515.053.691,36321 milioni

e, infine, la seguente mappa disparità

DisparityMap

Il che, come potete vedere, è piuttosto male. Ho anche provato la stessa coppia di immagini con il seguente esempio StereoRectifyUncalibrated: http://programmingexamples.net/wiki/OpenCV/WishList/StereoRectifyUncalibrated e SBM_Sample.cpp da esempi di codice tutorial opencv per costruire la mappa di disparità, e ottenuto un risultato molto simile.

Sto utilizzando OpenCV 2.4

Grazie in anticipo!

+0

Sto affrontando problemi molto simili. Hai trovato una soluzione? –

risposta

0

Vorrei suggerire di eseguire una calibrazione stereo utilizzando la scacchiera, o scattare più immagini con una scacchiera e utilizzare stereocalibrate.cpp sul computer. Dico questo perché stai usando stereorectifyuncalibrated, Mentre l'algoritmo non ha bisogno di conoscere i parametri intrinseci delle telecamere, dipende pesantemente dalla geometria epipolare. Pertanto, se gli obiettivi della fotocamera presentano una distorsione significativa, sarebbe meglio correggerla prima di calcolare la matrice fondamentale e chiamare questa funzione. Ad esempio, i coefficienti di distorsione possono essere stimati separatamente per ciascuna testa della telecamera stereo utilizzando calibrateCamera(). Quindi, le immagini possono essere corrette usando undistort(), o solo le coordinate punto possono essere corrette con undistortPoints().

2

Oltre ai possibili problemi di calibrazione, le immagini sono chiaramente prive di texture per il funzionamento del blocco stereo. Questo algoritmo vedrà molte ambiguità e disparità troppo grandi su parti piatte (non tetossurate).

Nota che i punti chiave sembrano corrispondere bene, quindi anche se l'output di rettifica sembra strano, probabilmente è corretto.

È possibile testare il codice contro le immagini standard dal Middlebury stereo page per i controlli di integrità.