7

OpenCV stereoRectifyUn calibrationd を使用して、画像のペアの視差マッピングを修正および構築しようとしましたが、あまり良い結果が得られません。私のコードは次のとおりです。

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 のキーポイント i であることを確認できます。

ndisp パラメータも試してみましたが、あまり役に立ちませんでした。

次の画像のペアで試しました:

左画像

右画像

次の修正されたペアを取得しました。

整流された左

修正された右

最後に、次の視差マップ

視差マップ

ご覧のとおり、これはかなり悪いです。また、次の stereoRectifyUncalibrated の例で同じ画像のペアを試しました: http://programmingexamples.net/wiki/OpenCV/WishList/StereoRectifyUn calibrationd と opencv チュートリアル コード サンプルの SBM_Sample.cpp を使用して視差マップを作成し、よく似た結果。

私はopencv 2.4を使用しています

前もって感謝します!

4

2 に答える 2

2

キャリブレーションの問題の可能性に加えて、ステレオ ブロック マッチングが機能するためのテクスチャが画像に明らかに欠けています。このアルゴリズムでは、平らな (テキシングされていない) パーツで多くのあいまいさと大きすぎる差異が見られます。

ただし、キーポイントはよく一致しているように見えるため、整流出力が奇妙に見えても、おそらく正しいことに注意してください。

サニティ チェックのために、 Middlebury ステレオ ページの標準画像に対してコードをテストできます。

于 2013-04-11T07:23:06.470 に答える
0

チェス盤を使用してステレオ キャリブレーションを行うか、チェス盤で複数の写真を撮りstereocalibrate.cpp、コンピューターで使用することをお勧めします。を使用しているためstereorectifyuncalibrated、アルゴリズムはカメラの固有パラメーターを知る必要はありませんが、エピポーラジオメトリに大きく依存していると言っています。したがって、カメラのレンズに大きな歪みがある場合は、基本行列を計算してこの関数を呼び出す前に、歪みを修正することをお勧めします。たとえば、 を使用して、ステレオ カメラの各ヘッドの歪み係数を個別に推定できますcalibrateCamera()。次に、 を使用して画像を修正するundistort()か、 でポイント座標のみを修正できますundistortPoints()

于 2013-01-20T20:24:30.503 に答える