Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When i apply a transform to an image, it shrinks the image. #22

Closed
parkgeonwo opened this issue Oct 6, 2022 · 6 comments
Closed

When i apply a transform to an image, it shrinks the image. #22

parkgeonwo opened this issue Oct 6, 2022 · 6 comments

Comments

@parkgeonwo
Copy link

parkgeonwo commented Oct 6, 2022

code

from pychubby.actions import OpenEyes

a = OpenEyes(scale=-0.04)
new_lf, df = a.perform(lf)
new_lf.plot(show_landmarks=False)

original image

original

applied imgae

new_lf2

If you look at the top side of the applied image, the image is scaled down with a black area.

Is it possible to transform a face without this being made?

https://pychubby.readthedocs.io/en/latest/source/gallery.html
If you look at the LinearTransform gif on the pychubby official website, you will see the same phenomenon.

Thanks for providing a good reference.

@parkgeonwo
Copy link
Author

When I transform the eyes, I want only the eyes to be transformed, not the entire image.

@jankrepl
Copy link
Owner

jankrepl commented Oct 6, 2022

Hey there! And thank you for your interest!

That is actually a great question:) pychubby is built on top of a "4 corners logic". That means that the 4 corners will never be displaced. However, very often points on the edges are going to be displaced and it will lead to these black regions. Note that if it was not the case even weirder artefacts might show up.

Anyway, possible solutions

  1. Just crop the final image so that the black regions on the edges are not visible
  2. Get all the perfectly black pixels (RGB=(0, 0, 0)) and replace them with some other color. A cleaner way of doing this would be passing a custom color in cv.remap when doing the warping.
    warped_img = cv2.remap(img, tform_x, tform_y, order)
  3. Completely change the logic of pychubby and make sure that pixels on the edge of the image are not displaced

I would go for the first option:)

Hope that helps:)

@parkgeonwo
Copy link
Author

parkgeonwo commented Oct 6, 2022

Thank you for answer. Do you know how to prevent the pixels on the edges from being deformed?
Methods 1 and 2 do not seem to be able to solve my problem now.

@jankrepl
Copy link
Owner

jankrepl commented Oct 6, 2022

Well, you would need to modify the source code. See below exactly the lines which implement the "fixed points" logic. Currently, it only "anchors" the 4 corners.

if anchor_corners:
corners = np.array([[0, 0],
[0, shape[0] - 1],
[shape[1] - 1, 0],
[shape[1] - 1, shape[0] - 1]])
new_points = np.vstack([new_points, corners])
old_points = np.vstack([old_points, corners])
points_delta_x = np.concatenate([points_delta_x, [0, 0, 0, 0]])
points_delta_y = np.concatenate([points_delta_y, [0, 0, 0, 0]])

See below a sketch of a possible change

Screenshot 2022-10-06 at 15 57 25

I guess you would have to play around and experiment a bit and see for yourself. You can add as many fixed points as you want. Note that by specifying these fixed points you are basically forcing the displacement at those given points to be 0.

Hope that makes sense:)

@parkgeonwo
Copy link
Author

parkgeonwo commented Oct 7, 2022

Transforming by adding anchor points at 50px spacing to each corner solved the problem. Thank you so very much.

corners_list = []
corners_list.append([0, 0])
corners_list.append([0, shape[0] -1])   # 0,y
corners_list.append([shape[1] -1, 0])   # x,0
corners_list.append([shape[1] -1, shape[0] -1])   # x,y

for i in range(1, shape[0]-1, 50):
    corners_list.append([0,i])
    corners_list.append([shape[1]-1,i])
for i in range(1, shape[1]-1, 50): 
    corners_list.append([i,0])
    corners_list.append([i,shape[0]-1])   

# print(shape[0], shape[1])
# print(corners_list)

if anchor_corners:
    corners = np.array(corners_list)  
    new_points = np.vstack([new_points, corners])
    old_points = np.vstack([old_points, corners])
    points_delta_x = np.concatenate([points_delta_x, [0 for i in range(len(corners_list))]]) 
    points_delta_y = np.concatenate([points_delta_y, [0 for i in range(len(corners_list))]])

@jankrepl
Copy link
Owner

jankrepl commented Oct 7, 2022

Great!

@jankrepl jankrepl closed this as completed Oct 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants