solvePnP 的输出与 projectPoints 不匹配
output from solvePnP doesn't match projectPoints
我从 solvePnP 得到了奇怪的数据,所以我尝试用 projectPoints 检查它:
retval, rvec, tvec=cv2.solvePnP(opts, ipts, mtx, dist, flags=cv2.SOLVEPNP_ITERATIVE)
print(retval,rvec,tvec)
proj, jac = cv2.projectPoints(opts, rvec, tvec, mtx, dist)
print(proj,ipts)
这里的 opts 是 z=0 的 3d 点,在这张图片上检测到:
ipts取自这张图(这里只取部分图):
我自己检查了点(使用 SIFT 检测,点被正确检测并以正确的方式配对)。
现在我想测试 SolvePnP 发现的 rvec 和 tvec 是否正确,所以我调用 cv2.projectPoint 来测试 3d 点是否投影到图像点。这是我所拥有的:
所以我看到投影点位于图像之外,y<0。
(从 solvePnP 返回为真)
这是失真矩阵 dist:
1.6324642475694839e+02 -2.1480843988631259e+04 -3.4969507980045117e-01 7.9693609309756430e-01 -4.0684056606034986e+01
这是 mtx:
6.4154558230601404e+04 0. 1.2973531562160772e+03
0. 9.8908265814965678e+04 9.5760834379036123e+02
0. 0. 1.
这是选项:
[[ 1708.74987793 1138.92041016 0. ]
[ 1708.74987793 1138.92041016 0. ]
[ 1708.74987793 1138.92041016 0. ]
[ 1708.74987793 1138.92041016 0. ]
[ 1708.74987793 1138.92041016 0. ]
[ 1708.74987793 1138.92041016 0. ]
[ 1708.74987793 1138.92041016 0. ]
[ 1984.09973145 1069.31677246 0. ]
[ 1984.09973145 1069.31677246 0. ]
[ 1908.19396973 1200.05529785 0. ]
[ 1994.56677246 1286.16516113 0. ]
[ 1994.56677246 1286.16516113 0. ]
[ 1806.82177734 1058.06872559 0. ]
[ 1925.55639648 1077.33703613 0. ]
[ 1998.30627441 1115.51647949 0. ]
[ 1998.30627441 1115.51647949 0. ]
[ 1998.30627441 1115.51647949 0. ]
[ 2013.79003906 1168.08728027 0. ]
[ 1972.93457031 1234.92614746 0. ]
[ 2029.11364746 1220.234375 0. ]]
这是 ipts:
[[ 71.6125946 11.61344719]
[ 116.60684967 71.6068573 ]
[ 116.60684967 71.6068573 ]
[ 101.60684967 86.60684967]
[ 101.60684967 86.60684967]
[ 116.60684967 101.6068573 ]
[ 116.60684967 101.6068573 ]
[ 112.37421417 53.40462112]
[ 112.37421417 53.40462112]
[ 83.76233673 84.36077118]
[ 98.45358276 112.38414764]
[ 98.45358276 112.38414764]
[ 67.2594223 38.04878998]
[ 96.85155487 51.85028076]
[ 112.26165009 67.25630188]
[ 112.26165009 67.25630188]
[ 112.26165009 67.25630188]
[ 112.24694061 82.24401855]
[ 96.82528687 97.66513824]
[ 112.2511673 97.25905609]]
rvec = [[-0.21890167] [-0.86241377] [ 0.96051463]]
tvec = [[ 239.04461181] [-2165.99539286] [-1700.61539107]]
我还尝试按照其中一条评论将 opts 中的每个 y 乘以 -1,但这给了我更疯狂的图片外坐标,例如 10^13。
相机矩阵 (mts) 不正确。 Fx和Fy相差很大(Fx=6.4154558230601404e+04 Fy=9.8908265814965678e+04)而且很大。根据 OpenCV calibrateCamera() 函数中的评论,通常会出现此问题,因为您可能在 findChessboardCorners.
中使用了 patternSize=cvSize(rows,cols) 而不是使用 patternSize=cvSize(cols,rows)
我从 solvePnP 得到了奇怪的数据,所以我尝试用 projectPoints 检查它:
retval, rvec, tvec=cv2.solvePnP(opts, ipts, mtx, dist, flags=cv2.SOLVEPNP_ITERATIVE)
print(retval,rvec,tvec)
proj, jac = cv2.projectPoints(opts, rvec, tvec, mtx, dist)
print(proj,ipts)
这里的 opts 是 z=0 的 3d 点,在这张图片上检测到:
ipts取自这张图(这里只取部分图):
我自己检查了点(使用 SIFT 检测,点被正确检测并以正确的方式配对)。
现在我想测试 SolvePnP 发现的 rvec 和 tvec 是否正确,所以我调用 cv2.projectPoint 来测试 3d 点是否投影到图像点。这是我所拥有的:
所以我看到投影点位于图像之外,y<0。
(从 solvePnP 返回为真)
这是失真矩阵 dist:
1.6324642475694839e+02 -2.1480843988631259e+04 -3.4969507980045117e-01 7.9693609309756430e-01 -4.0684056606034986e+01
这是 mtx:
6.4154558230601404e+04 0. 1.2973531562160772e+03
0. 9.8908265814965678e+04 9.5760834379036123e+02
0. 0. 1.
这是选项:
[[ 1708.74987793 1138.92041016 0. ]
[ 1708.74987793 1138.92041016 0. ]
[ 1708.74987793 1138.92041016 0. ]
[ 1708.74987793 1138.92041016 0. ]
[ 1708.74987793 1138.92041016 0. ]
[ 1708.74987793 1138.92041016 0. ]
[ 1708.74987793 1138.92041016 0. ]
[ 1984.09973145 1069.31677246 0. ]
[ 1984.09973145 1069.31677246 0. ]
[ 1908.19396973 1200.05529785 0. ]
[ 1994.56677246 1286.16516113 0. ]
[ 1994.56677246 1286.16516113 0. ]
[ 1806.82177734 1058.06872559 0. ]
[ 1925.55639648 1077.33703613 0. ]
[ 1998.30627441 1115.51647949 0. ]
[ 1998.30627441 1115.51647949 0. ]
[ 1998.30627441 1115.51647949 0. ]
[ 2013.79003906 1168.08728027 0. ]
[ 1972.93457031 1234.92614746 0. ]
[ 2029.11364746 1220.234375 0. ]]
这是 ipts:
[[ 71.6125946 11.61344719]
[ 116.60684967 71.6068573 ]
[ 116.60684967 71.6068573 ]
[ 101.60684967 86.60684967]
[ 101.60684967 86.60684967]
[ 116.60684967 101.6068573 ]
[ 116.60684967 101.6068573 ]
[ 112.37421417 53.40462112]
[ 112.37421417 53.40462112]
[ 83.76233673 84.36077118]
[ 98.45358276 112.38414764]
[ 98.45358276 112.38414764]
[ 67.2594223 38.04878998]
[ 96.85155487 51.85028076]
[ 112.26165009 67.25630188]
[ 112.26165009 67.25630188]
[ 112.26165009 67.25630188]
[ 112.24694061 82.24401855]
[ 96.82528687 97.66513824]
[ 112.2511673 97.25905609]]
rvec = [[-0.21890167] [-0.86241377] [ 0.96051463]]
tvec = [[ 239.04461181] [-2165.99539286] [-1700.61539107]]
我还尝试按照其中一条评论将 opts 中的每个 y 乘以 -1,但这给了我更疯狂的图片外坐标,例如 10^13。
相机矩阵 (mts) 不正确。 Fx和Fy相差很大(Fx=6.4154558230601404e+04 Fy=9.8908265814965678e+04)而且很大。根据 OpenCV calibrateCamera() 函数中的评论,通常会出现此问题,因为您可能在 findChessboardCorners.
中使用了 patternSize=cvSize(rows,cols) 而不是使用 patternSize=cvSize(cols,rows)