- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用以下参数调用 solvePnP。
apriltag_object_points = np.array([(-1, -1, 0), (-1, 1, 0), (1, 1, 0), (1, -1, 0)], dtype=np.float)
camera_matrix_left = np.eye(3)
dist_left = np.zeros((5, 1))
image_points = np.array(detection.position, dtype=np.float)
cv2.solvePnPRansac(apriltag_object_points, image_points, camera_matrix_left, dist_left)
但是,我收到以下错误:
OpenCV Error: Assertion failed (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 cvUndistortPoints, file /Users/travis/miniconda3/conda-bld/opencv_1506476120161/work/opencv-3.3.0/modules/imgproc/src/undistort.cpp, line 312
Traceback (most recent call last):
File "/Users/me/Documents/Code/project/file.py", line 139, in <module>
ret = cv2.solvePnPRansac(apriltag_object_points, image_points, camera_matrix_left, dist_left)
cv2.error: /Users/travis/miniconda3/conda-bld/opencv_1506476120161/work/opencv-3.3.0/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
看起来我的论证形式有问题,但他们似乎没问题......
apriltag_object_points.shape == (4, 3)
image_points.shape == (4, 2)
图像点必须是同质的吗?我是否只需要 hstack
1
到 image_points
的列向量?
最佳答案
该函数的文档错误是用 Python 实现的。 solvePnP()
的文档和 solvePnPRansac()
两种状态:
Parameters:
objectPoints – Array of object points in the object coordinate space, 3xN/Nx3 1-channel or 1xN/Nx1 3-channel, where N is the number of points.
vector<Point3f>
can be also passed here.imagePoints – Array of corresponding image points, 2xN/Nx2 1-channel or 1xN/Nx1 2-channel, where N is the number of points.
vector<Point2f>
can be also passed here.
因此,您假设您可以很好地使用 (N, 3) 和 (N, 2) 数组作为输入。但是,错误代码另有说明。让我们分解一下:
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)
好的,它们是 numpy 数组,所以我们可以丢弃前两个。但是在接下来的检查中,我们看到了一些有趣的东西:
(_src->rows == 1 || _src->cols == 1) && (_dst->rows == 1 || _dst->cols == 1)
它正在检查 src
中是否只有一行或一列和 dst
.换句话说,它在文档中声明的第二个版本中严格期待您的观点;它想要一个多 channel 点阵列。这意味着第一个坐标在矩阵的一个 channel 上,第二个坐标在下一个 channel 上,依此类推。
因此,如果我们只是将您的点 reshape 为多 channel 数组:
>>> apriltag_object_points = apriltag_object_points.reshape(4,1,3)
>>> image_points = image_points.reshape(4,1,2)
>>> it_works, rvec, tvec, inliers = cv2.solvePnPRansac(apriltag_object_points, image_points, camera_matrix_left, dist_left)
>>> it_works
True
有效!
future 的专业提示:OpenCV 的每个函数都允许点在 (npoints, ncoords)
中格式,它也接受 (npoints, 1, ncoords)
中的它们格式 AFAIK。然而,某些函数仅适用于后一种格式。因此,如果您在 Python 的 OpenCV 中使用点坐标,最好假设您的点应该在一个多 channel 数组中,其中 channel 的数量就是坐标轴的数量。
关于python - 解决 PnP object_points/image_points 形状?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46534126/
我正在从事一个 opencv 项目,并遵循不同的来源,包括书籍和一些源代码。我发现书和一些源代码之间存在差异。当使用已知的棋盘校准相机时,我们定义了一个由棋盘角组成的对象点。例如左上角是(0,0),下
我正在尝试使用以下参数调用 solvePnP。 apriltag_object_points = np.array([(-1, -1, 0), (-1, 1, 0), (1, 1, 0), (1, -
我是一名优秀的程序员,十分优秀!