首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用openCV的SphericalWarper?

如何使用openCV的SphericalWarper?
EN

Stack Overflow用户
提问于 2017-08-18 16:30:58
回答 1查看 3.7K关注 0票数 3

我有一个等长线拼接全景图像,我想用球面投影显示。我以前用openCV的imshow显示图像为-is(用等矩形投影),但是图像的顶部和底部都是扭曲的(就像任何等矩形投影一样),我想要消除这种失真。

我在openCV中找到了可以帮助我做到这一点的openCV。但是,我在正确理解如何使用warp时遇到了一些问题。

现在,我的代码中进行扭曲的部分如下所示:

代码语言:javascript
复制
    Mat panorama;
    Mat K = Mat::zeros(3, 3, CV_32F);
    Mat R = Mat::eye(3, 3, CV_32F);
    detail::SphericalWarper warper = detail::SphericalWarper(1.0f);
    warper.warp(imgBgr, K, R, INTER_LINEAR, BORDER_DEFAULT,panorama);

    imshow("Display frame", panorama);
    waitKey(0);

我的源图像,imgBgr看起来像这样(不完全是我的,只是一个例子):

目前,我得到的输出图像panorama看起来就像图像传感器中没有任何镜头的图像:

我想这是有意义的,因为目前我的相机内禀矩阵是所有零的3x3矩阵。因此,我的问题是:相机的内在矩阵应该包含什么?我有相机的内在参数,为相机拍摄的图像是缝制的,以产生我的源等矩形图像(imgBgr),但我不确定warper是否需要这些相同的参数。我只想用球面投影来查看我的源图像,这样由等长线投影引起的失真就不再存在了。我希望输出图像类似于谷歌的街景。

EN

回答 1

Stack Overflow用户

发布于 2018-05-07 13:16:33

我坚持同样的问题,但经过一些实验后,从洞里出来。本质矩阵看起来如下:

代码语言:javascript
复制
fx,  0, cx,
 0, fy, cy,
 0,  0,  1

其中f(x,y)是标度因子,c(x,y)是中心偏移量。您可以使用代码中的所有参数:

代码语言:javascript
复制
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/stitching/warpers.hpp>

using namespace std;
using namespace cv;

// Calculates rotation matrix given euler angles.
Mat eulerAnglesToRotationMatrix(Vec3f &theta)
{
    // Calculate rotation about x axis
    Mat R_x = (Mat_<float>(3,3) <<
               1,       0,              0,
               0,       cosf(theta[0]),   -sinf(theta[0]),
               0,       sinf(theta[0]),   cosf(theta[0])
               );

    // Calculate rotation about y axis
    Mat R_y = (Mat_<float>(3,3) <<
               cosf(theta[1]),    0,      sinf(theta[1]),
               0,               1,      0,
               -sinf(theta[1]),   0,      cosf(theta[1])
               );

    // Calculate rotation about z axis
    Mat R_z = (Mat_<float>(3,3) <<
               cosf(theta[2]),    -sinf(theta[2]),      0,
               sinf(theta[2]),    cosf(theta[2]),       0,
               0,               0,                  1);


    // Combined rotation matrix
    Mat R = R_z * R_y * R_x;

    return R;

}

int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";

    Mat origImg = imread("..path to file..");
    imshow("src", origImg);

    float scale = 100.0;
    float fx = 100, fy = 100, cx = 500, cy = 300;
    Vec3f rot = {};

    while (true) {
        cout << "•" << endl;
        cout << "Fx: " << fx << "; Fy: " << fy << endl;
        cout << "Cx: " << fx << "; Cy: " << fy << endl;
        cout << "Scale: " << scale << endl;
        cout << "Ang: " << rot << endl;

        detail::SphericalWarper wrap(scale);
        Mat K = (Mat_<float>(3,3) <<
                 fx, 0, cx,
                 0, fy, cy,
                 0, 0, 1);
        Mat R = eulerAnglesToRotationMatrix(rot);

        Mat dst;
        wrap.warp(origImg, K, R, INTER_LINEAR, BORDER_CONSTANT, dst);
        imshow("dst", dst);
        cout << dst.size() << endl;
        char c = waitKey();

        if (c == 'q') break;
        else if (c == 'a') fx += 10;
        else if (c == 'z') fx -= 10;
        else if (c == 's') fy += 10;
        else if (c == 'x') fy -= 10;
        else if (c == 'd') scale += 10;
        else if (c == 'c') scale -= 10;

        else if (c == 'f') rot[0] += 0.1;
        else if (c == 'v') rot[0] -= 0.1;
        else if (c == 'g') rot[1] += 0.1;
        else if (c == 'b') rot[1] -= 0.1;
        else if (c == 'h') rot[2] += 0.1;
        else if (c == 'n') rot[2] -= 0.1;
    }

    return 0;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45761194

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档