OpenCV Python-使用校准函数时如何格式化numpy数组
我正在尝试使用OpenCV 3.0.0 python绑定(使用非对称圆网格)校准鱼眼相机,但在正确设置对象和图像点阵列的格式方面存在问题。我的当前来源如下所示:OpenCV Python-使用校准函数时如何格式化numpy数组,python,opencv,numpy,opencv3.0,camera-calibration,Python,Opencv,Numpy,Opencv3.0,Camera Calibration,我正在尝试使用OpenCV 3.0.0 python绑定(使用非对称圆网格)校准鱼眼相机,但在正确设置对象和图像点阵列的格式方面存在问题。我的当前来源如下所示: import cv2 import glob import numpy as np def main(): circle_diameter = 4.5 circle_radius = circle_diameter/2.0 pattern_width = 4 pattern_height = 11
import cv2
import glob
import numpy as np
def main():
circle_diameter = 4.5
circle_radius = circle_diameter/2.0
pattern_width = 4
pattern_height = 11
num_points = pattern_width*pattern_height
images = glob.glob('*.bmp')
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
imgpoints = []
objpoints = []
obj = []
for i in range(pattern_height):
for j in range(pattern_width):
obj.append((
float(2*j + i % 2)*circle_radius,
float(i*circle_radius),
0
))
for name in images:
image = cv2.imread(name)
grayimage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
retval, centers = cv2.findCirclesGrid(grayimage, (pattern_width, pattern_height), flags=(cv2.CALIB_CB_ASYMMETRIC_GRID + cv2.CALIB_CB_CLUSTERING))
imgpoints_tmp = np.zeros((num_points, 2))
if retval:
for i in range(num_points):
imgpoints_tmp[i, 0] = centers[i, 0, 0]
imgpoints_tmp[i, 1] = centers[i, 0, 1]
imgpoints.append(imgpoints_tmp)
objpoints.append(obj)
# Convertion to numpy array
imgpoints = np.array(imgpoints, dtype=np.float32)
objpoints = np.array(objpoints, dtype=np.float32)
K, D = cv2.fisheye.calibrate(objpoints, imgpoints, image_size=(1280, 800), K=None, D=None)
if __name__ == '__main__':
main()
错误消息是:
OpenCV Error: Assertion failed (objectPoints.type() == CV_32FC3 || objectPoints.type() == CV_64FC3) in cv::fisheye::calibrate
objpoints
具有形状(31,44,3)
因此,
objpoints
数组需要以不同的方式格式化,但我无法实现正确的布局。也许有人能帮上忙?正确的objpoints
布局是一个numpy数组列表,其中len(objpoints)=“图片数”
,每个条目都是一个numpy数组
请看一看。OpenCV文档讨论了“向量”,它相当于列表或numpy.array。在这种情况下,“向量的向量”可以解释为numpy.数组的列表。在OpenCV()的示例中,他们将objp设置为objp2=np.zeros((8*9,3),np.float32)
但是,在全向相机或鱼眼相机中,应为:
objp=np.zero((1,8*9,3),np.float32)
想法就在这里数据类型正确,但形状不正确。
objpoints
的预期形状应为(n_观测值,1,n_角点/u观测值,3)
。因此,您案例中的代码应为:
imgpoints = np.array(imgpoints, dtype=np.float32).reshape(
-1,
1,
pattern_width * pattern_height,
3
)
或更一般的:
imgpoints = np.array(imgpoints, dtype=np.float32).reshape(
n_observations,
1,
n_corners_per_observation,
3
)
这个错误消息有点误导人。在这里没有找到令人满意的答案,所以我胡乱处理,最终让这个块工作起来:
calibration_flags = cv2.fisheye.CALIB_RECOMPUTE_EXTRINSIC + cv2.fisheye.CALIB_CHECK_COND + cv2.fisheye.CALIB_FIX_SKEW
# lists with each element a [1,n_points,_] array of type float32
obj_points = [np.random.rand(1,10,3).astype(np.float32)]
fisheye_points = [np.random.rand(1,10,2).astype(np.float32)]
# initialize empty variables of correct size and type, where total_num_points is summed across all arrays in each above list
rvecs = [np.zeros((1, 1, 3), dtype=np.float32) for i in range(total_num_points)]
tvecs = [np.zeros((1, 1, 3), dtype=np.float32) for i in range(total_num_points)]
D = np.zeros([4,1]).astype(np.float32)
K = np.zeros([3,3]).astype(np.float32)
outputs = cv2.fisheye.calibrate(gt_points,fisheye_points,(1920,1080),K,D,rvecs,tvecs)
这是当前cv2.fisheye绑定的一个问题。每个向量的长度是多少?2或3元素?