如何使用python中的opencv-fisheye模块在普通图像上应用鱼眼效果

问题描述 投票:0回答:1

我正在尝试使用 opencv-fisheye 模块在普通图像上应用鱼眼效果。

要将鱼眼图像转换为普通图像,可以使用“cv2.fisheye.un Distorimage” API。我不确定如何借助“cv2.fisheye. DistortionPoints”函数获取鱼眼图像。非常感谢任何工作示例代码/算法。

python opencv distortion fisheye radial
1个回答
0
投票

使用

cv2.fisheye.distortPoints()
,我们可以从源图像的坐标中获得目标(扭曲)图像的坐标。

herehere所述,“请注意,该函数假设未失真点的相机矩阵是恒等的。这意味着如果您想使用un DistorPoints()将未失真的点变换回原点,则必须将它们与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('images/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
),可以使上述实现速度更快。

© www.soinside.com 2019 - 2024. All rights reserved.