Hackster is hosting Hackster Holidays, Ep. 7: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 7 on Friday!
zhaoshuang
Published

A real-time DeepFake detection tool

This project can detect DeepFake real-time fake videos that cannot be recognized by human eyes, and the response is faster with the NPU.

106
A real-time DeepFake detection tool

Story

Read more

Code

model_df_1.onnx

Python
The trained model is used to classify face forgery
No preview (download only).

draw.py

Python
Marking the face area
# Used to mark facial regions on the screen

import win32gui
import win32con
import win32api
import time
from win32api import GetSystemMetrics


def draw_rectangle(hwnd, rect, color):
    hdc = win32gui.GetWindowDC(hwnd)
    # Draw Border
    hpen = win32gui.CreatePen(win32con.PS_SOLID, 3, color)
    #color2 = win32api.RGB(255, 255, 255)
    # The interior of the rectangle is filled with transparency
    hbrush = win32gui.CreateSolidBrush(win32con.NULL_BRUSH)
    old_brush = win32gui.SelectObject(hdc, hbrush)
    old_pen = win32gui.SelectObject(hdc, hpen)
    win32gui.Rectangle(hdc, rect[0], rect[1], rect[2], rect[3])
    win32gui.SelectObject(hdc, old_brush)
    win32gui.SelectObject(hdc, old_pen)
    win32gui.DeleteObject(hbrush)
    win32gui.DeleteObject(hpen)
    win32gui.ReleaseDC(hwnd, hdc)


def juxing(rectangle,t):
    # Get handle to desktop window
    desktop_hwnd = win32gui.GetDesktopWindow()

    # Define the position and size of the rectangle
    #rect = (100, 100, 500, 500)  # (left, top, right, bottom)
    rect = rectangle

    # Define the color of the rectangle (green)
    color = win32api.RGB(0, 255, 0)
    hwnd = win32gui.WindowFromPoint((0, 0))
    monitor = (0, 0, GetSystemMetrics(0), GetSystemMetrics(1))

    start_time = time.time()
    while True:
        elapsed_time = time.time() - start_time
        # Duration of rectangular box
        if elapsed_time >= t:
            print("Loop end")
            break
        draw_rectangle(desktop_hwnd, rect,color)
        win32gui.InvalidateRect(hwnd, monitor, True)  # Refresh the entire monitor


# juxing((100, 100, 500, 500))

dfdetect.py

Python
The most critical code file,deepfake detect
# zhaoshuang

import onnx
import onnxruntime as ort
import numpy as np
from PIL import Image
from pathlib import Path
import os
import cv2
import dlib
import torch
import torch.nn as nn
import pyautogui
import draw

