क्या मेरा दृष्टिकोण गणित सही है?


24

मुझे एक गृहकार्य मिला है जिसमें मुझे कुछ बदलावों की गणना करनी है और एक व्यापक परिवर्तन का उपयोग करते हुए प्लॉट करना है, लेकिन मुझे यकीन नहीं है कि मेरे परिणाम सही हैं, क्योंकि कैमरा निर्देशांक का उपयोग करते हुए 3 डी प्लॉट छवि निर्देशांक का उपयोग करते हुए 2d प्लॉट से बहुत अलग दिखता है । क्या आप मुझे यह समझने में मदद कर सकते हैं कि क्या गलत है?

यह वही दिया जाता है: कैमरा बिंदु पर है , विश्व निर्देशांक (मीटर में) में निर्दिष्ट है। कैमरा कॉर्डिनेट सिस्टम को दुनिया के Y अक्ष के चारों ओर से घुमाया जाता है , इसलिए यह रोटेशन मैट्रिक्स है θ = 160 डब्ल्यू आर सी = [ सी एस ( θ ) 0 एस मैं n ( θ ) 0 1 0 - एस मैं n ( θ ) 0 सी एस ( θ ) ]डब्ल्यूटीसी=[-1,1,5]टीθ=160wआरसी=[सीरों(θ)0रोंमैंn(θ)010-रोंमैंn(θ)0सीरों(θ)]

कैमरा पैरामीटर हैं: , , ,रों एक्स = रों y = 0.01 मीटर मीटर / पी एक्स एक्स = 320 पी एक्स y = 240 पी एक्स=16मीटरमीटररोंएक्स=रोंy=0.01मीटरमीटर/पीएक्सएक्स=320पीएक्सy=240पीएक्स

नमूना बिंदु (विश्व निर्देशांक में):

डब्ल्यूपी1=[1,1,0.5]टी

डब्ल्यूपी2=[1,1.5,0.5]टी

डब्ल्यूपी3=[1.5,1.5,0.5]टी

डब्ल्यूपी4=[1.5,1,0.5]टी

मुझे कैमरा निर्देशांक और छवि निर्देशांक में बिंदुओं की गणना और प्लॉट करना है, इसलिए मैंने निम्नलिखित कोड ऑक्टेव में लिखा है:

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

और ये वे स्क्रिप्ट हैं जो मुझे स्क्रिप्ट से मिली हैं: मैं उम्मीद कर रहा था कि वे कुछ इसी तरह के थे, लेकिन वे ऐसा नहीं करते हैं।

3 डी प्लाट

कैमरा निर्देशांक में प्लॉट

2D प्लॉट

छवि निर्देशांक में प्लॉट


8
+1 यह दिखाने के लिए कि होमवर्क प्रश्न उच्च गुणवत्ता वाले प्रश्न हो सकते हैं। :)
मार्टिन एंडर

2
जैसा कि मेटा पर बताया गया है कि यह प्रश्न एक अच्छे उत्तर के योग्य है। मेरे पास खुद नहीं है, लेकिन मैं अपनी प्रतिष्ठा किसी ऐसे व्यक्ति को देने के लिए खुश हूं जो ऐसा करता है।
ट्रिकोप्लाक्स 13

@trichoplax की समस्या यह है कि इसका निर्माण मैटलैब में किया गया है।
पूजा 24

@ जूजा आह अच्छी बात। यदि बाउंटी अवधि के दौरान कोई मैटलैब विशेषज्ञ कदम नहीं उठाता है, तो मैं ऑक्टेव को सीखने पर विचार करूंगा कि क्या वह समाधान खोजने के लिए पर्याप्त है।
ट्राइकोप्लाक्स

1
यह मेरे लिए बहुत स्पष्ट नहीं है कि पहली छवि का क्या मतलब है। दूसरा एक कैमरे के दृष्टिकोण से है, और लिफाफे के अनुमान के पीछे मुझे लगता है कि यह सही लगता है।
जुलिएन गुर्टॉल्ट

जवाबों:


8

दोनों आंकड़ों में अपनी कुल्हाड़ियों की पहचान करना और कैमरे की स्थिति को अपने पहले आंकड़े में जोड़ना आपको यह समझने में मदद करेगा कि क्या हो रहा है।

एक्सyz

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

0.016एसएक्स=एसy=0.00010.00001

[-1,1,एक्स]z=0.5एक्सटीn(160°)(5-0.5)=1.64 ...0.64 y yएक्स=-1), इसलिए केंद्र पर समाप्त हो जाएगा , जिसका अर्थ है कि अंक छवि के दाहिने खंड पर दिखाई देंगे। इसके अलावा, कैमरे में दो बिंदुओं के समान निर्देशांक होते हैं, और चूंकि निर्देशांक रोटेशन द्वारा नहीं बदले जाते हैं, इसलिए उन्हें परिवर्तन के बाद भी समान निर्देशांक पर समाप्त होना चाहिए, छवि की केंद्रीय पंक्ति पर।0.64yy

अपने उत्तर की जांच करने का एक अच्छा तरीका ब्लेंडर जैसे मौजूदा 3 डी मॉडलर का उपयोग करके है: ब्लेंडर में 3 डी दृश्य ब्लेंडर के निर्देशांक प्रणाली से सावधान रहें, उदाहरण के लिए डिफ़ॉल्ट कैमरा वेक्टर है [0, 0, -1]। यहाँ प्रस्तुतिकरण है: ब्लेंडर में रेंडर क्षेत्र को अधिक दृश्यमान बनाने के लिए फ़ोकल को दूसरे मूल्य पर सेट किया गया था। इसलिए हम देखते हैं कि नीचे के दो बिंदु छवि की मध्य पंक्ति पर हैं और बिंदु छवि के दाईं ओर थोड़े हैं।

मैंने पायथन में आपका होमवर्क लागू किया:

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

इससे मुझे वे आंकड़े मिलते हैं: क्रमशः: विश्व निर्देशांक, कैमरा निर्देशांक, कैमरा निर्देशांक थोड़ा घूमने के लिए कैमरा उन्मुखीकरण फिट बैठता है (ध्यान दें कि यहां कैमरा वेक्टर आंकड़ा दृष्टिकोण की ओर जाता है, यह आंकड़ा दर्ज नहीं करता है) और छवि निर्देशांक।विश्व समन्वय करता है कैमरा निर्देशांक कैमरा निर्देशांक घुमाया गया छवि निर्देशांक

इसलिए हम देखते हैं कि नीचे के बिंदुओं के लिए ऊर्ध्वाधर निर्देशांक मध्य पंक्ति (240) पर सही ढंग से हैं और अंक छवि के दाईं ओर (क्षैतिज मान> 320) हैं।

-f/Sxy[0,0,1]एक्स

[0,-1,0]

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.