Là quan điểm toán học của tôi đúng?


24

Tôi đã có một bài tập về nhà trong đó tôi phải tính toán và vẽ một số điểm bằng cách sử dụng phép biến đổi theo phương pháp, nhưng tôi không chắc kết quả của mình là đúng, vì biểu đồ 3d sử dụng tọa độ Camera trông rất khác so với biểu đồ 2d sử dụng tọa độ hình ảnh . Bạn có thể giúp tôi hiểu những gì sai?

Đây là những gì được đưa ra: Máy ảnh ở điểm W T C = [ - 1 , 1 , 5 ] T , được chỉ định trong tọa độ thế giới (tính bằng mét). Chiếc máy ảnh hệ tọa độ có thể xoay quanh trục y của tham chiếu thế giới bởi θ = 160 o , vì vậy nó của ma trận xoay là w R c = [ c o s ( θ ) 0 s i n ( θ ) 0 1 0 - s i n (WTC= =[-1,1,5]Tθ= =160owRc= =[coS(θ)0Stôin(θ)010-Stôin(θ)0coS(θ)]

Thông số máy ảnh là: , s x = s y = 0,01 m m / p x , o x = 320 p x , o y = 240 p xf= =16mmSx= =Sy= =0,01mm/pxox= =320pxoy= =240px

Điểm mẫu (theo tọa độ thế giới):

WP1= =[1,1,0,5]T

WP2= =[1,1,5,0,5]T

WP3= =[1,5,1,5,0,5]T

WP4= =[1,5,1,0,5]T

Tôi phải tính toán và vẽ các điểm trong tọa độ camera và tọa độ hình ảnh, vì vậy tôi đã viết đoạn mã sau trong Octave:

%camera intrinsic parameters
f = 16
Sx = 0.01
Sy = 0.01
Ox = 320
Oy = 240

%given points, in world coordinate
wP1 = transpose([1, 1, 0.5])
wP2 = transpose([1, 1.5, 0.5])
wP3 = transpose([1.5, 1.5, 0.5])
wP4 = transpose([1.5, 1, 0.5])

% camera translation matrix
wTc = transpose([-1, 1, 5])

% rotation angle converted to rad
theta = 160 / 180 * pi

%camera rotation matrix
wRc = transpose([cos(theta), 0, sin(theta); 0, 1, 0; -sin(theta), 0, cos(theta)])

%transform the points to homogeneous coordinates
wP1h = [wP1; 1]
wP2h = [wP2; 1]
wP3h = [wP3; 1]
wP4h = [wP4; 1]

%separate each line of the rotation matrix
R1 = transpose(wRc(1 , :))
R2 = transpose(wRc(2 , :))
R3 = transpose(wRc(3 , :))

%generate the extrinsic parameters matrix
Mext = [wRc, [-transpose(R1) * wTc; -transpose(R2) * wTc; -transpose(R3) * wTc]]

%intrinsic parameters matrix
Mint = [-f/Sx, 0, Ox; 0, -f/Sy, Oy; 0, 0, 1]

% calculate coordinates in camera coordinates
cP1 = wRc * (wP1 - wTc)
cP2 = wRc * (wP2 - wTc)
cP3 = wRc * (wP3 - wTc)
cP4 = wRc * (wP4 - wTc)

% put coordinates in a list for plotting

x = [cP1(1), cP2(1), cP3(1), cP4(1), cP1(1)]
y = [cP1(2), cP2(2), cP3(2), cP4(2), cP1(2)]
z = [cP1(3), cP2(3), cP3(3), cP4(3), cP1(3)]

%plot the points in 3D using camera coordinates
plot3(x, y, z, "o-r")

pause()

% calculate the points in image coordinates
iP1 = Mint * (Mext * wP1h)
iP2 = Mint * (Mext * wP2h)
iP3 = Mint * (Mext * wP3h)
iP4 = Mint * (Mext * wP4h)

%generate a list of points for plotting
x = [iP1(1) / iP1(3), iP2(1) / iP2(3), iP3(1) / iP3(3), iP4(1) / iP4(3), iP1(1) / iP1(3)]
y = [iP1(2) / iP1(3), iP2(2) / iP2(3), iP3(2) / iP3(3), iP4(2) / iP4(3), iP1(2) / iP1(3)]

plot(x, y, "o-r")

pause()

Và đây là những âm mưu tôi có được từ kịch bản: Tôi đã hy vọng chúng có phần giống nhau, nhưng chúng không giống nhau.

Cốt truyện 3D

Âm mưu trong tọa độ camera

Cốt truyện 2D

Vẽ trong tọa độ hình ảnh


8
+1 để hiển thị rằng các câu hỏi bài tập về nhà có thể là câu hỏi chất lượng cao. :)
Martin Ender

2
Như đã chỉ ra trên meta câu hỏi này xứng đáng có một câu trả lời hay. Tôi không có một mình, nhưng tôi rất vui khi được cung cấp một số danh tiếng của mình cho một người nào đó.
trichoplax

@trichoplax vấn đề là nó được thực hiện trong MATLAB.
joojaa

@joojaa ah điểm tốt. Nếu không có chuyên gia matlab nào bước vào giai đoạn tiền thưởng, tôi sẽ xem xét việc học Octave để xem liệu điều đó có đủ gần để tìm ra giải pháp hay không.
trichoplax

1
Nó không rõ ràng cho tôi ý nghĩa của hình ảnh đầu tiên. Cái thứ hai là từ quan điểm của máy ảnh, và sau khi ước tính phong bì tôi nghĩ nó có vẻ chính xác.
Julien Guertault

Câu trả lời:


8

Xác định các trục của bạn trong cả hai hình và thêm vị trí camera vào hình đầu tiên của bạn sẽ giúp bạn hiểu những gì đang diễn ra.

xyz

[0,0,1][0,1,0]

0,016Sx= =Sy= =0,00010,00001

[-1,1,x]z= =0,5xtmộtn(160°)(5-0,5)= =1,64 ...x= =-10,64yy

Một cách tốt để kiểm tra câu trả lời của bạn là sử dụng trình tạo mô hình 3D hiện có như Blender: Cảnh 3D trong Blender Hãy thận trọng với hệ tọa độ của Blender, ví dụ như vectơ máy ảnh mặc định là [0, 0, -1]. Đây là kết xuất: Kết xuất trong Blender Tiêu điểm được đặt thành giá trị khác để làm cho hình cầu rõ hơn. Vì vậy, chúng ta thấy rằng hai điểm dưới cùng nằm ở hàng giữa của hình ảnh và các điểm hơi ở bên phải của hình ảnh.

Tôi đã triển khai bài tập về nhà của bạn bằng Python:

import numpy as np

from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import axes3d, Axes3D


# Parameters
f_mm = 0.016
f_px = f_mm / 0.00001
t_cam = np.array([[-1., 1., 5.]]).T
t_cam_homogeneous = np.vstack((t_cam, np.array([[0]])))
theta = 160. * np.pi / 180.
ox = 320
oy = 240
# Rotation and points are in homogeneous coordinates
rot_cam = np.array([[np.cos(theta), 0, np.sin(theta)],
                    [0, 1, 0],
                    [-np.sin(theta), 0, np.cos(theta)]])
points = np.array([[1, 1, 0.5, 1],
                   [1, 1.5, 0.5, 1],
                   [1.5, 1.5, 0.5, 1],
                   [1.5, 1, 0.5, 1]]).T

# Compute projection matrix using intrinsics and extrinsics
intrinsics = np.array([[f_px, 0, ox],
                       [0, f_px, oy],
                       [0, 0, 1]])
extrinsics = np.hstack((rot_cam, rot_cam.dot(-t_cam)))

rot_cam2 = np.identity(4); rot_cam2[:3,:3] = rot_cam
camera_coordinates = rot_cam2.dot(points - t_cam_homogeneous)
camera_coordinates = camera_coordinates[:3,:] / camera_coordinates[3,:]

# Perform the projection
projected_points = intrinsics.dot(camera_coordinates)
projected_points = projected_points[:2,:] / projected_points[2,:]
projected_points[0,:] = -projected_points[0,:] # Inverted x-axis because camera is pointing toward [0, 0, 1]

fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(points[0,:], points[1,:], points[2,:], label="Points")
ax.scatter(t_cam[0], t_cam[1], t_cam[2], c="red", label="Camera")
ax.set_xlabel("X axis"); ax.set_ylabel("Y axis"); ax.set_zlabel("Z axis")
plt.title("World coordinates")
plt.legend()
plt.savefig('world_coordinates.png', dpi=300, bbox_inches="tight")

fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(camera_coordinates[0,:], camera_coordinates[1,:], camera_coordinates[2,:], label="Points")
ax.scatter(0, 0, 0, c="red", label="Camera")
ax.set_xlabel("X axis"); ax.set_ylabel("Y axis"); ax.set_zlabel("Z axis")
plt.title("Camera coordinates")
plt.legend()
plt.savefig('camera_coordinates.png', dpi=300, bbox_inches="tight")

plt.figure()
plt.scatter(projected_points[0,:], projected_points[1,:])
plt.xlabel("X axis"); plt.ylabel("Y axis")
plt.title("Image coordinates")
plt.savefig('image_coordinates.png', dpi=300, bbox_inches="tight")

plt.show()

Điều này mang lại cho tôi những số liệu: Tương ứng: Tọa độ thế giới, Tọa độ máy ảnh, Tọa độ máy ảnh được xoay để khớp với hướng máy ảnh một chút (lưu ý rằng ở đây vectơ camera đi về phía quan điểm hình, nó không "nhập" hình) và tọa độ hình ảnh.Tọa độ thế giới Tọa độ camera Tọa độ camera quay Tọa độ hình ảnh

Vì vậy, chúng ta thấy rằng tọa độ dọc cho các điểm dưới cùng là chính xác ở hàng giữa (240) và các điểm nằm ở bên phải của hình ảnh (giá trị ngang> 320).

-f/Sxy[0,0,1]x

[0,-1,0]

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.