微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用Python OpenCV捏缩/凸出变形

如何解决使用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魔杖中使用爆破和爆炸选项来做到这一点。

输入:

enter image description here

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)

放大:

enter image description here

爆炸:

enter image description here

,

熟悉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 举报,一经查实,本站将立刻删除。