C++ 如何使用openCV';是球形的吗?
我有一个等矩形缝合的全景图像,我想用球形投影显示。我以前使用openCV的C++ 如何使用openCV';是球形的吗?,c++,opencv,image-processing,computer-vision,360-degrees,C++,Opencv,Image Processing,Computer Vision,360 Degrees,我有一个等矩形缝合的全景图像,我想用球形投影显示。我以前使用openCV的imshow按原样显示图像(使用等矩形投影),但是图像的顶部和底部都发生了扭曲(与任何等矩形投影一样),我希望消除这种扭曲 我在openCV中找到了可以帮助我做到这一点的方法。但是我在理解如何使用warp时遇到了一些问题 目前,我的代码中进行扭曲的部分如下所示: Mat panorama; Mat K = Mat::zeros(3, 3, CV_32F); Mat R = Mat::eye(3, 3
imshow
按原样显示图像(使用等矩形投影),但是图像的顶部和底部都发生了扭曲(与任何等矩形投影一样),我希望消除这种扭曲
我在openCV中找到了可以帮助我做到这一点的方法。但是我在理解如何使用warp
时遇到了一些问题
目前,我的代码中进行扭曲的部分如下所示:
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
),但我不确定扭曲器是否需要这些相同的参数。我只想用一个球面投影来查看我的源图像,这样,由等矩形投影引起的失真就不再存在了。我希望输出的图像与Google street view的外观相似。我坚持同样的问题,但经过一些实验后,问题解决了。Intrinsics矩阵如下所示:
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;
}
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
使用名称空间cv;
//计算给定欧拉角的旋转矩阵。
Mat-eulerAnglesToRotationMatrix(向量3F和θ)
{
//计算绕x轴的旋转
Mat R_x=(Mat_(3,3)图像对我来说是一个蓝色矩形。@Yakk如果你说的是全景
图像,是的,这就是我当前输出的样子。