13

我在格式化 x,y 点列表以传递给 undistortPoints (opencv 2.4.1) 时遇到问题。

错误消息是 c++ 特定的,并抱怨点数组不是 CV_32FC2 类型。我不应该能够传入 Nx2 numpy 数组吗?

import cv2

camera_matrix = array(mat('1.3e+03, 0., 6.0e+02; 0., 1.3e+03, 4.8e+02; 0., 0., 1.'), dtype=float32)
dist_coeffs = array(mat('-2.4-01, 9.5e-02, -4.0e-04, 8.9e-05, 0.'), dtype=float32)

test = zeros((10,2), dtype=float32)

print test.shape, type(test)

xy_undistorted = cv2.undistortPoints(test, camera_matrix, dist_coeffs)

结果是:

opencv/modules/imgproc/src/undistort.cpp:279: 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

在 samples/python2/video.py 中使用了 projectPoints ,它接受一个数组并对其进行整形(-1,3),从而为该函数生成一个 Nx3 数组,似乎相同的格式应该在这里工作。

4

2 回答 2

13

我对相机校准了解不多。但是看到您的代码和错误,我将其更改如下:

import cv2
import numpy as np
camera_matrix = np.array([[1.3e+03, 0., 6.0e+02], [0., 1.3e+03, 4.8e+02], [0., 0., 1.]], dtype=np.float32)
dist_coeffs = np.array([-2.4-01, 9.5e-02, -4.0e-04, 8.9e-05, 0.], dtype=np.float32)

test = np.zeros((10,1,2), dtype=np.float32)
xy_undistorted = cv2.undistortPoints(test, camera_matrix, dist_coeffs)

print xy_undistorted

下面是我得到的结果,检查是否正确:

[[[ 0.0187303   0.01477836]]

 [[ 0.0187303   0.01477836]]

 [[ 0.0187303   0.01477836]]

 [[ 0.0187303   0.01477836]]

 [[ 0.0187303   0.01477836]]

 [[ 0.0187303   0.01477836]]

 [[ 0.0187303   0.01477836]]

 [[ 0.0187303   0.01477836]]

 [[ 0.0187303   0.01477836]]

 [[ 0.0187303   0.01477836]]]

问题是什么 :

错误说,来源应该有EITHER one row OR one column. 应该是CV_32FC2或CV_64FC2,表示两个通道和浮点。所以让你的形状 src (10,1,2) or (1,10,2)。两种方法都有效并给出相同的结果(我自己检查过)。唯一的问题是,我不知道它是否正确,所以你自己检查一下。

于 2012-06-13T17:56:03.567 回答
2

我已经测试了 Abid Rahman 的方法并且效果很好,但是有一些问题需要注意。

calib = np.reshape(calib, [3, 3])
dist = np.array(kp_mat, dtype=np.float32)
newcameramtx, _ = cv2.getOptimalNewCameraMatrix(calib, dist, (w, h), 1, (w, h))
# undistort
dst = cv2.undistortPoints(pt, calib, dist, None, newcameramtx)
dst = np.squeeze(dst)

笔记

  1. 点的形状应为 [1,N,2] 或 [N,1,2],坐标为 [x,y]
  2. 应指定新的相机矩阵。或者输出将是标准化坐标。
于 2018-09-26T05:51:16.597 回答