简体   繁体   English

python中的3D图像旋转

[英]3D image rotation in python

I have the following image I1. 我有以下图像I1。 I did not capture it. 我没有抓住它。 I downloaded it from Google 我是从Google下载的

在此处输入图片说明

I apply a known homography h to I1 to obtain the following image I2. 我将已知的单应性h应用于I1,以获得以下图像I2。

在此处输入图片说明

I want to assume that a camera has taken this above shot of I2. 我想假设照相机已经拍摄了以上I2的照片。 I have found the camera matrix of this "camera". 我已经找到了这个“相机”的相机矩阵。 Let this camera matrix be k . 令此相机矩阵为k Now, I want to rotate this image I2 about the camera axis. 现在,我想围绕相机轴旋转此图像I2。 According to the explanation in the accepted answer in this question , I need to set the rotation matrix R and then perform k*R*inv(k)*h on image I1 to get the required rotated image I3. 根据该问题接受答案的解释,我需要设置旋转矩阵R,然后对图像I1执行k*R*inv(k)*h ,以获得所需的旋转图像I3。

I have been facing problems when I try to set this rotation matrix R. I have used this method to set the matrix R. 尝试设置此旋转矩阵R时遇到问题。我使用此方法设置矩阵R。

To test my code, I initially tried to rotate the image around the z-axis by 10 degrees but I wasn't getting the correct output. 为了测试我的代码,我最初尝试将图像绕z轴旋转10度,但没有得到正确的输出。

My partial Python code: 我的部分Python代码:

theta_in_degrees = 10
theta_in_radians = theta_in_degrees*math.pi/180
ux=0.0 
uy=0.0 
uz=1.0 
vector_normalize_factor = math.sqrt(ux*ux+uy*uy+uz*uz)
ux=ux/vector_normalize_factor
uy=uy/vector_normalize_factor
uz=uz/vector_normalize_factor
print "ux*ux+uy*uy+uz*uz = ", ux*ux+uy*uy+uz*uz 
rotation_matrix = np.zeros([3,3])
c1 = math.cos(theta_in_radians)
c2 = 1-c1
s1 = math.sin(theta_in_radians)
rotation_matrix[0][0] = c1+ux*ux*c2
rotation_matrix[0][1] = ux*uy*c2-uz*s1
rotation_matrix[0][2] = ux*uz*c2+uy*s1
rotation_matrix[1][0] = uy*ux*c2+uz*s1
rotation_matrix[1][1] = c1+uy*uy*c2
rotation_matrix[1][2] = uy*uz*c2-ux*s1
rotation_matrix[2][0] = uz*ux*c2-uy*s1
rotation_matrix[2][1] = uz*uy*c2+ux*s1
rotation_matrix[2][2] = c1+uz*uz*c2
print "rotation_matrix = ", rotation_matrix
R = rotation_matrix
#Calculate homography H1 between reference top view and rotated frame
k_inv = np.linalg.inv(k)
Hi = k.dot(R)
Hii = k_inv.dot(h)
H1 = Hi.dot(Hii)
print "H1 = ", H1
im_out = cv2.warpPerspective(im_src, H1, (im_dst.shape[1],im_dst.shape[0]))

Here, img_src is the source of I1. 在这里, img_src是I1的来源。

The result I got when I tried the above code is a black image with no part of the image visible. 尝试上述代码时得到的结果是黑色图像,看不到图像的任何部分。 However, when I changed the value of theta_in_degrees to the following values, these were my outputs: 但是,当我将theta_in_degrees的值theta_in_degrees为以下值时,这些是我的输出:

0.00003 0.00003

在此处输入图片说明

0.00006 0.00006

在此处输入图片说明

0.00009 0.00009

在此处输入图片说明

Why is the rotation working only for such small values of theta_in_degrees ? 为什么旋转仅对theta_in_degrees这样小的值theta_in_degrees Also, the rotation visible in the images is not actually happening around the z-axis. 同样,图像中可见的旋转实际上并没有围绕z轴发生。 Why isn't the image rotating about the z-axis? 为什么图像不绕z轴旋转? Where am I going wrong and how can I fix these issues? 我在哪里出错,如何解决这些问题?

h matrix: h矩阵:

[[  1.71025842e+00  -7.51761942e-01   1.02803446e+02]
 [ -2.98552735e-16   1.39232576e-01   1.62792482e+02]
 [ -1.13518150e-18  -2.27094753e-03   1.00000000e+00]]

