File size: 4,368 Bytes
81a10b9
c1bfbc1
 
3627fe5
 
 
 
 
 
b86ea9d
c1bfbc1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a65f332
 
 
 
 
 
f43a498
 
 
c1bfbc1
 
b86ea9d
c1bfbc1
3627fe5
 
 
 
 
2e10e77
3627fe5
 
2e10e77
3627fe5
2e10e77
3627fe5
2e10e77
 
 
 
 
3627fe5
 
 
 
b86ea9d
3627fe5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e9ff5fb
3627fe5
c36ef50
 
4b1097a
4e9eb62
 
3627fe5
b86ea9d
30a3577
 
c1bfbc1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import gradio as gr
import numpy as np
import cv2
import torch

import random
import os

import spaces
'''
class ImageMorpher:
    def __init__(self, num_frames=30, fps=10):
        self.num_frames = num_frames
        self.fps = fps

    def morph_images(self, image_A, image_B):
        """Morphs two images."""
        image_A = np.array(image_A)
        image_B = np.array(image_B)

        if image_A.shape != image_B.shape:
            raise ValueError("Images must have the same dimensions.")
        if image_A.dtype != image_B.dtype:
            raise ValueError("Images must have the same data type.")

        height, width, _ = image_A.shape
        morphed_images = []

        for i in range(self.num_frames + 1):
            alpha = i / self.num_frames
            beta = 1 - alpha
            morphed_image = cv2.addWeighted(image_A, alpha, image_B, beta, 0)
            morphed_images.append(morphed_image)

        return morphed_images

    def create_mp4(self, images, output_path="output.mp4"):
        """Creates an MP4 video from a list of images."""
        height, width, _ = images[0].shape
        fourcc = cv2.VideoWriter_fourcc(*'mp4v')
        video_writer = cv2.VideoWriter(output_path, fourcc, self.fps, (width, height))

        for image in images:
            video_writer.write(image)

        video_writer.release()

    def morph_image_chain(self, images):
        """Morphs a chain of images and returns the video path."""
        morphed_images = []
        for i in range(len(images) - 1):
            morphed_images.extend(self.morph_images(images[i], images[i + 1]))
        self.create_mp4(morphed_images)
        return "output.mp4"

def swap_to_gallery(images):
    return gr.update(value=images, visible=True), gr.update(visible=True), gr.update(visible=False)

def upload_example_to_gallery(images, prompt, style, negative_prompt):
    return gr.update(value=images, visible=True), gr.update(visible=True), gr.update(visible=False)

def remove_back_to_files():
    return gr.update(visible=False), gr.update(visible=False), gr.update(visible=True)
    
# Create an instance of the ImageMorpher class
morpher = ImageMorpher()
"""
# Define the Gradio interface
   ### Description and style
logo = r"""
<center><img src='https://photo-maker.github.io/assets/logo.png' alt='PhotoMaker logo' style="width:80px; margin-bottom:10px"></center>
"""
title = r"""
<h1 align="center">🤗 Morphy the morpher 🤗</h1>
"""
description = r"""
<b></b> 
<br>
Morph image chain into mp4
<br>
How to use:<br>
    -Select two or more images using the "select" tool in the "Images" input field.<br>
    -Click "Submit".<br>

The "Output Video" block will display the morphed video, which you can watch and download.<br>
""" 
css = '''
.gradio-container {width: 85% !important}
'''
"""
with gr.Blocks(css=css) as demo:
    gr.Markdown(logo)
    gr.Markdown(title)
    gr.Markdown(description)

    
    with gr.Row():
        with gr.Column():

            fn=morpher.morph_image_chain,
            files = gr.File(
                    label="Drag (Select) 1 or more photos of your face",
                    file_types=["image"],
                    file_count="multiple"
                )
            inputs = gr.Gallery(label="Your images",type="numpy", visible=False, columns=5, rows=1, height=200)
        with gr.Column(visible=False) as clear_button:
            remove_and_reupload = gr.ClearButton(value="Remove and upload new ones", components=files, size="sm")
        with gr.Column():
            outputs=gr.Video(label="Output Video",interactive=False),
            title="Image Chain Morphing App",
        with gr.Column():
            gallery = gr.Gallery(label="Generated Images") 
            
        files.upload(fn=swap_to_gallery, inputs=files, outputs=[files, clear_button, files])
        remove_and_reupload.click(fn=remove_back_to_files, outputs=[files, clear_button, files])
demo.launch()
"""

import app1
'''
Explanation:

ImageMorpher class:

Encapsulates the morphing logic and video creation.
Has num_frames and fps attributes for customization.
morph_images method handles morphing two images.
create_mp4 method creates the MP4 video.
morph_image_chain method:
Iterates through the input image list and morphs each pair.
Creates the final MP4 video using create_mp4.
Returns the path to the video file.


'''