1

I have an assignment to transform an image

im1

to one that has distortion effect like a dent, squeeze, stretch like this:

im2

im3

im4

I have done with twirling, fisheye, bulge, but I'm having a hard time finding the right formulas for those effects. here is my code for twirling:

import numpy as np
import cv2 
import math 
from google.colab.patches import cv2_imshow
img = cv2.imread("./orig_img.png")

h,w,_ = img.shape
flex_x = np.zeros((h,w),np.float32)
flex_y = np.zeros((h,w),np.float32)

scale_y= 1
scale_x = 1
alpha = -1.8
center_x, center_y = (w // 2, h // 2)
radius = h/5

for y in range(h):
    delta_y = scale_y * (y - center_y)
    for x in range(w):
        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:
            theta = np.arctan2(delta_x,delta_y) + alpha*(radius-math.sqrt(distance))/radius
            r_sin = math.sqrt(distance)*np.cos(theta)
            r_cos = math.sqrt(distance)*np.sin(theta)
            flex_x[y, x] = r_cos + center_x
            flex_y[y, x] = r_sin + center_y

dst = cv2.remap(img, flex_x, flex_y, cv2.INTER_LINEAR)
cv2_imshow(dst)

Anyone who has experience with this kind of transformation, please help me! I'm really thankful.

  • 1
    Have a look at thinPlateShapeTransformer – Micka Jan 12 '22 at 09:50
  • related (ThinPlateSplineShapeTransformer) https://stackoverflow.com/questions/70601059/opencv2-thin-plate-splines-apply-transformation-not-working – Christoph Rackwitz Jan 12 '22 at 10:54
  • related (previous task of the assignment, same user, different account): https://stackoverflow.com/questions/70668248/how-to-create-light-tunnel-transformation-image – Christoph Rackwitz Jan 12 '22 at 10:54
  • 2
    if the thin plate/spline thing isn't to your liking, all I can recommend is to imagine the problem in 1D. imagine a plot of y=x, then imagine deforming that plot. "wavelets" may be helpful to compose a suitable function. here's something that would "stretch" using a derivative of a gaussian [wolfram alpha link](https://www.wolframalpha.com/input/?i=plot+%7By%3Dx%2C+y+%3D+x+%2B+2+*+-x%2F%281.0%5E3+*+sqrt%282*pi%29%29+*+exp%28-x%5E2+%2F+%282*1.0%5E2%29%29%7D+from+-3+to+%2B3) when used as a map (y values are used as lookup into source picture). for pinching just change the sign and scale factor – Christoph Rackwitz Jan 12 '22 at 11:04
  • thank you, I'll try them, it's a good idea tot think as 1d problem – Nguyen Viet Jan 12 '22 at 13:36

0 Answers0