python - 需要帮助理解 cv2.undistortPoints() 的错误

标签 python opencv computer-vision triangulation

我正在尝试使用 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: 错误: (-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) 在函数 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)    ...
...

在这里,将每个坐标放入双 channel 数组的单独 channel 中是有意义的,这样您就可以获得一个二维 x 坐标数组和一个二维 y 坐标数组,例如:

channel 0(x 坐标):

0    1    2    ...
0    1    2    ...
0    1    2    ...
...

channel 1(y 坐标):

0    0    0    ...
1    1    1    ...
2    2    2    ...
...

这就是将每个坐标放在单独 channel 上的原因。


其他一些需要这种格式的 OpenCV 函数包括 cv2.transform()cv2.perspectiveTransform(),我之前回答过相同的问题,here 和分别为 here

关于python - 需要帮助理解 cv2.undistortPoints() 的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47402445/

相关文章:

matlab - 从特征向量分类

python - 向模型发出请求的正确方法(通过 Azure ML Designer 部署)

python - 当我尝试使用 pika (python) 向 RabbitMQ 确认消息时发生错误 "unknown delivery tag"

python - 生成一维高斯核的最简单方法

python - IO.UnsupportedOperation : Not Writable

android - 用opencv处理Android图像

c++ - 如何在纹理映射过程后合并两个 .obj 文件?

python - Pandas:编辑数据框的一部分,使其影响主数据框

python - 如何找到钻头等金属零件的确切边缘/二进制阈值?

opencv - 配置OpenCV时CMake报错