全景图像拼接wave correct部分实现原理

最近在研究全景图像的拼接,阅读了OpenCV中图像拼接的部分代码,阅读到waveCorrect函数时看的一头雾水。函数的功能是传入每个相机的旋转矩阵,计算一个矫正的旋转矩阵,对旋转矩阵进行矫正,使得拼接后的图像近似为直线(矫正拼接后图像的波浪形式)。示例见lowe的论文中相关部分:


该部分在 Lowe[2] 的论文中叫做Automatic Panorama Straightening,在 Szeliski[3,4] 的综述文章中叫做Up vector selection,OpenCV的代码是对Lowe算法的实现。

straightening约束的OpenCV代码如下

void waveCorrect(std::vector &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 &rmats, WaveCorrectKind kind) 函数。

2. Automatic Panoramic Image Stitching using Invariant Features

3. 计算机视觉——算法与应用,第340页。

4. Image Alignment and Stitching,第50页。

你可能感兴趣的:(计算机视觉,数字图像处理,图像拼接)