k matrix: k矩阵:

[[  1.41009391e+09   0.00000000e+00   5.14000000e+02]
 [  0.00000000e+00   1.78412347e+02   1.17000000e+02]
 [  0.00000000e+00   0.00000000e+00   1.00000000e+00]]

Edit: 编辑:

After incorporating the suggestion by Toby Collins, I set the top left value of k to be the same as k[1][1] . 纳入Toby Collins的建议后,我将k左上角值设置为与k[1][1] When I now perform rotation about the z-axis, I get the correct rotated images for all values of theta_in_degrees from 0 to 360. However, when I try to rotate the image about the y-axis by changing the ux, uy and uz in the above code to the following, I get absurd rotation results: 现在,当我绕着z轴执行旋转时, theta_in_degrees从0到360的所有theta_in_degrees值,我得到了正确的旋转图像。但是,当我尝试通过更改ux,uy和uz来绕y轴旋转图像时,上面的代码如下,我得到了荒谬的旋转结果:

ux=0.0 
uy=1.0 
uz=0.0 

Some samples for different values of theta_in_degrees and the corresponding results for rotation about the y-axis are shown below: 下面显示了不同theta_in_degrees值的一些样本以及绕y轴旋转的相应结果:

-10 -10

在此处输入图片说明

-40 -40

在此处输入图片说明

-90 -90

在此处输入图片说明

-110 -110

在此处输入图片说明

Where am I still going wrong? 我仍然在哪里错? Also, why is there such a huge drop in the length and width of successive yellow stripes in a rotated image? 另外,为什么旋转的图像中连续的黄色条纹的长度和宽度有如此大的下降? And why does a part of the image wrap around (for example, the results of rotation by -90 and -110 degrees)? 以及为什么图像的一部分会回绕(例如,旋转-90度和-110度的结果)?

The second part of my question is this: The vector equation of my axis of rotation is (320, 0, -10)+t(0, 1, 0) . 我的问题的第二部分是:我旋转轴的矢量方程为(320, 0, -10)+t(0, 1, 0) In order to use this method , to calculate the rotation matrix, I need to define the ux , uy and uz of the axis of rotation such that ux^2+uy^2+uz^2=1 . 为了使用此方法来计算旋转矩阵,我需要定义旋转轴的uxuyuz ,以使ux^2+uy^2+uz^2=1 This would be straightforward if the rotation needs to be done around one of the coordinate axes (as I am currently doing for testing purposes). 如果需要绕坐标轴之一旋转(如我目前出于测试目的),这将很简单。 But how do I get these values of ux , uy and uz if the t in the vector equation of my rotation axis is variable? 但是,如果旋转轴矢量方程中的t是可变的,如何获得uxuyuz这些值? I am also open to suggestions regarding any other approaches to finding a suitable rotation matrix R such that the rotation happens around the axis I have mentioned (say, by x degrees). 我也乐于接受任何其他寻找合适的旋转矩阵R的方法的建议,以使旋转围绕我提到的轴(例如x度)发生。

The difficulty you are having is that your homography matrix h does not correspond well with a projection obtained with a sensible perspective camera. 您所面临的困难是,单应矩阵h与使用灵敏透视相机获得的投影不太吻合。 I think there is a simpler approach. 我认为有一种更简单的方法。

Fundamentally, you needed to be very clear about your technical goal, and separate this from your approach for solving it. 从根本上讲,您需要非常清楚自己的技术目标,并将其与解决问题的方法分开。 Always do this whenever you tackle any vision problem. 解决任何视力问题时,请务必执行此操作。

Technical goal 技术目标

So let's be clear about the technical goal. 因此,让我们明确一下技术目标。 You have a top-down image of a planar surface (also called a rectified view). 您具有自顶向下的平面图像(也称为校正视图)。 Normally you would call this surface the model , defined on the plane z=0. 通常,您将此表面称为模型 ,定义在平面z = 0上。 You want to render this model. 您要渲染此模型。 Specifically you want to do the following; 具体来说,您想执行以下操作;

  1. A virtual perspective camera is created that is looking at the model from a particular viewpoint. 创建了一个虚拟透视相机,该相机从特定视点观看模型。 We define this model-to-camera rigid transform by R 1, t 1, with an intrinsic matrix K . 我们通过R 1, t 1定义此模型到相机的刚性变换,并使用一个固有矩阵K。
  2. The camera is moved by rotating it about its centre of projection. 通过绕其投影中心旋转照相机来移动照相机。 Let's denote this rotation by R 2. 让我们用R 2表示这种旋转。
  3. The model is rendered using the view from 2. We will call this image I2 使用来自2的视图渲染模型。我们将此图像称为I2

