如何使用Python中的OpenCV-Fisheye模块在普通图像上应用鱼眼效果

4
我正在尝试使用OpenCV的鱼眼模块在普通图像上应用鱼眼效果。
要将鱼眼图像转换为普通图像,可以使用'cv2.fisheye.undistortimage' API。但是我不确定如何使用'cv2.fisheye.distortPoints'函数获取鱼眼图像。非常感谢任何可行的示例代码/算法。

我在https://docs.opencv.org/4.1.1/db/d58/group__calib3d__fisheye.html#ga167df4b00a6fd55287ba829fbf9913b9上找不到任何关于图像扭曲的模块,只有关于点或者对图像进行去畸变的模块。 - fmw42
cv2.undistort(img, camera_matrix, dist_coefs, None, newcameramtx) 尝试交换 newcameramtx 和 camera_matrix - Alex Alex
1个回答

1

使用 cv2.fisheye.distortPoints() 函数,我们可以从源图像的坐标获取目标(畸变)图像的坐标。

此处此处所述,"请注意,该函数假设未畸变点的相机矩阵为单位矩阵。这意味着如果您想要通过 undistortPoints() 函数将点转换回未畸变状态,则需要将它们与 P−1 相乘"。

函数 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()

enter image description here

请注意,上述实现可以通过采样少量点(而不是所有点)并使用插值(例如使用scipy)来大大加快速度。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接