Bhanumacharla commited on
Commit
05dcc83
Β·
1 Parent(s): 73a1b58

Added Flask AnimeGAN app

Browse files
Files changed (2) hide show
  1. app.py +163 -0
  2. requirements.txt +7 -0
app.py ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import cv2
4
+ import numpy as np
5
+ import torchvision.transforms as transforms
6
+ from PIL import Image
7
+ import random
8
+ import os
9
+
10
+ # πŸš€ Load the AnimeGANv2 model with GPU support
11
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
12
+ print(f"πŸ”Ή Using device: {device}")
13
+
14
+ # Load the AnimeGANv2 model (choose a style)
15
+ model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="paprika").to(device)
16
+ model.eval()
17
+
18
+ model2 = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="face_paint_512_v2").to(device)
19
+ model2.eval()
20
+
21
+ # Define image transformation function
22
+ transform = transforms.Compose([
23
+ transforms.ToTensor(),
24
+ transforms.Normalize((0.5,), (0.5,)), # Normalize to [-1, 1]
25
+ ])
26
+
27
+ def process_frame(frame):
28
+ """Convert a video frame to anime style using GPU"""
29
+ img = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
30
+ img_tensor = transform(img).unsqueeze(0).to(device) # Move to GPU
31
+
32
+ with torch.no_grad():
33
+ output = model(img_tensor) # Apply model
34
+
35
+ # Convert output tensor to NumPy image
36
+ output = output.squeeze(0).cpu().numpy() # Move back to CPU
37
+ output = np.transpose(output, (1, 2, 0))
38
+ output = (output + 1) / 2 # Normalize to [0, 1]
39
+ output_img = (output * 255).astype(np.uint8)
40
+
41
+ img_tensor2 = transform(output_img).unsqueeze(0).to(device) # Move to GPU
42
+
43
+ with torch.no_grad():
44
+ output2 = model2(img_tensor2) # Apply model
45
+
46
+ # Convert output tensor to NumPy image
47
+ output2 = output2.squeeze(0).cpu().numpy() # Move back to CPU
48
+ output2 = np.transpose(output2, (1, 2, 0))
49
+ output2 = (output2 + 1) / 2 # Normalize to [0, 1]
50
+ output2_img = (output2 * 255).astype(np.uint8)
51
+
52
+ return cv2.cvtColor(output2_img, cv2.COLOR_RGB2BGR)
53
+
54
+ def apply_motion_blur(frame, kernel_size=25):
55
+ """Applies motion blur to simulate page flip transition"""
56
+ kernel = np.zeros((kernel_size, kernel_size))
57
+ kernel[int((kernel_size - 1) / 2), :] = np.ones(kernel_size)
58
+ kernel /= kernel_size
59
+ return cv2.filter2D(frame, -1, kernel)
60
+
61
+ def apply_random_transformations(frame):
62
+ """Applies small changes to make video unique"""
63
+
64
+ # Slightly change brightness and contrast
65
+ alpha = random.uniform(0.9, 1.1) # Contrast
66
+ beta = random.randint(-10, 10) # Brightness
67
+ frame = cv2.convertScaleAbs(frame, alpha=alpha, beta=beta)
68
+
69
+ return frame
70
+
71
+ def apply_color_modifications(frame):
72
+ """Applies slight hue shift, saturation change, and noise to make video unique"""
73
+
74
+ # Convert frame to HSV
75
+ hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV).astype(np.float32)
76
+
77
+ # 🎨 Random Hue Shift (1-5 degrees)
78
+ hue_shift = random.randint(-5, 5)
79
+ hsv[:, :, 0] = (hsv[:, :, 0] + hue_shift) % 180
80
+
81
+ # πŸ”₯ Random Saturation Boost (0.9x - 1.1x)
82
+ sat_scale = random.uniform(0.9, 1.1)
83
+ hsv[:, :, 1] = np.clip(hsv[:, :, 1] * sat_scale, 0, 255)
84
+
85
+ # 🎭 Convert back to BGR
86
+ frame = cv2.cvtColor(hsv.astype(np.uint8), cv2.COLOR_HSV2BGR)
87
+
88
+ return frame
89
+
90
+ def process_video(input_video_path, speed_factor=1, skipping_factor=2):
91
+ output_video_path = "anime_video.mp4"
92
+
93
+ # Open the input video
94
+ cap = cv2.VideoCapture(input_video_path)
95
+
96
+ # Get video properties
97
+ frame_width = int(cap.get(3))
98
+ frame_height = int(cap.get(4))
99
+
100
+ original_fps = int(cap.get(cv2.CAP_PROP_FPS))
101
+ total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
102
+
103
+ # Adjust FPS based on speed factor
104
+ new_fps = max(1, int(original_fps * speed_factor)) # Ensure FPS doesn't drop to 0
105
+
106
+ # Define video writer
107
+ fourcc = cv2.VideoWriter_fourcc(*"mp4v")
108
+ out = cv2.VideoWriter(output_video_path, fourcc, new_fps, (frame_width, frame_height))
109
+
110
+ frame_count = 0
111
+ print("πŸŽ₯ Processing video with Smooth Book Flip effect...")
112
+
113
+ previous_anime_frame = None
114
+
115
+ # Process video frame-by-frame
116
+ while cap.isOpened():
117
+ ret, frame = cap.read()
118
+ if not ret:
119
+ break # End of video
120
+
121
+ if frame_count % skipping_factor == 0:
122
+ # Skip some frames randomly to alter video signature
123
+ if random.random() > 0.95: # Skip 5% of frames randomly
124
+ frame_count += 1
125
+ continue
126
+
127
+ anime_frame = process_frame(frame)
128
+ anime_frame = apply_random_transformations(anime_frame)
129
+ anime_frame = apply_color_modifications(anime_frame)
130
+
131
+ out.write(anime_frame) # Write stylized frame
132
+
133
+ # Add motion-blurred transition frame instead of white screen
134
+ if previous_anime_frame is not None:
135
+ blurred_transition = apply_motion_blur(anime_frame, kernel_size=20)
136
+ out.write(blurred_transition)
137
+
138
+ previous_anime_frame = anime_frame # Store last processed frame
139
+
140
+ frame_count += 1
141
+ print(f"Processing frame {frame_count}/{total_frames}", end="\r")
142
+
143
+ # Release resources
144
+ cap.release()
145
+ out.release()
146
+
147
+ os.remove(input_video_path)
148
+ return output_video_path
149
+
150
+ demo = gr.Interface(
151
+ fn=process_video,
152
+ inputs=[
153
+ gr.Video(label="Upload your video"),
154
+ gr.Slider(0.25, 1.5, value=1, step=0.05, label="Speed Factor (Lower = Slower, Higher = Faster)"),
155
+ gr.Slider(1, 10, value=2, step=1, label="Frames skipping Factor (Lower = Less, Higher = More)"),
156
+ ],
157
+ outputs=gr.Video(),
158
+ title="AnimeGAN Video Styler",
159
+ description="Upload a video and get an anime-stylized version!"
160
+ )
161
+
162
+ if __name__ == "__main__":
163
+ demo.launch(share=True)
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ flask
2
+ torch
3
+ torchvision
4
+ opencv-python
5
+ numpy
6
+ pillow
7
+ gradio