Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 使用滚转俯仰偏航角变换图像(图像校正)_Matlab_Opencv_Image Processing_Image Rotation_Euler Angles - Fatal编程技术网

Matlab 使用滚转俯仰偏航角变换图像(图像校正)

Matlab 使用滚转俯仰偏航角变换图像(图像校正),matlab,opencv,image-processing,image-rotation,euler-angles,Matlab,Opencv,Image Processing,Image Rotation,Euler Angles,我正在开发一个应用程序,需要对从移动相机平台拍摄的图像进行校正。平台测量横摇、俯仰和偏航角,我想让它看起来像是从正上方拍摄的图像,通过对这些信息的某种转换 换句话说,我想要一个完美的正方形平躺在地上,从远处用相机定向拍摄,然后进行变换,这样这个正方形就可以完全对称了 我一直试图通过OpenCV(C++)和Matlab来实现这一点,但我似乎缺少一些基本的方法 在Matlab中,我尝试了以下方法: %% Transform perspective img = imread('my_favourite

我正在开发一个应用程序,需要对从移动相机平台拍摄的图像进行校正。平台测量横摇、俯仰和偏航角,我想让它看起来像是从正上方拍摄的图像,通过对这些信息的某种转换

换句话说,我想要一个完美的正方形平躺在地上,从远处用相机定向拍摄,然后进行变换,这样这个正方形就可以完全对称了

我一直试图通过OpenCV(C++)和Matlab来实现这一点,但我似乎缺少一些基本的方法

在Matlab中,我尝试了以下方法:

%% Transform perspective
img = imread('my_favourite_image.jpg');
R = R_z(yaw_angle)*R_y(pitch_angle)*R_x(roll_angle);
tform = projective2d(R);   
outputImage = imwarp(img,tform);
figure(1), imshow(outputImage);
其中R_z/y/x是标准旋转矩阵(用度实现)

对于某些偏航旋转,这一切都很好:

R = R_z(10)*R_y(0)*R_x(0);
结果如下:

如果我尝试围绕X轴或Y轴旋转相同数量的图像,我会得到如下结果:

R = R_z(10)*R_y(0)*R_x(10);

然而,如果我旋转10度,除以一些大的数字,它开始看起来不错。但同样,这是一个没有任何研究价值的结果:

R = R_z(10)*R_y(0)*R_x(10/1000);

有人能帮我理解为什么绕X轴或Y轴旋转会导致变换失控吗?有没有办法解决这个问题而不用除以一些随机数和其他魔术?这是不是可以用某种欧拉参数来解决?任何帮助都将不胜感激

更新:完整设置和测量

为完整起见,添加了完整的测试代码和初始图像,以及平台角度:

代码:

初始图像:

车身坐标系中的摄像头平台测量值:

Roll:     -10
Pitch:    -30
Yaw:      166 (angular deviation from north)
据我所知,偏航角与变换没有直接关系。然而,我可能错了

其他信息:


我想指定使用设置的环境不包含可以可靠用作参考的线条(海洋照片)(地平线通常不在图片中)。此外,初始图像中的正方形仅用于衡量变换是否正确,在真实场景中不会出现。我认为可以通过以下方式导出变换:

1) 让您有四个3d点A(-1,-1,0)、B(1,-1,0)、C(1,1,0)和D(-1,1,0)。可以取任意4个非共线点。它们与图像无关

2) 您有变换矩阵,因此可以通过将点坐标乘以变换矩阵来设置相机。您将获得相对于摄影机位置/方向的3d坐标

3) 您需要获得点到屏幕平面的投影。最简单的方法是使用ortographic投影(只需忽略深度坐标)。在这个阶段中,您将得到变换点的二维投影

4) 一旦有了两组二维点坐标(步骤1中的一组没有三维坐标,步骤3中的一组),就可以用标准方式计算单应矩阵


5) 对图像应用反同调变换

所以,这就是我最后要做的:我想除非你真的在处理3D图像,否则校正照片的透视图是一个2D操作。考虑到这一点,我将变换矩阵的z轴值替换为0和1,并对图像应用二维仿射变换

以以下方式旋转初始图像(见初始post),测量的横摇=-10,俯仰=-30:

R_rotation = R_y(-60)*R_x(10); 
R_2d       = [   R_rot(1,1)  R_rot(1,2) 0; 
                 R_rot(2,1)  R_rot(2,2) 0;
                 0           0          1    ] 
这意味着将摄影机平台旋转到虚拟摄影机方向,其中摄影机放置在场景上方,指向正下方。注意上面矩阵中用于横摇和俯仰的值

此外,如果旋转图像以便与平台标题对齐,则可能会添加围绕z轴的旋转,从而给出:

R_rotation = R_y(-60)*R_x(10)*R_z(some_heading); 
R_2d       = [   R_rot(1,1)  R_rot(1,2) 0; 
                 R_rot(2,1)  R_rot(2,2) 0;
                 0           0          1    ] 
