Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions code/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
import os
import cv2

def doMorphing(img1, img2, duration, frame_rate, output):
def doMorphing(img1, img2, duration, frame_rate, output, clean):

[size, img1, img2, points1, points2, list3] = generate_face_correspondences(img1, img2)

tri = make_delaunay(size[1], size[0], list3, img1, img2)

generate_morph_sequence(duration, frame_rate, img1, img2, points1, points2, tri, size, output)
generate_morph_sequence(duration, frame_rate, img1, img2, points1, points2, tri, size, output, clean)

if __name__ == "__main__":

Expand All @@ -24,10 +24,12 @@ def doMorphing(img1, img2, duration, frame_rate, output):
parser.add_argument("--duration", type=int, default=5, help="The duration")
parser.add_argument("--frame", type=int, default=20, help="The frameame Rate")
parser.add_argument("--output", help="Output Video Path")
parser.add_argument("--clean", action="store_true", help="Hide the sides of the triangles")
args = parser.parse_args()

image1 = cv2.imread(args.img1)
image2 = cv2.imread(args.img2)
print("clean = ", args.clean)

doMorphing(image1, image2, args.duration, args.frame, args.output)

doMorphing(image1, image2, args.duration, args.frame, args.output, args.clean)

22 changes: 12 additions & 10 deletions code/face_morph.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def apply_affine_transform(src, srcTri, dstTri, size) :


# Warps and alpha blends triangular regions from img1 and img2 to img
def morph_triangle(img1, img2, img, t1, t2, t, alpha) :
def morph_triangle(img1, img2, img, t1, t2, t, alpha, clean) :

# Find bounding rectangle for each triangle
r1 = cv2.boundingRect(np.float32([t1]))
Expand Down Expand Up @@ -56,7 +56,7 @@ def morph_triangle(img1, img2, img, t1, t2, t, alpha) :
img[r[1]:r[1]+r[3], r[0]:r[0]+r[2]] = img[r[1]:r[1]+r[3], r[0]:r[0]+r[2]] * ( 1 - mask ) + imgRect * mask


def generate_morph_sequence(duration,frame_rate,img1,img2,points1,points2,tri_list,size,output):
def generate_morph_sequence(duration,frame_rate,img1,img2,points1,points2,tri_list,size,output,clean):

num_images = int(duration*frame_rate)
p = Popen(['ffmpeg', '-y', '-f', 'image2pipe', '-r', str(frame_rate),'-s',str(size[1])+'x'+str(size[0]), '-i', '-', '-c:v', 'libx264', '-crf', '25','-vf','scale=trunc(iw/2)*2:trunc(ih/2)*2','-pix_fmt','yuv420p', output], stdin=PIPE)
Expand Down Expand Up @@ -90,18 +90,20 @@ def generate_morph_sequence(duration,frame_rate,img1,img2,points1,points2,tri_li
t = [points[x], points[y], points[z]]

# Morph one triangle at a time.
morph_triangle(img1, img2, morphed_frame, t1, t2, t, alpha)
morph_triangle(img1, img2, morphed_frame, t1, t2, t, alpha, clean)

if not clean:

pt1 = (int(t[0][0]), int(t[0][1]))
pt2 = (int(t[1][0]), int(t[1][1]))
pt3 = (int(t[2][0]), int(t[2][1]))
pt1 = (int(t[0][0]), int(t[0][1]))
pt2 = (int(t[1][0]), int(t[1][1]))
pt3 = (int(t[2][0]), int(t[2][1]))

cv2.line(morphed_frame, pt1, pt2, (255, 255, 255), 1, 8, 0)
cv2.line(morphed_frame, pt2, pt3, (255, 255, 255), 1, 8, 0)
cv2.line(morphed_frame, pt3, pt1, (255, 255, 255), 1, 8, 0)
cv2.line(morphed_frame, pt1, pt2, (255, 255, 255), 1, 8, 0)
cv2.line(morphed_frame, pt2, pt3, (255, 255, 255), 1, 8, 0)
cv2.line(morphed_frame, pt3, pt1, (255, 255, 255), 1, 8, 0)

res = Image.fromarray(cv2.cvtColor(np.uint8(morphed_frame), cv2.COLOR_BGR2RGB))
res.save(p.stdin,'JPEG')

p.stdin.close()
p.wait()
p.wait()