For simplicity I'm going to use T( R , t ) to denote the 4x4 homogeneous rigid transform for some rotation R and translation t . 为简单起见,我将使用T( Rt )表示某些旋转R和平移t的4x4均匀刚性变换。 The model-to-camera transform at stage 3 is therefore given by T =T( R2 , (0,0,0)) x T( R1 , t 1). 因此,在阶段3的模型到摄像机的变换由T = T( R2 ,(0,0,0))x T( R1t 1)给出。

Rendering options 渲染选项

There are two good ways to create I2 有两种创建I2的好方法

  1. Use a rendering engine such as OpenGL or Ogre. 使用渲染引擎,例如OpenGL或Ogre。 The advantage of this is that it can be easy to make a GUI for changing the camera viewpoint and other complex rendering effects can be added. 这样做的优点是可以很容易地制作用于更改相机视点的GUI,并且可以添加其他复杂的渲染效果。

  2. Determine the model-to-image homography matrix and render with OpenCV using warpPerspective . 确定模型到图像的单应矩阵,并使用warpPerspective使用OpenCV进行warpPerspective The advantage of this is that it can be done in a few lines without breaking into rendering software. 这样做的好处是可以在几行之内完成,而无需使用渲染软件。 The disadvantage is that you can get some strange effects if the homography has a vanishing point in the render (as you are observing). 缺点是,如果单应性在渲染中消失(如您所观察的),则可能会得到一些奇怪的效果。 More on that point later. 关于这一点的更多信息。

Definition of model-to-image homography 模型到图像单应性的定义

To use the OpenCV approach we define the model-to-image homography as H 2. This can be defined in terms of the camera parameters. 要使用OpenCV方法,我们将模型与图像的单应性定义为H2 。这可以根据相机参数进行定义。 Consider a point p =(x,y,1) on the model plane in homogeneous coordinates. 考虑模型平面上同质坐标中的点p =(x,y,1)。 Its position q in I2 in homogeneous coordinates is given by q = KM p , where M is. 它在齐次坐标中在I2中的位置qq = KM p给出 ,其中M为。 3x3 matrix given by M =(T00,T01,T03; T10,T11,T13; T20,T21,T23). M =(T00,T01,T03; T10,T11,T13; T20,T21,T23)给出的3x3矩阵。 This is straightforward to derive using the perspective camera model. 使用透视相机模型可以直接得出结论。 Consequently, we now have that H 2 = KM . 因此,我们现在有H 2 = KM

Instantiate the homography matrix 实例化单应矩阵

Now we have to instantiate the homography, unlike your proposed approach, I would define it using a particular camera configuration, by specifying K , R 1, t 1, R 2. The choice is up to you! 现在,我们必须实例化单应性,与您提出的方法不同,我将使用特定的摄像机配置来定义它,方法是指定KR 1, t 1, R 2。选择取决于您! To simplify the definition of K you can use a simple form with one free parameter (focal length), and set the principal point to the image centre. 为了简化K的定义,您可以使用带有一个自由参数(焦距)的简单形式,并将主点设置为图像中心。 For typical cameras f ranges between 0.5 and 2 time the image width, but it's up to you. 对于典型的相机,f的范围是图像宽度的0.5到2倍,但这取决于您。 You then need to set R 1 and t 1 depending on the viewing angle/distance that you want for your viewpoint. 然后,您需要根据所需的视角/距离来设置R 1和t 1。

How is this different to your current approach 这与您目前的方法有何不同

I want to emphasize that this does not contradict any of the previous answers I have given. 我想强调一点,这与我以前给出的任何答案都不矛盾。 It is simply a different approach which may be easier to manage. 这只是一种不同的方法,可能更易于管理。 Essentially, here I am proposing to define your homography directly using camera parameters (which you set as you want). 本质上,这里我建议直接使用相机参数(您可以根据需要设置)定义单应性。 This guarantees you are using a sensible intrinsic matrix (because you set it yourself). 这保证您使用的是明智的内在矩阵(因为您自己设置了它)。 It is different to your approach where you first create a homography and then want to find the matching camera parameters (which may or not be physically sensible). 这与您首先创建一个单应性然后想要找到匹配的相机参数(在物理上或可能不是物理上合适)的方法不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM