全景圖像拼接wave correct部分實現原理

最近在研究全景圖像的拼接,閱讀了OpenCV中圖像拼接的部分代碼,閱讀到waveCorrect函數時看的一頭霧水。函數的功能是傳入每個相機的旋轉矩陣,計算一個矯正的旋轉矩陣,對旋轉矩陣進行矯正,使得拼接後的圖像近似爲直線(矯正拼接後圖像的波浪形式)。示例見lowe的論文中相關部分:


該部分在 Lowe[2] 的論文中叫做Automatic Panorama Straightening,在 Szeliski[3,4] 的綜述文章中叫做Up vector selection,OpenCV的代碼是對Lowe算法的實現。

straightening約束的OpenCV代碼如下

void waveCorrect(std::vector<Mat> &rmats, WaveCorrectKind kind)
{
    LOGLN("Wave correcting...");
#if ENABLE_LOG
    int64 t = getTickCount();
#endif

    Mat moment = Mat::zeros(3, 3, CV_32F);
    for (size_t i = 0; i < rmats.size(); ++i)
    {
        Mat col = rmats[i].col(0);
        moment += col * col.t();
    }
    Mat eigen_vals, eigen_vecs;
    eigen(moment, eigen_vals, eigen_vecs);

    Mat rg1;
    if (kind == WAVE_CORRECT_HORIZ)
        rg1 = eigen_vecs.row(2).t();
    else if (kind == WAVE_CORRECT_VERT)
        rg1 = eigen_vecs.row(0).t();
    else
        CV_Error(CV_StsBadArg, "unsupported kind of wave correction");

    Mat img_k = Mat::zeros(3, 1, CV_32F);
    for (size_t i = 0; i < rmats.size(); ++i)
        img_k += rmats[i].col(2);
    Mat rg0 = rg1.cross(img_k);
    rg0 /= norm(rg0);

    Mat rg2 = rg0.cross(rg1);

    double conf = 0;
    if (kind == WAVE_CORRECT_HORIZ)
    {
        for (size_t i = 0; i < rmats.size(); ++i)
            conf += rg0.dot(rmats[i].col(0));
        if (conf < 0)
        {
            rg0 *= -1;
            rg1 *= -1;
        }
    }
    else if (kind == WAVE_CORRECT_VERT)
    {
        for (size_t i = 0; i < rmats.size(); ++i)
            conf -= rg1.dot(rmats[i].col(0));
        if (conf < 0)
        {
            rg0 *= -1;
            rg1 *= -1;
        }
    }

    Mat R = Mat::zeros(3, 3, CV_32F);
    Mat tmp = R.row(0);
    Mat(rg0.t()).copyTo(tmp);
    tmp = R.row(1);
    Mat(rg1.t()).copyTo(tmp);
    tmp = R.row(2);
    Mat(rg2.t()).copyTo(tmp);

    for (size_t i = 0; i < rmats.size(); ++i)
        rmats[i] = R * rmats[i];

    LOGLN("Wave correcting, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");
}


主要使用兩個約束條件來計算全局旋轉矩陣:

1. 相機座標系的X軸與世界座標系中的Z軸垂直。

2. 相機的旋轉矩陣的Z軸方向的平均值與世界座標系的Z軸相接近。


參考:

1. OpenCV代碼 motion_estimators.cpp 的 void waveCorrect(std::vector<Mat> &rmats, WaveCorrectKind kind) 函數。

2. Automatic Panoramic Image Stitching using Invariant Features

3. 計算機視覺——算法與應用,第340頁。

4. Image Alignment and Stitching,第50頁。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章