问题:
我一直在使用一种将2D点投影到3D世界坐标的方法,但是问题是这种方法似乎只在图片的特定区域内有效,特别是在Y暗淡的图片中间。
其中y = 900像素到960像素左右(约为图像的一半,因为高度为1900像素)。在X轴上的位置似乎并不影响结果。
如果任何点位于图像中的该区域之外,则由于某种原因投影误差会变得相对较大。
希望,如果您识别出正在使用的方法,则可以知道这是预期的还是将2D点投影到3D时的通常行为。
方法:
我已经校准好相机,并收到了dist。矩阵和内在/外在参数。
然后,我将摄像机相对于地板成一定角度安装。然后,我放置了一个棋盘(27毫米),并提取了8个角及其等效像素pos。第一个角被视为origo。 所有世界坐标的Z都设置为0,因为它们都位于水平平面(棋盘)上。
corners_mm =
[[[ 0.0 0.0 0.0]]
[[ 81.0 0.0 0.0]]
[[189.0 0.0 0.0]]
[[ 0.0 81.0 0.0]]
[[189.0 81.0 0.0]]
[[ 0.0 135.0 0.0]]
[[ 81.0 135.0 0.0]]
[[189.0 135.0 0.0]]]
它们的等效像素坐标
corners_px =
[[[ 792.19329834 856.27441406]]
[[1206.41516113 857.33868408]]
[[1759.16418457 858.57226562]]
[[ 714.56268311 1218.61853027]]
[[1820.47705078 1222.60766602]]
[[ 647.03851318 1526.37414551]]
[[1172.93127441 1523.64477539]]
[[1874.76403809 1532.85961914]]]
然后我通过使用:找到平移矩阵和旋转矩阵来进行>
(success, rvec, tvec) = cv2.solvePnP(corners_mm, corners_px, camera_matrix, dist_coeffs, flags=cv2.SOLVEPNP_ITERATIVE)
之后,要将2D像素点投影到3D世界中,请使用以下方程式:
if success:
for t in range(len(testPoints)):
test_point = np.array([(corners2[testPoints[t]][0][0],corners2[testPoints[t]][0][1],1)])
R_mtx, jac=cv2.Rodrigues(rvec1)
R_mtx_inv = np.linalg.inv(R_mtx)
c_mtx_inv = np.linalg.inv(camera_matrix)
leftS = np.dot(R_mtx,np.dot(c_mtx_inv,test_point.T))
rightS = np.dot(R_mtx_inv,tvec1)
s = (0 + rightS[2][0]/leftS[2][0]) # Since the point lies on z=0
p = np.dot(R_mtx_inv,(np.dot(s,np.dot(c_mtx_inv,test_point.T))-tvec1))
error = np.sqrt((p[0]-cornersMM[testPoints[t]][0][0])**2+(p[1]-cornersMM[testPoints[t]][0][1])**2)
print("Pixel coord: ",corners2[testPoints[t]][0])
print("Point p=",p.T,". Real Point p=",cornersMM[testPoints[t]][0],". Error= ",error,"\n")
这是在运行其他棋盘角之后的结果:
Scaling factor s = 383.9287552918096
Pixel coord: [914.2861 966.66876]
Point p= [[26.48480073 23.85364395 4.02147882]] . Real Point p= [27. 27.] . Error= [3.18825762]
Scaling factor s = 384.2605213415536
Pixel coord: [1058.0303 966.8387]
Point p= [[53.69952146 23.46813802 4.44696027]] . Real Point p= [54. 27.] . Error= [3.54462077]
Scaling factor s = 384.62030282668377
Pixel coord: [1201.3347 967.20044]
Point p= [[80.87623388 23.09493248 4.91692147]] . Real Point p= [81. 27.] . Error= [3.90702833]
Scaling factor s = 384.98106229340203
Pixel coord: [1343.8606 967.5755]
Point p= [[107.95585216 22.72399509 5.38878594]] . Real Point p= [108. 27.] . Error= [4.27623281]
Scaling factor s = 385.36643137335125
Pixel coord: [1487.4963 968.09564]
Point p= [[135.29957545 22.35815082 5.8986339 ]] . Real Point p= [135. 27.] . Error= [4.65150613]
Scaling factor s = 385.7547941046753
Pixel coord: [1631.5691 968.6244]
Point p= [[162.78170295 21.99088556 6.41271338]] . Real Point p= [162. 27.] . Error= [5.0697423]
Scaling factor s = 402.38970043677546
Pixel coord: [ 895.38715 1086.4141 ]
Point p= [[19.06780191 31.62058907 33.26717073]] . Real Point p= [27. 54.] . Error= [23.7435844]
Scaling factor s = 402.7540074449231
Pixel coord: [1045.7467 1086.4874]
Point p= [[48.90153119 31.19823733 33.7345693 ]] . Real Point p= [54. 54.] . Error= [23.36481896]
Scaling factor s = 403.1130389085318
Pixel coord: [1195.3281 1086.5355]
Point p= [[78.63475653 30.77563645 34.19398602]] . Real Point p= [81. 54.] . Error= [23.34449483]
Scaling factor s = 403.57372225847223
Pixel coord: [1344.4689 1087.2102]
Point p= [[108.33465481 30.3956586 34.8144114 ]] . Real Point p= [108. 54.] . Error= [23.6067136]
Scaling factor s = 404.0358986308904
Pixel coord: [1494.3865 1087.8763]
Point p= [[138.2575754 30.01201531 35.43638351]] . Real Point p= [135. 54.] . Error= [24.20816406]
Scaling factor s = 404.57224193636085
Pixel coord: [1645.1809 1088.9764]
Point p= [[168.43617735 29.65409449 36.17480541]] . Real Point p= [162. 54.] . Error= [25.18228532]
Scaling factor s = 424.7669812677892
Pixel coord: [ 874.1305 1217.6154]
Point p= [[ 9.96176828 41.03744603 68.71751552]] . Real Point p= [27. 81.] . Error= [43.44314744]
Scaling factor s = 425.103753756061
Pixel coord: [1031.8788 1217.1991]
Point p= [[43.00873936 40.54202738 69.12957342]] . Real Point p= [54. 81.] . Error= [41.92440052]
Scaling factor s = 425.52607265299326
Pixel coord: [1188.8845 1217.2631]
Point p= [[75.9467962 40.08403135 69.67742615]] . Real Point p= [81. 81.] . Error= [41.22682815]
Scaling factor s = 426.0181876969468
Pixel coord: [1344.9645 1217.7203]
Point p= [[108.7565942 39.65732435 70.33621624]] . Real Point p= [108. 81.] . Error= [41.34959812]
Scaling factor s = 426.63193208820377
Pixel coord: [1502.17 1218.8234]
Point p= [[141.89057117 39.27462706 71.1863252 ]] . Real Point p= [135. 81.] . Error= [42.29050387]
这样,您可以看到误差随着Y轴的增加而迅速增加。
该错误是否还会增加?