我试图用以下参数调用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
发布于 2017-10-03 07:04:39
文档对于这个函数是错误的,因为它是用Python实现的。solvePnP()和solvePnPRansac()的文档都是这样的:
参数: objectPoints -对象坐标空间中的目标点数组,3XN/Nx3-1通道或1xN/NX1-3通道,其中N是点的数目。
vector<Point3f>也可以在这里传递。 imagePoints -数组对应的图像点,2XN/Nx2-1-通道或1xN/NX1-2-通道,其中N是点的数目。vector<Point2f>也可以在这里传递。
因此,假设您很好地使用(N,3)和(N,2)数组作为输入。但是,错误代码却不这么说。让我们把它分解:
CV_IS_MAT(_src) & CV_IS_MAT(_dst)和&(_src->_dst->_dst-)和(_dst->rows == 1 CV_ _dst->cols == 1->cols+ _src->rows 1 == _dst->row+ _dst->cols _dst->cols(_src-> CV_MAT_TYPE(_src->type) == CV_32FC2 CV_MAT_TYPE(_src->type) == CV_CV_MAT_TYPE(_src->type)。64FC2) && (CV_MAT_TYPE(_dst->type) == CV_32FC2连CV_MAT_TYPE(_dst->type) == CV_64FC2)
好的,它们是numpy数组,所以我们可能可以丢弃前两个数组。但是在接下来的检查中,我们看到了一些有趣的东西:
(_src->行== 1 x _src->cols == 1) &(_dst-> == 1 == _dst->cols == 1)
它正在检查src和dst中是否只有一行或一列。换句话说,它在docs中声明的第二个版本中严格地期望您的点;它需要一个多通道点数组。这意味着第一个坐标位于矩阵的一个通道上,第二个坐标位于下一个通道上,等等。
因此,如果我们简单地将你的点重塑成一个多通道数组:
>>> 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它起作用了!
未来的支持提示:在OpenCV允许(npoints, ncoords)格式的点数的每一个函数中,它也接受(npoints, 1, ncoords)格式的AFAIK。然而,有些功能只适用于后一种格式。因此,如果在OpenCV和Python中使用点坐标,最好假设点应该位于多通道数组中,其中通道数是坐标轴的数量。
https://stackoverflow.com/questions/46534126
复制相似问题