Created
December 29, 2018 00:24
-
-
Save smeschke/b6ff8ba5a8f044d7a7475dfdb111d921 to your computer and use it in GitHub Desktop.
Warps an image to make it look like you didn't eat too much sweets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cv2, numpy as np | |
# Read image | |
img = cv2.imread('/home/stephen/Desktop/vids/me.png') | |
h,w,_ = img.shape | |
sf = 1 | |
img = cv2.resize(img, (int(w/sf), int(h/sf))) | |
img_pristine = img.copy() | |
# Get clicks from user | |
global click_list | |
click_list = [] | |
def callback(event, x, y, flags, param): | |
if event == 1: | |
click_list.append((x,y)) | |
print(x,y) | |
cv2.namedWindow('img') | |
cv2.setMouseCallback('img', callback) | |
# Takes an image and three points | |
# Returns an image where everythign is blacked out except that triangle | |
def get_mask(p0, p1, p2): | |
h,w,_ = img.shape | |
mask = np.zeros((h,w), np.uint8) | |
pts = np.array([p0,p1,p2], np.int32) | |
mask = cv2.drawContours(mask, [pts], 0, 255, -1) | |
return mask | |
# Take the image and two sets of points. | |
# Transform the image | |
def transform(img, p0, p1, old_center, new_center): | |
rows,cols,ch = img.shape | |
pts1 = np.float32([p0,p1,old_center]) | |
pts2 = np.float32([p0,p1,new_center]) | |
M = cv2.getAffineTransform(pts1,pts2) | |
dst = cv2.warpAffine(img,M,(cols,rows)) | |
return dst | |
# Takes an image, and a mask | |
# Returns the image, minus the parts of the image that are masked out | |
def mask_image(img, mask): | |
res = cv2.bitwise_and(img,img, mask= mask) | |
return res | |
k=0 | |
while k!=27: | |
img_pristine = img.copy() | |
# Get the input from the user | |
while True: | |
# Display the input to the user | |
img_copy = img.copy() | |
try: | |
cv2.circle(img_copy, click_list[0], 12, 234) | |
cv2.line(img_copy, click_list[0], click_list[1], 255, 3) | |
cv2.circle(img_copy, click_list[1], 12, 234) | |
cv2.line(img_copy, click_list[1], click_list[2], 255, 3) | |
cv2.circle(img_copy, click_list[2], 12, 234) | |
cv2.line(img_copy, click_list[2], click_list[0], 255, 3) | |
cv2.circle(img_copy, click_list[3], 12, 234) | |
cv2.line(img_copy, click_list[3], click_list[2], 255, 3) | |
cv2.line(img_copy, click_list[3], click_list[1], 255, 3) | |
cv2.line(img_copy, click_list[3], click_list[0], 255, 3) | |
except: pass | |
# Check if all the input has been collected | |
if len(click_list)==5: break | |
# Show the image | |
cv2.imshow('img', img_copy) | |
k = cv2.waitKey(1) | |
if k == 27:break | |
# All of the user input has been collected, time to warp the image. | |
# A triangular region of the image is warped from this old center | |
old_center = click_list[3] | |
# To a new center | |
new_center = click_list[4] | |
# Define the three triangles | |
triangles = [] | |
triangles.append((click_list[0], click_list[1])) | |
triangles.append((click_list[1], click_list[2])) | |
triangles.append((click_list[2], click_list[0])) | |
for a,b in triangles: | |
# Warp triangle | |
warped_triangle = transform(img_pristine, a, b, old_center, new_center) | |
# Generate mask of warped triangle | |
mask = get_mask(a, b, new_center) | |
# Mask source image (now the background) | |
background = mask_image(img, 255-mask) | |
#cv2.imshow('img', background) | |
#k = cv2.waitKey(0) | |
# Mask warped triangle image (new the foreground) | |
foreground = mask_image(warped_triangle, mask) | |
#cv2.imshow('img', foreground) | |
#k = cv2.waitKey(0) | |
# Paste warped triangle onto masked source | |
img = background + foreground | |
#cv2.imshow('img', img) | |
#k = cv2.waitKey(0) | |
cv2.imshow('img', img) | |
k = cv2.waitKey(0) | |
click_list = [] | |
cv2.destroyAllWindows() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This file is used to warp images. First, two sets of three triangles are manually defined by the user. Then the first set of three triangles (the fat set) is morphed into the second set of triangles (the thin set).