global flag
flag: int = 1
def get_boundingbox(face, width, height, scale=1.3, minsize=None):
    """
    Expects a dlib face to generate a quadratic bounding box.
    :param face: dlib face class
    :param width: frame width
    :param height: frame height
    :param scale: bounding box size multiplier to get a bigger face region
    :param minsize: set minimum bounding box size
    :return: x, y, bounding_box_size in opencv form
    """
    x1 = face.left()
    y1 = face.top()
    x2 = face.right()
    y2 = face.bottom()
    size_bb = int(max(x2 - x1, y2 - y1) * scale)
    if minsize:
        if size_bb < minsize:
            size_bb = minsize
    center_x, center_y = (x1 + x2) // 2, (y1 + y2) // 2

    # Check for out of bounds, x-y top left corner
    x1 = max(int(center_x - size_bb // 2), 0)
    y1 = max(int(center_y - size_bb // 2), 0)
    # Check for too big bb size for given x, y
    size_bb = min(width - x1, size_bb)
    size_bb = min(height - y1, size_bb)

    return x1, y1, size_bb

def detect(picname,session):
    '''
    Detection classification
    :param picname:Screenshot image
    :param session:use NPU
    :return: label,real,fake,noface
    '''
    image = picname

    # Face detector
    face_detector = dlib.get_frontal_face_detector()

    # Text variables
    font_face = cv2.FONT_HERSHEY_SIMPLEX
    thickness = 2
    font_scale = 1
 
    height, width = image.shape[:2]

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    faces = face_detector(gray, 1)

    if len(faces):
        # For now only take biggest face
        face = faces[0]
        # Prediction
        # Face crop with dlib and bounding box scale enlargement
        x, y, size = get_boundingbox(face, width, height)
        cropped_face = image[y:y+size, x:x+size]

        cf = Image.fromarray(cropped_face)
        imagex = cf.resize((299, 299)) 
        image_array = np.array(imagex).astype(np.float32)
        # image_array = image_array/255
        
        # Reshape the array to match the input shape expected by the model
        image_array = np.transpose(image_array, (2, 0, 1))  

        # Add a batch dimension to the input image
        input_data = np.expand_dims(image_array, axis=0)

        # Run the model
        outputs = session.run(None, {'input': input_data})
    
        #Process the outputs
        output_array = outputs[0]

        post_function=nn.Softmax(dim=1)
        temp = torch.from_numpy(output_array)

        output = post_function(temp)
        _, prediction = torch.max(output, 1)    # argmax
        prediction = float(prediction.numpy())

        x = face.left()
        y = face.top()
        w = face.right() - x
        h = face.bottom() - y
        label = 'fake' if prediction == 1 else 'real'
        color = (0, 255, 0) if prediction == 0 else (0, 0, 255)
        output_list = ['{0:.2f}'.format(float(x)) for x in
                        output.numpy()[0]]
        print(output_list)
        cv2.putText(image, str(output_list)+'=>'+label, (x, y+h+30),
                            font_face, font_scale,
                            color, thickness, 2)
                # draw box over face
        cv2.rectangle(image, (x, y), (x + w, y + h), color, 2)

        print(x,y,w,h,label)
        draw.juxing((x, y, x+w, y+h),1)
        #cv2.imshow('DeepFake Detect', image)
        #cv2.waitKey(10)  # About 30 fps
        return label
    else:
        draw.juxing((100, 100, 500, 500),1)
        return 'noface'

    print("done")

def init_session():
    '''
    Initialize NPU
    :return: NPU session
    '''

    quantized_model_path = 'model_df_1.onnx'
    model = onnx.load(quantized_model_path)

    path = r'voe-4.0-win_amd64'
    providers = ['VitisAIExecutionProvider']
    cache_dir = Path(__file__).parent.resolve()
    provider_options = [{
                    'config_file': os.path.join('..', path, 'vaip_config.json'),
                    'cacheDir': str(cache_dir),
                    'cacheKey': 'quickstart_modelcachekey'
                }]

    session = ort.InferenceSession(model.SerializeToString(), providers=providers,
                                provider_options=provider_options)
    return session

def df(session):
    '''
    mian program
    :param session:NPU session
    '''

    count = 0
    res = []
    global flag
    while(count<3):
        img = pyautogui.screenshot(region=None) # x,y,w,h
        # img.save('screenshot.png')
        img = cv2.cvtColor(np.asarray(img),cv2.COLOR_RGB2BGR)
        lab = detect(img,session)
        res.append(lab)
        count = count + 1
    resmax = max(res,key=res.count)
    print(resmax)

    from win11toast import toast
    if resmax=='fake':
        toast('Deepfake Detect', 'The face maybe fake!',icon='C:/zhaoshuang/app/icon.ico',duration='2000')
    
    elif resmax=='noface':
        toast('Deepfake Detect', 'Not detect face',icon='C:/zhaoshuang/app/icon.ico',duration='2000')

    session = None

    flag = 1

dfsecurity.py

Python
Packaged as an application
import sys

from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QMenu, QAction, QMessageBox
import dfdetect

# Create application objects
app = QApplication(sys.argv)

# Create a system tray icon object
tray_icon = QSystemTrayIcon()

# Create tray icon menu
tray_menu = QMenu()
action_quit = QAction("exit", triggered=app.quit)
tray_menu.addAction(action_quit)

# Set menu to tray icon
tray_icon.setContextMenu(tray_menu)

# Set default icons for tray icons
default_icon = QIcon("01.jpg")
tray_icon.setIcon(default_icon)

# Set mouse prompts for tray icons
tray_icon.setToolTip("Double Click to start deepfake detection")


tray_icon.show()
session = dfdetect.init_session()

# Double click event handling function
def show_message_box(reason):
    if reason == QSystemTrayIcon.DoubleClick and dfdetect.flag == 1:
        #QMessageBox.information(None, "", "")
        print("double click")
        dfdetect.flag = 0
        dfdetect.df(session)
        print("show_message_box")


# Add a listener for double-click events
tray_icon.activated.connect(show_message_box)
app.setQuitOnLastWindowClosed(False)

# Running the application
sys.exit(app.exec_())

dfsecurity.exe

Python
You can run the EXE file directly and put 01.jpg and model_df_1.onnx in the same folder
No preview (download only).

logo

You can run the EXE file directly and put 01.jpg and model_df_1.onnx in the same folder

Credits

zhaoshuang
1 project • 0 followers

Comments