Opencv cv.calibrateCamera returns "argument for calibrateCamera() given by name ('flags') and position (8)"
Opencv cv.calibrateCamera returns "argument for calibrateCamera() given by name ('flags') and position (8)"
我正在尝试使用来自图像(像素位置)和现实世界位置的已知数据来校准相机。
这是我所知道的:
相机
focal_length = 3.9
image_height = 3456
image_width = 4608
esl_height = 35
sensor_height = 4.69
sensor_width = 6.26
pixel_size = 1.34/1000
FOV_x = 71.9
FOV_y = 56.7
F_x = image_width /(2 * tan(FOV_x* pi / 360))
F_y = image_height /(2 * tan(FOV_y* pi / 360))
C_x = image_width / 2
C_y = image_height / 2
row1 = [F_x,0,C_x]
row2 = [0,F_y, C_y]
row3 = [0,0,1]
camera_matrix = np.matrix([row1,row2,row3])
给出:
matrix([[3.17701054e+03, 0.00000000e+00, 2.30400000e+03],
[0.00000000e+00, 3.20254589e+03, 1.72800000e+03],
[0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])
数据
我有一个包含 49 个点的数据集,我有两个真实世界的 (x,y) 位置(我也有 z 值,但我真的只对 (x,y) 位置感兴趣。另外,我有图像中所有这些点的像素位置(它们是我执行的对象检测中的边界框中心。
id manual.location.x manual.location.y manual.location.z \
0 0 32.9878 41.9033 0.215
1 1 32.9878 44.4404 0.215
2 2 32.9878 44.4404 0.215
3 3 32.9878 44.4404 0.565
4 4 32.9878 44.4404 0.565
5 5 32.9878 44.4404 0.565
6 6 32.9878 44.4404 0.565
7 7 32.9878 44.4404 0.565
8 8 32.9878 41.9033 0.753
9 9 32.9878 44.4404 0.779
10 10 32.9878 44.4404 0.779
11 11 32.9878 44.4404 0.779
12 12 32.9878 41.9033 1.024
13 13 32.9878 44.4404 1.024
14 14 32.9878 42.7490 1.100
15 15 32.9878 43.5947 1.100
16 16 32.9878 43.5947 1.100
17 17 32.9878 43.5947 1.100
18 18 32.9878 43.5947 1.100
19 19 32.9878 44.4404 1.231
20 20 32.9878 44.4404 1.231
21 21 32.9878 44.4404 1.231
22 22 32.9878 44.4404 1.231
23 23 32.9878 42.7490 1.320
24 24 32.9878 43.5947 1.412
25 25 32.9878 42.7490 1.412
26 26 32.9878 43.5947 1.412
27 27 32.9878 44.4404 1.412
28 28 32.9878 44.4404 1.458
29 29 32.9878 44.4404 1.458
30 30 32.9878 44.4404 1.458
31 31 32.9878 44.4404 1.458
32 32 32.9878 42.7490 1.620
33 33 32.9878 42.7490 1.620
34 34 32.9878 43.5947 1.620
35 35 32.9878 43.5947 1.620
36 36 32.9878 42.7490 1.620
37 37 32.9878 44.4404 1.651
38 38 32.9878 44.4404 1.651
39 39 32.9878 44.4404 1.651
40 40 32.9878 44.4404 1.651
41 41 32.9878 44.4404 1.651
42 42 32.9878 42.7490 1.850
43 43 32.9878 42.7490 NaN
44 44 32.9878 44.4404 NaN
45 45 32.9878 44.4404 NaN
46 46 32.9878 44.4404 1.850
47 47 32.9878 43.5947 1.850
48 48 32.9878 44.4404 1.850
bbox_center_x bbox_center_y
0 4269.5 2914.0
1 1035.0 2883.5
2 843.5 2880.0
3 1516.5 2529.0
4 1247.5 2527.0
5 1730.0 2525.5
6 987.0 2522.0
7 765.5 2520.0
8 4435.0 2356.5
9 1196.0 2257.0
10 938.5 2255.0
11 704.5 2250.0
12 4547.0 1998.0
13 1291.0 1980.0
14 3681.0 1864.5
15 2394.0 1856.0
16 1931.5 1854.0
17 2043.0 1853.5
18 2043.0 1853.5
19 1620.0 1676.0
20 1267.0 1675.5
21 847.0 1672.5
22 593.5 1669.5
23 3783.5 1452.0
24 1931.5 1446.5
25 3346.5 1443.5
26 2878.0 1443.0
27 1632.0 1350.0
28 1409.0 1346.5
29 945.0 1339.5
30 727.0 1334.0
31 534.5 1332.0
32 4349.0 1109.0
33 3859.0 1101.0
34 1920.5 1097.5
35 2878.0 1090.5
36 3364.0 1087.0
37 1460.5 1037.0
38 1290.5 1036.0
39 1065.5 1034.0
40 748.0 1032.5
41 473.0 1029.0
42 4262.0 726.0
43 3683.5 713.0
44 1375.0 710.0
45 1094.5 708.0
46 850.0 705.0
47 3103.5 702.5
48 375.5 701.5
为了方便起见,我愿意让现实世界位置的z坐标(manual.location.z
)为0。
现在,我在 z 坐标 = 0 的数据上使用 cv.calibrateCamera
尝试了以下操作。因此,我执行了以下操作:
manual.location.x manual.location.y manual.location.z bbox_center_x \
0 32.9878 41.9033 0 4269.5
1 32.9878 44.4404 0 1035.0
2 32.9878 44.4404 0 843.5
3 32.9878 44.4404 0 1516.5
4 32.9878 44.4404 0 1247.5
5 32.9878 44.4404 0 1730.0
6 32.9878 44.4404 0 987.0
7 32.9878 44.4404 0 765.5
8 32.9878 41.9033 0 4435.0
9 32.9878 44.4404 0 1196.0
10 32.9878 44.4404 0 938.5
11 32.9878 44.4404 0 704.5
12 32.9878 41.9033 0 4547.0
13 32.9878 44.4404 0 1291.0
14 32.9878 42.7490 0 3681.0
15 32.9878 43.5947 0 2394.0
16 32.9878 43.5947 0 1931.5
17 32.9878 43.5947 0 2043.0
18 32.9878 43.5947 0 2043.0
19 32.9878 44.4404 0 1620.0
20 32.9878 44.4404 0 1267.0
21 32.9878 44.4404 0 847.0
22 32.9878 44.4404 0 593.5
23 32.9878 42.7490 0 3783.5
24 32.9878 43.5947 0 1931.5
25 32.9878 42.7490 0 3346.5
26 32.9878 43.5947 0 2878.0
27 32.9878 44.4404 0 1632.0
28 32.9878 44.4404 0 1409.0
29 32.9878 44.4404 0 945.0
30 32.9878 44.4404 0 727.0
31 32.9878 44.4404 0 534.5
32 32.9878 42.7490 0 4349.0
33 32.9878 42.7490 0 3859.0
34 32.9878 43.5947 0 1920.5
35 32.9878 43.5947 0 2878.0
36 32.9878 42.7490 0 3364.0
37 32.9878 44.4404 0 1460.5
38 32.9878 44.4404 0 1290.5
39 32.9878 44.4404 0 1065.5
40 32.9878 44.4404 0 748.0
41 32.9878 44.4404 0 473.0
42 32.9878 42.7490 0 4262.0
46 32.9878 44.4404 0 850.0
47 32.9878 43.5947 0 3103.5
48 32.9878 44.4404 0 375.5
bbox_center_y
0 2914.0
1 2883.5
2 2880.0
3 2529.0
4 2527.0
5 2525.5
6 2522.0
7 2520.0
8 2356.5
9 2257.0
10 2255.0
11 2250.0
12 1998.0
13 1980.0
14 1864.5
15 1856.0
16 1854.0
17 1853.5
18 1853.5
19 1676.0
20 1675.5
21 1672.5
22 1669.5
23 1452.0
24 1446.5
25 1443.5
26 1443.0
27 1350.0
28 1346.5
29 1339.5
30 1334.0
31 1332.0
32 1109.0
33 1101.0
34 1097.5
35 1090.5
36 1087.0
37 1037.0
38 1036.0
39 1034.0
40 1032.5
41 1029.0
42 726.0
46 705.0
47 702.5
48 701.5
并准备了相机校准的数据:
data = df_p.to_numpy()
pts3d = data[:, 0:3]
pts2d = data[:, 3:5]
pts3d = pts3d.reshape(1,-1, 3)
pts2d = pts2d.reshape(1,-1, 2)
image_height = 3456
image_width = 4608
w = image_width
h = image_height
pts3d = pts3d.astype('float32')
pts2d = pts2d.astype('float32')
size = (w,h)
最后:
image_height = 3456
image_width = 4608
tvec = np.array([0, 0, 0], dtype=np.float32) #Camera is static
rvec = np.array([0, 0, 0], dtype=np.float32) #Camera is static
distCoeffs =np.array([0,0,0,0,0], dtype=np.float32)
cv.calibrateCamera([pts3d], [pts2d],size,camera_matrix,None,None,None,None,flags=cv.CALIB_FIX_K1+cv.CALIB_FIX_K2+cv.CALIB_FIX_K3+cv.CALIB_FIX_K4+cv.CALIB_FIX_K5)
但是这个returns:
---------------------------------------------------------------------------
error Traceback (most recent call last)
<ipython-input-374-406d179adbf6> in <module>
17 distCoeffs =np.array([0, 0, 0,0,0], dtype=np.float32)
18
---> 19 cv.calibrateCamera([pts3d], [pts2d],size,camera_matrix,None,None,None,None,flags=cv.CALIB_FIX_K1+cv.CALIB_FIX_K2+cv.CALIB_FIX_K3+cv.CALIB_FIX_K4+cv.CALIB_FIX_K5)
error: OpenCV(4.5.3) :-1: error: (-5:Bad argument) in function 'calibrateCamera'
> Overload resolution failed:
> - argument for calibrateCamera() given by name ('flags') and position (8)
> - argument for calibrateCamera() given by name ('flags') and position (8)
甚至这个:
cv.calibrateCamera([pts3d], [pts2d],size,camera_matrix,distCoeffs,None,None,None,flags=cv.CALIB_FIX_K1+cv.CALIB_FIX_K2+cv.CALIB_FIX_K3+cv.CALIB_FIX_K4+cv.CALIB_FIX_K5)
returns同样的错误。
我不知道我做错了什么。
我想要什么?我希望能够获得相机的失真系数。这种方式或任何其他给我满意结果的方式。
我的猜测是它与以下中使用的标志有关:
cv.calibrateCamera([pts3d], [pts2d],size,camera_matrix,distCoeffs,None,None,None,flags=cv.CALIB_FIX_K1+cv.CALIB_FIX_K2+cv.CALIB_FIX_K3+cv.CALIB_FIX_K4+cv.CALIB_FIX_K5)
如果将其更改为:
cv.calibrateCamera([pts3d], [pts2d],size,camera_matrix,distCoeffs,None,None,None,flags=cv.CALIB_USE_INTRINSIC_GUESS)
或者只是将标志保留为标准方式并且它不再产生该错误,因为 camera_matrix
和使用的标志之间存在不匹配。
也许您还需要添加 cv.CALIB_FIX_K6
?
我正在尝试使用来自图像(像素位置)和现实世界位置的已知数据来校准相机。
这是我所知道的:
相机
focal_length = 3.9
image_height = 3456
image_width = 4608
esl_height = 35
sensor_height = 4.69
sensor_width = 6.26
pixel_size = 1.34/1000
FOV_x = 71.9
FOV_y = 56.7
F_x = image_width /(2 * tan(FOV_x* pi / 360))
F_y = image_height /(2 * tan(FOV_y* pi / 360))
C_x = image_width / 2
C_y = image_height / 2
row1 = [F_x,0,C_x]
row2 = [0,F_y, C_y]
row3 = [0,0,1]
camera_matrix = np.matrix([row1,row2,row3])
给出:
matrix([[3.17701054e+03, 0.00000000e+00, 2.30400000e+03],
[0.00000000e+00, 3.20254589e+03, 1.72800000e+03],
[0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])
数据
我有一个包含 49 个点的数据集,我有两个真实世界的 (x,y) 位置(我也有 z 值,但我真的只对 (x,y) 位置感兴趣。另外,我有图像中所有这些点的像素位置(它们是我执行的对象检测中的边界框中心。
id manual.location.x manual.location.y manual.location.z \
0 0 32.9878 41.9033 0.215
1 1 32.9878 44.4404 0.215
2 2 32.9878 44.4404 0.215
3 3 32.9878 44.4404 0.565
4 4 32.9878 44.4404 0.565
5 5 32.9878 44.4404 0.565
6 6 32.9878 44.4404 0.565
7 7 32.9878 44.4404 0.565
8 8 32.9878 41.9033 0.753
9 9 32.9878 44.4404 0.779
10 10 32.9878 44.4404 0.779
11 11 32.9878 44.4404 0.779
12 12 32.9878 41.9033 1.024
13 13 32.9878 44.4404 1.024
14 14 32.9878 42.7490 1.100
15 15 32.9878 43.5947 1.100
16 16 32.9878 43.5947 1.100
17 17 32.9878 43.5947 1.100
18 18 32.9878 43.5947 1.100
19 19 32.9878 44.4404 1.231
20 20 32.9878 44.4404 1.231
21 21 32.9878 44.4404 1.231
22 22 32.9878 44.4404 1.231
23 23 32.9878 42.7490 1.320
24 24 32.9878 43.5947 1.412
25 25 32.9878 42.7490 1.412
26 26 32.9878 43.5947 1.412
27 27 32.9878 44.4404 1.412
28 28 32.9878 44.4404 1.458
29 29 32.9878 44.4404 1.458
30 30 32.9878 44.4404 1.458
31 31 32.9878 44.4404 1.458
32 32 32.9878 42.7490 1.620
33 33 32.9878 42.7490 1.620
34 34 32.9878 43.5947 1.620
35 35 32.9878 43.5947 1.620
36 36 32.9878 42.7490 1.620
37 37 32.9878 44.4404 1.651
38 38 32.9878 44.4404 1.651
39 39 32.9878 44.4404 1.651
40 40 32.9878 44.4404 1.651
41 41 32.9878 44.4404 1.651
42 42 32.9878 42.7490 1.850
43 43 32.9878 42.7490 NaN
44 44 32.9878 44.4404 NaN
45 45 32.9878 44.4404 NaN
46 46 32.9878 44.4404 1.850
47 47 32.9878 43.5947 1.850
48 48 32.9878 44.4404 1.850
bbox_center_x bbox_center_y
0 4269.5 2914.0
1 1035.0 2883.5
2 843.5 2880.0
3 1516.5 2529.0
4 1247.5 2527.0
5 1730.0 2525.5
6 987.0 2522.0
7 765.5 2520.0
8 4435.0 2356.5
9 1196.0 2257.0
10 938.5 2255.0
11 704.5 2250.0
12 4547.0 1998.0
13 1291.0 1980.0
14 3681.0 1864.5
15 2394.0 1856.0
16 1931.5 1854.0
17 2043.0 1853.5
18 2043.0 1853.5
19 1620.0 1676.0
20 1267.0 1675.5
21 847.0 1672.5
22 593.5 1669.5
23 3783.5 1452.0
24 1931.5 1446.5
25 3346.5 1443.5
26 2878.0 1443.0
27 1632.0 1350.0
28 1409.0 1346.5
29 945.0 1339.5
30 727.0 1334.0
31 534.5 1332.0
32 4349.0 1109.0
33 3859.0 1101.0
34 1920.5 1097.5
35 2878.0 1090.5
36 3364.0 1087.0
37 1460.5 1037.0
38 1290.5 1036.0
39 1065.5 1034.0
40 748.0 1032.5
41 473.0 1029.0
42 4262.0 726.0
43 3683.5 713.0
44 1375.0 710.0
45 1094.5 708.0
46 850.0 705.0
47 3103.5 702.5
48 375.5 701.5
为了方便起见,我愿意让现实世界位置的z坐标(manual.location.z
)为0。
现在,我在 z 坐标 = 0 的数据上使用 cv.calibrateCamera
尝试了以下操作。因此,我执行了以下操作:
manual.location.x manual.location.y manual.location.z bbox_center_x \
0 32.9878 41.9033 0 4269.5
1 32.9878 44.4404 0 1035.0
2 32.9878 44.4404 0 843.5
3 32.9878 44.4404 0 1516.5
4 32.9878 44.4404 0 1247.5
5 32.9878 44.4404 0 1730.0
6 32.9878 44.4404 0 987.0
7 32.9878 44.4404 0 765.5
8 32.9878 41.9033 0 4435.0
9 32.9878 44.4404 0 1196.0
10 32.9878 44.4404 0 938.5
11 32.9878 44.4404 0 704.5
12 32.9878 41.9033 0 4547.0
13 32.9878 44.4404 0 1291.0
14 32.9878 42.7490 0 3681.0
15 32.9878 43.5947 0 2394.0
16 32.9878 43.5947 0 1931.5
17 32.9878 43.5947 0 2043.0
18 32.9878 43.5947 0 2043.0
19 32.9878 44.4404 0 1620.0
20 32.9878 44.4404 0 1267.0
21 32.9878 44.4404 0 847.0
22 32.9878 44.4404 0 593.5
23 32.9878 42.7490 0 3783.5
24 32.9878 43.5947 0 1931.5
25 32.9878 42.7490 0 3346.5
26 32.9878 43.5947 0 2878.0
27 32.9878 44.4404 0 1632.0
28 32.9878 44.4404 0 1409.0
29 32.9878 44.4404 0 945.0
30 32.9878 44.4404 0 727.0
31 32.9878 44.4404 0 534.5
32 32.9878 42.7490 0 4349.0
33 32.9878 42.7490 0 3859.0
34 32.9878 43.5947 0 1920.5
35 32.9878 43.5947 0 2878.0
36 32.9878 42.7490 0 3364.0
37 32.9878 44.4404 0 1460.5
38 32.9878 44.4404 0 1290.5
39 32.9878 44.4404 0 1065.5
40 32.9878 44.4404 0 748.0
41 32.9878 44.4404 0 473.0
42 32.9878 42.7490 0 4262.0
46 32.9878 44.4404 0 850.0
47 32.9878 43.5947 0 3103.5
48 32.9878 44.4404 0 375.5
bbox_center_y
0 2914.0
1 2883.5
2 2880.0
3 2529.0
4 2527.0
5 2525.5
6 2522.0
7 2520.0
8 2356.5
9 2257.0
10 2255.0
11 2250.0
12 1998.0
13 1980.0
14 1864.5
15 1856.0
16 1854.0
17 1853.5
18 1853.5
19 1676.0
20 1675.5
21 1672.5
22 1669.5
23 1452.0
24 1446.5
25 1443.5
26 1443.0
27 1350.0
28 1346.5
29 1339.5
30 1334.0
31 1332.0
32 1109.0
33 1101.0
34 1097.5
35 1090.5
36 1087.0
37 1037.0
38 1036.0
39 1034.0
40 1032.5
41 1029.0
42 726.0
46 705.0
47 702.5
48 701.5
并准备了相机校准的数据:
data = df_p.to_numpy()
pts3d = data[:, 0:3]
pts2d = data[:, 3:5]
pts3d = pts3d.reshape(1,-1, 3)
pts2d = pts2d.reshape(1,-1, 2)
image_height = 3456
image_width = 4608
w = image_width
h = image_height
pts3d = pts3d.astype('float32')
pts2d = pts2d.astype('float32')
size = (w,h)
最后:
image_height = 3456
image_width = 4608
tvec = np.array([0, 0, 0], dtype=np.float32) #Camera is static
rvec = np.array([0, 0, 0], dtype=np.float32) #Camera is static
distCoeffs =np.array([0,0,0,0,0], dtype=np.float32)
cv.calibrateCamera([pts3d], [pts2d],size,camera_matrix,None,None,None,None,flags=cv.CALIB_FIX_K1+cv.CALIB_FIX_K2+cv.CALIB_FIX_K3+cv.CALIB_FIX_K4+cv.CALIB_FIX_K5)
但是这个returns:
---------------------------------------------------------------------------
error Traceback (most recent call last)
<ipython-input-374-406d179adbf6> in <module>
17 distCoeffs =np.array([0, 0, 0,0,0], dtype=np.float32)
18
---> 19 cv.calibrateCamera([pts3d], [pts2d],size,camera_matrix,None,None,None,None,flags=cv.CALIB_FIX_K1+cv.CALIB_FIX_K2+cv.CALIB_FIX_K3+cv.CALIB_FIX_K4+cv.CALIB_FIX_K5)
error: OpenCV(4.5.3) :-1: error: (-5:Bad argument) in function 'calibrateCamera'
> Overload resolution failed:
> - argument for calibrateCamera() given by name ('flags') and position (8)
> - argument for calibrateCamera() given by name ('flags') and position (8)
甚至这个:
cv.calibrateCamera([pts3d], [pts2d],size,camera_matrix,distCoeffs,None,None,None,flags=cv.CALIB_FIX_K1+cv.CALIB_FIX_K2+cv.CALIB_FIX_K3+cv.CALIB_FIX_K4+cv.CALIB_FIX_K5)
returns同样的错误。
我不知道我做错了什么。
我想要什么?我希望能够获得相机的失真系数。这种方式或任何其他给我满意结果的方式。
我的猜测是它与以下中使用的标志有关:
cv.calibrateCamera([pts3d], [pts2d],size,camera_matrix,distCoeffs,None,None,None,flags=cv.CALIB_FIX_K1+cv.CALIB_FIX_K2+cv.CALIB_FIX_K3+cv.CALIB_FIX_K4+cv.CALIB_FIX_K5)
如果将其更改为:
cv.calibrateCamera([pts3d], [pts2d],size,camera_matrix,distCoeffs,None,None,None,flags=cv.CALIB_USE_INTRINSIC_GUESS)
或者只是将标志保留为标准方式并且它不再产生该错误,因为 camera_matrix
和使用的标志之间存在不匹配。
也许您还需要添加 cv.CALIB_FIX_K6
?