我试图应用鱼眼效果对正常的图像使用opencv鱼眼模块。要将鱼眼图像转换为正常图像,可以使用“cv2.fisheye.undistortimage”API。我不知道如何使用“cv2.fisheye.distortPoints”函数获得鱼眼图像。任何工作示例代码/算法都非常受欢迎。
mm9b1k5b1#
使用cv2.fisheye.distortPoints(),我们可以从源图像的坐标中获得目标(失真)图像的坐标。如here和这里所述,“注意,该函数假设未失真点的相机矩阵是恒等的。这意味着如果你想用undistortPoints()变换回未失真的点,你必须将它们乘以P−1”。函数cv2.fisheye.undistortPoints()接受 * 标准化 * 坐标作为输入,因此我们需要将原始索引乘以相机内部矩阵的逆,如下所示。需要通过 * 摄像机标定 * 得到矩阵摄像机本征值K和畸变系数d:输入鹦鹉图像可以从here获得。
cv2.fisheye.distortPoints()
cv2.fisheye.undistortPoints()
K
d
import matplotlib.pylab as plt import cv2 K = np.array( [[338.37324094,0,319.5],[0,339.059099,239.5],[0,0,1]], dtype=np.float32) # camera intrinsic parameters d = np.array([0.17149, -0.27191, 0.25787, -0.08054], dtype=np.float32) # k1, k2, k3, k4 - distortion coefficients def apply_fisheye_effect(img, K, d): indices = np.array(np.meshgrid(range(img.shape[0]), range(img.shape[1]))).T \ .reshape(np.prod(img.shape[:2]), -1).astype(np.float32) Kinv = np.linalg.inv(K) indices1 = np.zeros_like(indices, dtype=np.float32) for i in range(len(indices)): x, y = indices[i] indices1[i] = (Kinv @ np.array([[x], [y], [1]])).squeeze()[:2] indices1 = indices1[np.newaxis, :, :] in_indices = cv2.fisheye.distortPoints(indices1, K, d) indices, in_indices = indices.squeeze(), in_indices.squeeze() distorted_img = np.zeros_like(img) for i in range(len(indices)): x, y = indices[i] ix, iy = in_indices[i] if (ix < img.shape[0]) and (iy < img.shape[1]): distorted_img[int(ix),int(iy)] = img[int(x),int(y)] return distorted_img K = np.array( [[338.37324094,0,319.5],[0,339.059099,239.5],[0,0,1]],dtype=np.float32) # camera intrinsic params d = np.array([0.17149, -0.27191, 0.25787, -0.08054],dtype=np.float32) # k1, k2, k3, k4 - distortion coefficients img = plt.imread('parrot.jpg') img = img / img.max() distorted_img = apply_fisheye_effect(img, K, d) plt.figure(figsize=(15,7)) plt.subplot(121), plt.imshow(img, aspect='auto'), plt.axis('off'), plt.title('original', size=20) plt.subplot(122), plt.imshow(distorted_img, aspect='auto'), plt.axis('off'), plt.title('distorted', size=20) plt.show()
请注意,通过对几个点(而不是所有点)进行采样并使用插值(例如scipy),可以使上述实现更快。
scipy
1条答案
按热度按时间mm9b1k5b1#
使用
cv2.fisheye.distortPoints()
,我们可以从源图像的坐标中获得目标(失真)图像的坐标。如here和这里所述,“注意,该函数假设未失真点的相机矩阵是恒等的。这意味着如果你想用undistortPoints()变换回未失真的点,你必须将它们乘以P−1”。
函数
cv2.fisheye.undistortPoints()
接受 * 标准化 * 坐标作为输入,因此我们需要将原始索引乘以相机内部矩阵的逆,如下所示。需要通过 * 摄像机标定 * 得到矩阵摄像机本征值
K
和畸变系数d
:输入鹦鹉图像可以从here获得。
请注意,通过对几个点(而不是所有点)进行采样并使用插值(例如
scipy
),可以使上述实现更快。