需要帮助理解 cv2.undistortPoints() 的错误
Need help in understanding error for cv2.undistortPoints()
我正在尝试使用 OpenCV 中的结构光对来自投影仪和相机的点进行三角测量 Python。在这个过程中,我有一个在相机和投影仪之间一对一匹配的元组列表。我将其传递给 cv2.undistortedPoints(),如下所示:
camera_normalizedPoints = cv2.undistortPoints(camera_points, camera_K, camera_d)
但是,python 抛出以下错误,我无法理解该错误的含义。
camera_normalizedPoints = cv2.undistortPoints(camera_points, camera_K, camera_d)
cv2.error: /home/base/opencv_build/opencv/modules/imgproc/src/undistort.cpp:312: error: (-215) CV_IS_MAT(_src) && CV_IS_MAT(_dst) && (_src->rows == 1 || _src->cols == 1) && (_dst->rows == 1 || _dst->cols == 1) && _src->cols + _src->rows - 1 == _dst->rows + _dst->cols - 1 && (CV_MAT_TYPE(_src->type) == CV_32FC2 || CV_MAT_TYPE(_src->type) == CV_64FC2) && (CV_MAT_TYPE(_dst->type) == CV_32FC2 || CV_MAT_TYPE(_dst->type) == CV_64FC2) in function cvUndistortPoints
非常感谢任何帮助。
谢谢。
不幸的是,Python 的文档并不总是明确说明输入形状,undistortPoints()
甚至还没有 Python 文档。
输入点必须是形状为 (n_points, 1, n_dimensions)
的数组。所以如果你有二维坐标,它们的形状应该是 (n_points, 1, 2)
。或者对于 3D 坐标,它们的形状应该是 (n_points, 1, 3)
。 大多数 OpenCV 函数都是如此。据我所知,这种格式适用于所有 OpenCV 函数,而少数几个 OpenCV 函数也将接受形状为 (n_points, n_dimensions)
的点。我发现最好保持所有内容的一致性并采用 (n_points, 1, n_dimensions)
.
格式
要清楚,这意味着四个 32 位浮点 2D 点的数组看起来像:
points = np.array([[[x1, y1]], [[x2, y2]], [[x3, y3]], [[x4, y4]]], dtype=np.float32)
如果您有一个形状为 (n_points, n_dimensions)
的数组,您可以使用 np.newaxis
:
展开它
>>> points = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
>>> points.shape
(4, 2)
>>> points = points[:, np.newaxis, :]
>>> points.shape
(4, 1, 2)
或 np.expand_dims()
:
>>> points = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
>>> points.shape
(4, 2)
>>> points = np.expand_dims(points, 1)
>>> points.shape
(4, 1, 2)
或 np.transpose()
的各种排序,具体取决于您的尺寸顺序。例如如果你的形状是 (1, n_points, n_dimensions)
那么你想交换轴 0 和轴 1 以获得 (n_points, 1, n_dimensions)
,所以 points = np.transpose(points, (1, 0, 2))
会改变轴首先放置轴 1,然后是轴 0,然后是轴 2 , 所以新形状是正确的。
如果您认为这是一种奇怪的点格式,那是因为您只考虑点列表,但如果您将点视为图像的坐标,则这是合理的。如果你有一个图像,那么图像中每个点的坐标由一对 (x, y)
定义,如:
(0, 0) (1, 0) (2, 0) ...
(0, 1) (1, 1) (2, 1) ...
(0, 2) (1, 2) (2, 2) ...
...
在这里,将每个坐标放入双通道数组的单独通道中是有意义的,这样您就可以得到一个二维 x 坐标数组和一个二维 y 坐标数组,例如:
通道 0(x 坐标):
0 1 2 ...
0 1 2 ...
0 1 2 ...
...
通道 1(y 坐标):
0 0 0 ...
1 1 1 ...
2 2 2 ...
...
所以这就是将每个坐标放在单独通道上的原因。
其他一些需要这种格式的 OpenCV 函数包括 cv2.transform()
和 cv2.perspectiveTransform()
,我之前已经回答过相同的问题,分别是 and 。
我也遇到了这个问题,研究了一段时间终于明白了。
open系统中,distort操作在camera matrix之前,所以处理顺序为:
image_distorted ->camera_matrix -> 去扭曲功能 ->camera_matrix -> 回到 image_undistorted。
因此您需要对 camera_K 进行小的修复。
camera_normalizedPoints = cv2.undistortPoints(camera_points, camera_K, camera_d, cv2.Mat.sye(3,3), camera_K)
论坛:https://i.stack.imgur.com/nmR5P.jpg
我正在尝试使用 OpenCV 中的结构光对来自投影仪和相机的点进行三角测量 Python。在这个过程中,我有一个在相机和投影仪之间一对一匹配的元组列表。我将其传递给 cv2.undistortedPoints(),如下所示:
camera_normalizedPoints = cv2.undistortPoints(camera_points, camera_K, camera_d)
但是,python 抛出以下错误,我无法理解该错误的含义。
camera_normalizedPoints = cv2.undistortPoints(camera_points, camera_K, camera_d)
cv2.error: /home/base/opencv_build/opencv/modules/imgproc/src/undistort.cpp:312: error: (-215) CV_IS_MAT(_src) && CV_IS_MAT(_dst) && (_src->rows == 1 || _src->cols == 1) && (_dst->rows == 1 || _dst->cols == 1) && _src->cols + _src->rows - 1 == _dst->rows + _dst->cols - 1 && (CV_MAT_TYPE(_src->type) == CV_32FC2 || CV_MAT_TYPE(_src->type) == CV_64FC2) && (CV_MAT_TYPE(_dst->type) == CV_32FC2 || CV_MAT_TYPE(_dst->type) == CV_64FC2) in function cvUndistortPoints
非常感谢任何帮助。
谢谢。
不幸的是,Python 的文档并不总是明确说明输入形状,undistortPoints()
甚至还没有 Python 文档。
输入点必须是形状为 (n_points, 1, n_dimensions)
的数组。所以如果你有二维坐标,它们的形状应该是 (n_points, 1, 2)
。或者对于 3D 坐标,它们的形状应该是 (n_points, 1, 3)
。 大多数 OpenCV 函数都是如此。据我所知,这种格式适用于所有 OpenCV 函数,而少数几个 OpenCV 函数也将接受形状为 (n_points, n_dimensions)
的点。我发现最好保持所有内容的一致性并采用 (n_points, 1, n_dimensions)
.
要清楚,这意味着四个 32 位浮点 2D 点的数组看起来像:
points = np.array([[[x1, y1]], [[x2, y2]], [[x3, y3]], [[x4, y4]]], dtype=np.float32)
如果您有一个形状为 (n_points, n_dimensions)
的数组,您可以使用 np.newaxis
:
>>> points = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
>>> points.shape
(4, 2)
>>> points = points[:, np.newaxis, :]
>>> points.shape
(4, 1, 2)
或 np.expand_dims()
:
>>> points = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
>>> points.shape
(4, 2)
>>> points = np.expand_dims(points, 1)
>>> points.shape
(4, 1, 2)
或 np.transpose()
的各种排序,具体取决于您的尺寸顺序。例如如果你的形状是 (1, n_points, n_dimensions)
那么你想交换轴 0 和轴 1 以获得 (n_points, 1, n_dimensions)
,所以 points = np.transpose(points, (1, 0, 2))
会改变轴首先放置轴 1,然后是轴 0,然后是轴 2 , 所以新形状是正确的。
如果您认为这是一种奇怪的点格式,那是因为您只考虑点列表,但如果您将点视为图像的坐标,则这是合理的。如果你有一个图像,那么图像中每个点的坐标由一对 (x, y)
定义,如:
(0, 0) (1, 0) (2, 0) ...
(0, 1) (1, 1) (2, 1) ...
(0, 2) (1, 2) (2, 2) ...
...
在这里,将每个坐标放入双通道数组的单独通道中是有意义的,这样您就可以得到一个二维 x 坐标数组和一个二维 y 坐标数组,例如:
通道 0(x 坐标):
0 1 2 ...
0 1 2 ...
0 1 2 ...
...
通道 1(y 坐标):
0 0 0 ...
1 1 1 ...
2 2 2 ...
...
所以这就是将每个坐标放在单独通道上的原因。
其他一些需要这种格式的 OpenCV 函数包括 cv2.transform()
和 cv2.perspectiveTransform()
,我之前已经回答过相同的问题,分别是
我也遇到了这个问题,研究了一段时间终于明白了。
open系统中,distort操作在camera matrix之前,所以处理顺序为: image_distorted ->camera_matrix -> 去扭曲功能 ->camera_matrix -> 回到 image_undistorted。
因此您需要对 camera_K 进行小的修复。
camera_normalizedPoints = cv2.undistortPoints(camera_points, camera_K, camera_d, cv2.Mat.sye(3,3), camera_K)
论坛:https://i.stack.imgur.com/nmR5P.jpg