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)
from PIL import ImageOps
class BarrelDeformer:
def transform(self, x, y):
# center and scale the grid for radius calculation (distance from center of image)
x_c, y_c = w / 2, h / 2
x = (x - x_c) / x_c
y = (y - y_c) / 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, y = x * m_r, y * m_r
# reset all the shifting
x, y = x*x_c + x_c, y*y_c + y_c
return x, y
def transform_rectangle(self, x0, y0, x1, y1):
return (*self.transform(x0, y0),
*self.transform(x0, y1),
*self.transform(x1, y1),
*self.transform(x1, y0),
)
def getmesh(self, img):
self.w, self.h = img.size
gridspace = 20
target_grid = []
for x in range(0, self.w, gridspace):
for y in range(0, self.h, gridspace):
target_grid.append((x, y, x + gridspace, y + gridspace))
source_grid = [self.transform_rectangle(*rect) for rect in target_grid]
return [t for t in zip(target_grid, source_grid)]
# adjust k_1 and k_2 to achieve the required distortion
k_1 = 0.2
k_2 = 0.05
im = Image.open('house.png')
im.putalpha(255)
w, h = im.size
im_deformed = ImageOps.deform(im, BarrelDeformer())
plt.figure(figsize=(12,5))
plt.imshow(np.hstack((np.array(im), np.array(im_deformed)))), plt.axis('off')
plt.title('The original and the deformed image', size=20)
plt.show()
3条答案
按热度按时间kninwzqo1#
下面是如何在Python Wand 0.5.9中实现的
(http://docs.wand-py.org/en/0.5.9/index.html)
输入:
结果:
请参阅https://imagemagick.org/Usage/distorts/#barrel以获取相同的示例和参数讨论。
参见https://hackaday.io/project/12384-autofan-automated-control-of-air-flow/log/41862-correcting-for-lens-distortions了解Python/OpenCV方法。
4ktjp1zp2#
我将使用scipy,但仅用于插值:
....
....
我们使用的是一个简单的模型,
m_r
因子乘以每个x,y
,当它将点移得更远时,会给出一个拉伸。最后对畸变点进行插值得到图像。vzgqcmou3#
我们可以用Sankalp Bhamare的Barrel实现中的
PIL
的ImageOps.deform()
替换scipy.ndimage.map_coordinates()
,以获得相同的期望失真: