Spaces:
Running
Running
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import cv2
|
3 |
+
import glob
|
4 |
+
import shutil
|
5 |
+
import numpy as np
|
6 |
+
import gradio as gr
|
7 |
+
from PIL import Image
|
8 |
+
from moviepy.editor import VideoFileClip, AudioFileClip, CompositeAudioClip
|
9 |
+
from insightface.app import FaceAnalysis
|
10 |
+
|
11 |
+
def video_to_images(video_path, images_path):
|
12 |
+
cam = cv2.VideoCapture(video_path)
|
13 |
+
fps = cam.get(cv2.CAP_PROP_FPS)
|
14 |
+
clip = VideoFileClip(video_path)
|
15 |
+
clip.audio.write_audiofile("./audio.mp3")
|
16 |
+
|
17 |
+
if os.path.exists(images_path):
|
18 |
+
shutil.rmtree(images_path)
|
19 |
+
os.makedirs(images_path)
|
20 |
+
|
21 |
+
frame_num = 0
|
22 |
+
while True:
|
23 |
+
ret, frame = cam.read()
|
24 |
+
if not ret:
|
25 |
+
break
|
26 |
+
filename = os.path.join(images_path, f"{frame_num:05}.png")
|
27 |
+
cv2.imwrite(filename, frame, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])
|
28 |
+
frame_num += 1
|
29 |
+
|
30 |
+
cam.release()
|
31 |
+
return fps
|
32 |
+
|
33 |
+
def blur_faces_in_images(images_path):
|
34 |
+
faceapp = FaceAnalysis(name="buffalo_l", providers=["CPUExecutionProvider"])
|
35 |
+
faceapp.prepare(ctx_id=0)
|
36 |
+
|
37 |
+
for img_path in sorted(glob.glob(os.path.join(images_path, "*.png"))):
|
38 |
+
img = cv2.imread(img_path)
|
39 |
+
faces = faceapp.get(img)
|
40 |
+
for face in faces:
|
41 |
+
x1, y1, x2, y2 = list(map(int, face.bbox))
|
42 |
+
face_crop = img[y1:y2, x1:x2]
|
43 |
+
img[y1:y2, x1:x2] = cv2.GaussianBlur(face_crop, (99, 99), 30)
|
44 |
+
cv2.imwrite(img_path, img)
|
45 |
+
|
46 |
+
def images_to_video(images_path, output_path, fps):
|
47 |
+
images = sorted(glob.glob(os.path.join(images_path, "*.png")))
|
48 |
+
frame = cv2.imread(images[0])
|
49 |
+
height, width, _ = frame.shape
|
50 |
+
|
51 |
+
temp_path = "temp_video.avi"
|
52 |
+
fourcc = cv2.VideoWriter_fourcc(*'XVID')
|
53 |
+
out = cv2.VideoWriter(temp_path, fourcc, fps, (width, height))
|
54 |
+
|
55 |
+
for img_path in images:
|
56 |
+
frame = cv2.imread(img_path)
|
57 |
+
out.write(frame)
|
58 |
+
out.release()
|
59 |
+
|
60 |
+
video = VideoFileClip(temp_path)
|
61 |
+
audio = AudioFileClip("audio.mp3")
|
62 |
+
final = video.set_audio(audio)
|
63 |
+
final.write_videofile(output_path, codec="libx264", audio_codec="aac")
|
64 |
+
|
65 |
+
os.remove(temp_path)
|
66 |
+
os.remove("audio.mp3")
|
67 |
+
|
68 |
+
def process(video):
|
69 |
+
input_path = "input.mp4"
|
70 |
+
output_path = "output.mp4"
|
71 |
+
frames_dir = "frames"
|
72 |
+
|
73 |
+
video.save(input_path)
|
74 |
+
fps = video_to_images(input_path, frames_dir)
|
75 |
+
blur_faces_in_images(frames_dir)
|
76 |
+
images_to_video(frames_dir, output_path, fps)
|
77 |
+
|
78 |
+
shutil.rmtree(frames_dir)
|
79 |
+
return output_path
|
80 |
+
|
81 |
+
demo = gr.Interface(
|
82 |
+
fn=process,
|
83 |
+
inputs=gr.Video(label="Upload Video"),
|
84 |
+
outputs=gr.Video(label="Faces Blurred"),
|
85 |
+
title="Face Blurring App",
|
86 |
+
description="Uploads a video and returns the same video with all faces blurred using InsightFace."
|
87 |
+
)
|
88 |
+
|
89 |
+
if __name__ == "__main__":
|
90 |
+
demo.launch()
|