如何解决使用Python OpenCV捏缩/凸出变形
我想使用Python OpenCV在图像上应用收缩/凸起过滤器。结果应为以下示例:
https://pixijs.io/pixi-filters/tools/screenshots/dist/bulge-pinch.gif
我已阅读以下应该是过滤器正确公式的stackoverflow帖子:Formulas for Barrel/Pincushion distortion
但是我正在努力在Python OpenCV中实现它。
我已经了解了将地图应用于滤镜的地图:Distortion effect using OpenCv-python
据我了解,代码可能如下所示:
import numpy as np
import cv2 as cv
f_img = 'example.jpg'
im_cv = cv.imread(f_img)
# grab the dimensions of the image
(h,w,_) = im_cv.shape
# set up the x and y maps as float32
flex_x = np.zeros((h,w),np.float32)
flex_y = np.zeros((h,np.float32)
# create map with the barrel pincushion distortion formula
for y in range(h):
for x in range(w):
flex_x[y,x] = APPLY FORMULA TO X
flex_y[y,x] = APPLY FORMULA TO Y
# do the remap this is where the magic happens
dst = cv.remap(im_cv,flex_x,flex_y,cv.INTER_LINEAR)
cv.imshow('src',im_cv)
cv.imshow('dst',dst)
cv.waitKey(0)
cv.destroyAllWindows()
这是实现示例图像中呈现的失真的正确方法吗?非常感谢有关有用资源或示例的帮助。
解决方法
您可以在使用ImageMagick的Python魔杖中使用爆破和爆炸选项来做到这一点。
输入:
from wand.image import Image
import numpy as np
import cv2
with Image(filename='zelda1.jpg') as img:
img.virtual_pixel = 'black'
img.implode(0.5)
img.save(filename='zelda1_implode.jpg')
# convert to opencv/numpy array format
img_implode_opencv = np.array(img)
img_implode_opencv = cv2.cvtColor(img_implode_opencv,cv2.COLOR_RGB2BGR)
with Image(filename='zelda1.jpg') as img:
img.virtual_pixel = 'black'
img.implode(-0.5 )
img.save(filename='zelda1_explode.jpg')
# convert to opencv/numpy array format
img_explode_opencv = np.array(img)
img_explode_opencv = cv2.cvtColor(img_explode_opencv,cv2.COLOR_RGB2BGR)
# display result with opencv
cv2.imshow("IMPLODE",img_implode_opencv)
cv2.imshow("EXPLODE",img_explode_opencv)
cv2.waitKey(0)
放大:
爆炸:
,熟悉ImageMagick源代码后,我找到了一种将公式应用于失真的方法。借助OpenCV remap函数,这是使图像变形的一种方式:
import numpy as np
import cv2 as cv
f_img = 'example.jpg'
im_cv = cv.imread(f_img)
# grab the dimensions of the image
(h,w,_) = im_cv.shape
# set up the x and y maps as float32
flex_x = np.zeros((h,w),np.float32)
flex_y = np.zeros((h,np.float32)
# create map with the barrel pincushion distortion formula
for y in range(h):
delta_y = scale_y * (y - center_y)
for x in range(w):
# determine if pixel is within an ellipse
delta_x = scale_x * (x - center_x)
distance = delta_x * delta_x + delta_y * delta_y
if distance >= (radius * radius):
flex_x[y,x] = x
flex_y[y,x] = y
else:
factor = 1.0
if distance > 0.0:
factor = math.pow(math.sin(math.pi * math.sqrt(distance) / radius / 2),-amount)
flex_x[y,x] = factor * delta_x / scale_x + center_x
flex_y[y,x] = factor * delta_y / scale_y + center_y
# do the remap this is where the magic happens
dst = cv.remap(im_cv,flex_x,flex_y,cv.INTER_LINEAR)
cv.imshow('src',im_cv)
cv.imshow('dst',dst)
cv.waitKey(0)
cv.destroyAllWindows()
与使用ImageMagick的 convert -implode 函数具有相同的效果。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。