请注意,这不会更改实际图像-它只会旋转图像

因此,围绕Y轴和X轴旋转的初始图像如下所示:

如上所示,执行此转换的完整代码是:

% Load image
img = imread('initial_image.jpg'); 

% Full rotation matrix. Z-axis included, but not used.
R_rot = R_y(-60)*R_x(10)*R_z(0); 

% Strip the values related to the Z-axis from R_rot
R_2d  = [   R_rot(1,1)  R_rot(1,2) 0; 
            R_rot(2,1)  R_rot(2,2) 0;
            0           0          1    ]; 

% Generate transformation matrix, and warp (matlab syntax)
tform = affine2d(R_2d);
outputImage = imwarp(img,tform);

% Display image
figure(1), imshow(outputImage);



%*** Rotation Matrix Functions ***%

%% Matrix for Yaw-rotation about the Z-axis
function [R] = R_z(psi)
    R = [cosd(psi) -sind(psi) 0;
         sind(psi)  cosd(psi) 0;
         0          0         1];
end

%% Matrix for Pitch-rotation about the Y-axis
function [R] = R_y(theta)
    R = [cosd(theta)    0   sind(theta);
         0              1   0          ;
         -sind(theta)   0   cosd(theta)     ];
end

%% Matrix for Roll-rotation about the X-axis
function [R] = R_x(phi)
    R = [1  0           0;
         0  cosd(phi)   -sind(phi);
         0  sind(phi)   cosd(phi)];
end

谢谢你的支持,我希望这对别人有帮助

您需要估计单应性。有关现成的Matlab解决方案,请参见函数
vgg_H_from_x_lin.m
from


对于这一理论,请深入阅读计算机视觉教科书,例如在

的第3章或第3章中免费提供的教科书。也许我的答案不正确,因为我对摄像机参数的理解有误,但我想知道偏航/俯仰/滚动是否与对象的位置有关。我使用了的公式,我的代码如下(旋转函数
R_x
R_y
,和
R_z
是从你的公式复制的,我没有粘贴在这里)

结果是:

这表明你仍然需要一些旋转操作才能在脑海中找到“正确”的对齐方式(但可能不需要在相机的脑海中找到正确的位置)。 所以我改变
R_rot=inv(R_rot)
R_rot=inv(R_rot)*R_x(-5)*R_y(25)*R_z(180),现在它给了我:

看起来更像你想要的。
谢谢。

您能上传原始图像和旋转矩阵实现吗?嗨,Scap3y!我在上面的帖子中为这个问题添加了完整的信息和代码。好吧,我想你错过了一个关键的步骤:找到与图像中线条的水平投影相关的单应性。请参阅以了解如何使其工作。一旦你计算了单应性,你就可以用它来代替你的
R
矩阵,这应该可以做到。谢谢你的建议。我将要分析的图像中没有任何线条(实际上)。然而,我认为我可以直接从R中创建这些校正向量
% Load image
img = imread('initial_image.jpg'); 

% Full rotation matrix. Z-axis included, but not used.
R_rot = R_y(-60)*R_x(10)*R_z(0); 

% Strip the values related to the Z-axis from R_rot
R_2d  = [   R_rot(1,1)  R_rot(1,2) 0; 
            R_rot(2,1)  R_rot(2,2) 0;
            0           0          1    ]; 

% Generate transformation matrix, and warp (matlab syntax)
tform = affine2d(R_2d);
outputImage = imwarp(img,tform);

% Display image
figure(1), imshow(outputImage);



%*** Rotation Matrix Functions ***%

%% Matrix for Yaw-rotation about the Z-axis
function [R] = R_z(psi)
    R = [cosd(psi) -sind(psi) 0;
         sind(psi)  cosd(psi) 0;
         0          0         1];
end

%% Matrix for Pitch-rotation about the Y-axis
function [R] = R_y(theta)
    R = [cosd(theta)    0   sind(theta);
         0              1   0          ;
         -sind(theta)   0   cosd(theta)     ];
end

%% Matrix for Roll-rotation about the X-axis
function [R] = R_x(phi)
    R = [1  0           0;
         0  cosd(phi)   -sind(phi);
         0  sind(phi)   cosd(phi)];
end
close all
file='http://i.stack.imgur.com/m5e01.jpg'; % original image
I=imread(file);

R_rot = R_x(-10)*R_y(-30)*R_z(166);
R_rot = inv(R_rot);

R_2d  = [   R_rot(1,1)  R_rot(1,2) 0; 
            R_rot(2,1)  R_rot(2,2) 0;
            0           0          1    ]; 


T = maketform('affine',R_2d);

transformedI = imtransform(I,T);
        figure, imshow(I), figure, imshow(transformedI)