| | import gradio as gr |
| | import cv2 |
| | import numpy as np |
| | import tensorflow as tf |
| | import tensorflow_addons |
| |
|
| | from facenet_pytorch import MTCNN |
| | from PIL import Image |
| | import moviepy.editor as mp |
| | import os |
| | import zipfile |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | |
| | mtcnn = MTCNN(margin=14, keep_all=True, factor=0.7, device='cpu') |
| |
|
| | |
| | class DetectionPipeline: |
| | """Pipeline class for detecting faces in the frames of a video file.""" |
| |
|
| | def __init__(self, detector, n_frames=None, batch_size=60, resize=None): |
| | """Constructor for DetectionPipeline class. |
| | |
| | Keyword Arguments: |
| | n_frames {int} -- Total number of frames to load. These will be evenly spaced |
| | throughout the video. If not specified (i.e., None), all frames will be loaded. |
| | (default: {None}) |
| | batch_size {int} -- Batch size to use with MTCNN face detector. (default: {32}) |
| | resize {float} -- Fraction by which to resize frames from original prior to face |
| | detection. A value less than 1 results in downsampling and a value greater than |
| | 1 result in upsampling. (default: {None}) |
| | """ |
| | self.detector = detector |
| | self.n_frames = n_frames |
| | self.batch_size = batch_size |
| | self.resize = resize |
| |
|
| | def __call__(self, filename): |
| | """Load frames from an MP4 video and detect faces. |
| | |
| | Arguments: |
| | filename {str} -- Path to video. |
| | """ |
| | |
| | v_cap = cv2.VideoCapture(filename) |
| | v_len = int(v_cap.get(cv2.CAP_PROP_FRAME_COUNT)) |
| |
|
| | |
| | if self.n_frames is None: |
| | sample = np.arange(0, v_len) |
| | else: |
| | sample = np.linspace(0, v_len - 1, self.n_frames).astype(int) |
| |
|
| | |
| | faces = [] |
| | frames = [] |
| | for j in range(v_len): |
| | success = v_cap.grab() |
| | if j in sample: |
| | |
| | success, frame = v_cap.retrieve() |
| | if not success: |
| | continue |
| | frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) |
| | |
| |
|
| | |
| | if self.resize is not None: |
| | frame = frame.resize([int(d * self.resize) for d in frame.size]) |
| | frames.append(frame) |
| |
|
| | |
| | if len(frames) % self.batch_size == 0 or j == sample[-1]: |
| |
|
| | boxes, probs = self.detector.detect(frames) |
| |
|
| | for i in range(len(frames)): |
| |
|
| | if boxes[i] is None: |
| | faces.append(face2) |
| | continue |
| |
|
| | box = boxes[i][0].astype(int) |
| | frame = frames[i] |
| | face = frame[box[1]:box[3], box[0]:box[2]] |
| |
|
| | if not face.any(): |
| | faces.append(face2) |
| | continue |
| |
|
| | face2 = cv2.resize(face, (224, 224)) |
| |
|
| | faces.append(face2) |
| |
|
| | frames = [] |
| |
|
| | v_cap.release() |
| |
|
| | return faces |
| |
|
| |
|
| | detection_pipeline = DetectionPipeline(detector=mtcnn,n_frames=20, batch_size=60) |
| |
|
| | model = tf.keras.models.load_model("p1") |
| |
|
| |
|
| | def deepfakespredict(input_video): |
| |
|
| | faces = detection_pipeline(input_video) |
| |
|
| | total = 0 |
| | real = 0 |
| | fake = 0 |
| |
|
| | for face in faces: |
| |
|
| | face2 = face/255 |
| | pred = model.predict(np.expand_dims(face2, axis=0))[0] |
| | total+=1 |
| |
|
| | pred2 = pred[1] |
| |
|
| | if pred2 > 0.5: |
| | fake+=1 |
| | else: |
| | real+=1 |
| |
|
| | fake_ratio = fake/total |
| |
|
| | text ="" |
| | text2 = "Deepfakes Confidence: " + str(fake_ratio*100) + "%" |
| |
|
| | if fake_ratio >= 0.5: |
| | text = "The video is FAKE." |
| | else: |
| | text = "The video is REAL." |
| |
|
| | face_frames = [] |
| | |
| | for face in faces: |
| | face_frame = Image.fromarray(face.astype('uint8'), 'RGB') |
| | face_frames.append(face_frame) |
| | |
| | face_frames[0].save('results.gif', save_all=True, append_images=face_frames[1:], duration = 250, loop = 100 ) |
| | clip = mp.VideoFileClip("results.gif") |
| | clip.write_videofile("video.mp4") |
| |
|
| | return text, text2, "video.mp4" |
| |
|
| |
|
| |
|
| | title="EfficientNetV2 Deepfakes Video Detector" |
| | |
| | examples = [ |
| | ['Video1-fake-1-ff.mp4'], |
| | ['Video6-real-1-ff.mp4'], |
| | ['Video3-fake-3-ff.mp4'], |
| | ['Video8-real-3-ff.mp4'], |
| | ['real-1.mp4'], |
| | ['fake-1.mp4'], |
| | ] |
| | |
| | gr.Interface(deepfakespredict, |
| | inputs = ["video"], |
| | outputs=["text","text", gr.Video(label="Detected face sequence")], |
| | title=title, |
| | examples=examples |
| | ).launch() |