如何使用 Python OpenCV 创建这种桶形/径向畸变?

How to create this barrel / radial distortion with Python OpenCV?

我正在使用 python / opencv 中的代码制作自定义虚拟现实耳机。我需要能够扭曲图像以创建 "barrel distortion" / "radial distortion" 效果。

一些图片来解释:

我已经有了要使用并向用户展示的 source_image,并且已经将它们并排放置。现在我只需要 out = cv2.createBarrelDistortion(source_image, params) 这样的东西。 (而且我不介意能够调整一些参数,例如畸变中心、畸变幅度等,这样我就可以让它看起来适合我得到的任何定制镜头。)

非常感谢任何帮助!

以下是 Python Wand 0.5.9

中的操作方法

(http://docs.wand-py.org/en/0.5.9/index.html)


输入:

from wand.image import Image
import numpy as np
import cv2


with Image(filename='checks.png') as img:
    print(img.size)
    img.virtual_pixel = 'transparent'
    img.distort('barrel', (0.2, 0.0, 0.0, 1.0))
    img.save(filename='checks_barrel.png')
    # convert to opencv/numpy array format
    img_opencv = np.array(img)

# display result with opencv
cv2.imshow("BARREL", img_opencv)
cv2.waitKey(0)


结果:

请参阅 https://imagemagick.org/Usage/distorts/#barrel 以了解相同的示例和参数讨论。

Python/OpenCV 方法参见 https://hackaday.io/project/12384-autofan-automated-control-of-air-flow/log/41862-correcting-for-lens-distortions

我会使用 scipy ,但仅用于插值:

import numpy as np
from matplotlib import pyplot as plt

import scipy.ndimage

.....

#img: input image

# adjust k_1 and k_2 to achieve the required distortion
k_1 = 0.2
k_2 = 0.05

#img = imread("...")

h,w = [99,100] # img size

x,y = np.meshgrid(np.float32(np.arange(w)),np.float32(np.arange(h))) # meshgrid for interpolation mapping


# center and scale the grid for radius calculation (distance from center of image)
x_c = w/2 
y_c = h/2 
x = x - x_c
y = y - y_c
x = x/x_c
y = y/y_c

radius = np.sqrt(x**2 + y**2) # distance from the center of image

m_r = 1 + k_1*radius + k_2*radius**2 # radial distortion model

# apply the model 
x= x * m_r 
y = y * m_r

# reset all the shifting
x= x*x_c + x_c
y = y*y_c + y_c

distorted = scipy.ndimage.map_coordinates(img, [y.ravel(),x.ravel()])
distorted.resize(img.shape)

.....

我们使用的是一个简单的模型,m_r 因子乘以每个 x,y 会产生一个拉伸,因为它将点移得更远。 最后我们对扭曲的点进行插值并得到我们的图像。