Python OpenCV kullanarak sıkıştırma / çıkıntı distorsiyonu
Python OpenCV kullanarak bir görüntüye bir sıkıştırma / şişkinlik filtresi uygulamak istiyorum. Sonuç şu örnekten bir tür olmalıdır:
https://pixijs.io/pixi-filters/tools/screenshots/dist/bulge-pinch.gif
Filtre için doğru formül olması gereken aşağıdaki yığın aşımı gönderisini okudum: Namlu / İğne yastığı distorsiyonu için Formüller
Ancak bunu Python OpenCV'de uygulamakta zorlanıyorum.
Bir görüntüye filtre uygulamak için haritalar hakkında okudum: OpenCv-python kullanarak bozulma etkisi
Anladığım kadarıyla, kod şöyle bir şeye benzeyebilir:
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, w), 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()
Örnek resimde sunulan distorsiyonu elde etmenin doğru yolu bu mu? Yararlı kaynaklar veya tercihen örneklerle ilgili herhangi bir yardım çok takdir edilmektedir.
Yanıtlar
Bunu, ImageMagick kullanan Python Wand'daki implode ve explode seçeneklerini kullanarak yapabilirsiniz.
Giriş:
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)
Implode:
Patlat:
ImageMagick kaynak kodunu öğrendikten sonra, distorsiyon formülünü uygulamanın bir yolunu buldum. OpenCV yeniden eşleme işlevinin yardımıyla , bu bir görüntüyü deforme etmenin bir yoludur:
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, w), 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()
Bu, ImageMagick'in convert -implode işlevini kullanmakla aynı etkiye sahiptir .