投影2D像素点3D世界点-分析

时间:2019-11-12 12:58:23

标签: python opencv perspectivecamera opencv-solvepnp

问题:
我一直在使用一种将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轴的增加而迅速增加。

该错误是否还会增加?

0 个答案:

没有答案