Как использовать OpenCV SphericalWarper?

У меня есть ровное сшитое панорамное изображение, которое я хочу отобразить со сферической проекцией. Ранее я отображал изображение как есть (с равносторонней проекцией), используя openCV imshow, но верхняя и нижняя части изображения искажены (как и при любой равноугольной проекции), и я хочу избавиться от этого искажения.

я нашел SphericalWarper в openCV это может помочь мне сделать это. Но у меня есть некоторые проблемы с пониманием, как именно использовать warp,

На данный момент раздел кода my, который выполняет деформацию, выглядит следующим образом:

    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выглядит как изображение с датчика изображения без линз:

введите описание изображения здесь

Я думаю, это имеет смысл, потому что в настоящее время встроенная матрица моей камеры представляет собой матрицу 3х3 всех нулей. Так что мой вопрос является: Что должна содержать внутренняя матрица камеры? У меня есть внутренние параметры камеры для камер, которые снимали изображения, сшитые для получения моего исходного прямоугольного изображения (imgBgr), но я не уверен, что warper нужны эти же параметры. Я просто хочу просмотреть мое исходное изображение в виде сферической проекции, чтобы больше не возникало искажение, вызванное равноугольной проекцией. Я хочу, чтобы выходное изображение было похоже на то, как выглядит Google Street View.

2

Решение

Я придерживаюсь той же проблемы, но после некоторых экспериментов выбрался из ямы. Внутренняя матрица выглядит так:

fx,  0, cx,
0, fy, cy,
0,  0,  1

где f (x, y) — масштабный коэффициент, c (x, y) — смещение центра. Вы можете играть со всеми параметрами в коде:

#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;
}
0

Другие решения

Других решений пока нет …