Benim bakış açım matematik doğru mu?


24

Pespective dönüşümü kullanarak bazı noktaları hesaplamak ve çizmek zorunda olduğum bir ödevim var, ancak kamera koordinatlarını kullanan 3d arsa görüntü koordinatlarını kullanarak 2d arsadan çok farklı göründüğü için sonuçlarımın doğru olduğundan emin değilim. . Neyin yanlış olduğunu anlamama yardım eder misin?

Bu verilen: Kamera dünya koordinatlarında (metre cinsinden) belirtilen W T C = [ - 1 , 1 , 5 ] T noktasında . Kamera koordinat sistemi Y çevresinde döndürülür dünya referans eksenine θ = 160 o 's rotasyon matrisi yani, ağırlık R c = [ c o s ( θ ) 0 s i n ( θ ) 0 1 0 - s i n (WTC=[1,1,5]Tθ=160owRc=[cos(θ)0sin(θ)010sin(θ)0cos(θ)]

Kamera parametresi: f=16mm , sx=sy=0.01mm/px , ox=320px , oy=240px

Örnek noktalar (dünya koordinatlarında):

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

Kamera koordinatlarındaki ve görüntü koordinatlarındaki noktaları hesaplamalı ve çizmeliyim, bu yüzden aşağıdaki kodu Octave dilinde yazdım:

%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()

Ve bunlar senaryodan aldığım grafikler: Biraz daha benzer olmalarını bekliyordum ama öyle görünmüyorlardı.

3B arsa

Kamera koordinatlarında arsa

2B arsa

Görüntü koordinatlarında arsa


8
Ödev sorularının yüksek kaliteli sorular olabileceğini göstermek için + 1. :)
Martin Ender

2
Metada belirtildiği gibi , bu soru iyi bir cevabı hak ediyor. Kendimde bir tane yok, ama itibarımı birilerine vermekten mutluyum.
trichoplax

@trichoplax problem şu ki matlabda yapılıyor.
joojaa

@ joojaa ah iyi bir nokta. Ödül döneminde hiçbir matlab uzmanı devreye girmezse, çözüm bulmak için yeterince yakın olup olmadığını öğrenmek için Octave öğrenmeyi düşüneceğim .
trichoplax

1
İlk görüntünün ne anlama geldiği bana çok açık gelmiyor. İkincisi, kameranın bakış açısından ve zarf tahmininin bir arkasından sonra doğru göründüğünü düşünüyorum.
Julien Guertault

Yanıtlar:


8

Eksenlerinizi her iki şekilde de belirlemek ve ilk pozisyonunuza kamera konumunu eklemek, neler olduğunu anlamanıza yardımcı olacaktır.

xyz

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

0.016Sx=Sy=0.00010.00001

[1,1,x]z=0.5xtan(160°)(50.5)=1.64...x=10.64yİki nokta olarak koordinatlar ve koordinatları rotasyon tarafından değiştirilmediğinden, dönüşümün ardından aynı koordinatlarda bulunmalı, yani görüntünün orta satırında.y

Cevabınızı kontrol etmenin iyi bir yolu, Blender gibi mevcut bir 3D modelleyiciyi kullanmaktır: Blender'da 3B sahne Blender'ın koordinat sistemi konusunda dikkatli olun, örneğin varsayılan kamera vektörü [0, 0, -1]. İşte render: Render Blender'da Focal, küreyi daha görünür hale getirmek için başka bir değere ayarlandı. Bu yüzden görüyoruz ki iki nokta görüntünün orta satırında ve noktalar görüntünün sağında hafifçe.

Ödevini Python'da uyguladım:

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()

Bu da bana şu rakamları veriyor : Sırasıyla: Dünya koordinatları, Kamera koordinatları, Kamera koordinatları hafifçe kamera oryantasyonuna uyacak şekilde döndürülmüş (burada kamera vektörünün şekil bakış açısına doğru gittiğini, şekle "girmediğini" ve görüntü koordinatlarını not alın.Dünya koordinatları Kamera koordinatları Kamera koordinatları döndürülmüş Görüntü koordinatları

Dolayısıyla, alt noktaların dikey koordinatlarının orta sırada (240) doğru olduğunu ve noktaların görüntünün sağ tarafında olduğunu görüyoruz (yatay değer> 320).

Elimdeki bir hatanın negatif X değerleri bulduğuna inanıyorum, bu yüzden -f/Sxytelafi etmek için içsel matristeki focals'ı ( ) ihmal ettin . Buradaki sorun, kameranın başlangıçta dönük olduğunu varsaydığımızdır (aksi takdirde 160 ° dönüş noktalara işaret etmez). Bu şekilde bakarsanız , sola doğru giderken ekseni artar , bu eksenin tersi alınmalıdır.[0,0,1]x

Her iki sonucumuz da bana benziyor, sadece kamera için yukarı bir vektör farz ettiniz (aslında her iki eksenin de aynası yapıldı, çünkü her iki odağı da etkisizleştirdiniz) ve hesaplamayı metre yerine mm cinsinden yaptınız.[0,1,0]

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.