Python OpenCV를 사용한 핀치 / 벌지 왜곡

Sep 26 2020

Python OpenCV를 사용하여 이미지에 핀치 / 벌지 필터를 적용하고 싶습니다. 결과는 다음과 같은 예입니다.

https://pixijs.io/pixi-filters/tools/screenshots/dist/bulge-pinch.gif

필터에 대한 올바른 공식이어야하는 다음 스택 오버 플로우 게시물을 읽었습니다. 배럴 / 핀쿠션 왜곡에 대한 공식

그러나 나는 이것을 Python OpenCV에서 구현하기 위해 고군분투하고 있습니다.

이미지에 필터를 적용하는지도에 대해 읽었습니다. 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, 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()

이것이 예제 이미지에 표시된 왜곡을 달성하는 올바른 방법입니까? 유용한 리소스 또는 바람직하게는 예에 대한 도움을 많이 주시면 감사하겠습니다.

답변

4 fmw42 Sep 26 2020 at 01:46

ImageMagick을 사용하는 Python Wand의 implode 및 explode 옵션을 사용하여이를 수행 할 수 있습니다.

입력:

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)

파열 :

터지다:

3 DaviJones Sep 27 2020 at 15:11

ImageMagick 소스 코드에 익숙해 진 후 왜곡 공식을 적용하는 방법을 찾았습니다. 의 도움으로 OpenCV의 재 배열 기능이 이미지를 왜곡하는 방법입니다 :

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()

이것은 ImageMagick 의 convert -implode 함수를 사용하는 것과 동일한 효과가 있습니다.