File size: 5,420 Bytes
99c30b7 342ea4d 9358900 56225c5 bd55878 9c93e59 9358900 342ea4d bd55878 9358900 bd55878 9358900 342ea4d 9358900 bd55878 342ea4d 9358900 342ea4d bd55878 9358900 342ea4d 9358900 342ea4d 9358900 342ea4d 9358900 342ea4d bd55878 9358900 bd55878 56225c5 bd55878 56225c5 342ea4d bd55878 342ea4d bd55878 342ea4d 56225c5 9c93e59 342ea4d 9358900 342ea4d 9358900 342ea4d bd55878 342ea4d 56225c5 bd55878 342ea4d 56225c5 342ea4d bd55878 99c30b7 9c93e59 99c30b7 342ea4d |
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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
import gradio as gr
from detector.face import verify_faces, analyze_face
from detector.voice import verify_voices
from detector.video import verify_faces_in_video
from reports.pdf_report import generate_pdf_report
from utils.youtube_utils import download_youtube_video
import modal
verify_faces_remote = modal.Function.lookup("deepface-agent", "verify_faces_remote")
# Holds latest results
last_face_result = None
last_voice_result = None
last_video_results = None
# @app.local_entrypoint()
def compare_faces(img1_path: str, img2_path: str) -> str:
"""Use this tool to compare to faces for a match
Args:
img1_path: The path to the first image
img2_path: The path to the second image
"""
global last_face_result
# Read image files as bytes
with open(img1_path, "rb") as f1, open(img2_path, "rb") as f2:
img1_bytes = f1.read()
img2_bytes = f2.read()
result = verify_faces_remote.remote(img1_bytes, img2_bytes)
result_text = ""
if "error" in result:
return f"โ Error: {result['error']}"
if result["verified"]:
result_text = f"โ
Match! Distance: {result['distance']:.4f} (Threshold: {result['threshold']})"
last_face_result = result_text
return result_text
else:
result_text = f"โ No Match. Distance: {result['distance']:.4f} (Threshold: {result['threshold']})"
last_face_result = result_text
return result_text
def compare_voices(audio1: str, audio2: str) -> str:
"""Use this tool to compare two voices for a match
Args:
audio1: The path to the first audio file
audio2: The path to the second audio file
"""
global last_voice_result
result = verify_voices(audio1, audio2)
result_text = ""
if "error" in result:
return f"โ Error: {result['error']}"
if result["match"]:
result_text = f"โ
Same speaker detected. Similarity: {result['similarity']} (Threshold: {result['threshold']})"
last_voice_result = result_text
return result_text
else:
result_text = f"โ Different speakers. Similarity: {result['similarity']} (Threshold: {result['threshold']})"
last_voice_result = result_text
return result_text
def scan_video(video_file: str, ref_img: str, youtube_url="") -> str:
"""Use this tool to scan a video for deepfake face swaps
Args:
video_file: The path to the video file
ref_img: The path to the reference image
youtube_url: The YouTube URL (optional)
"""
global last_video_results
if youtube_url:
try:
video_file = download_youtube_video(youtube_url)
except Exception as e:
return f"โ Error downloading YouTube video: {str(e)}"
results = verify_faces_in_video(video_file, ref_img)
report = ""
last_video_results = results
for r in results:
if "error" in r:
report += f"\nโ ๏ธ Frame {r['frame']}: {r['error']}"
else:
status = "โ
Match" if r["verified"] else "โ Mismatch"
report += f"\n๐ผ Frame {r['frame']}: {status} (Distance: {r['distance']})"
return report
def generate_report():
return generate_pdf_report(last_face_result, last_voice_result, last_video_results)
with gr.Blocks(title="Deepfake Watchdog") as demo:
gr.Markdown("# ๐ก๏ธDeepfake Watchdog ๐ค")
gr.Markdown("## Upload your image and/or voice to scan for deepfake misuse online.")
# Face Verification
with gr.Tab("Face Verification"):
image1 = gr.Image(label="Upload your face", type="filepath")
# audio = gr.Audio(label="Upload your voice (optional)", type="filepath")
image2 = gr.Image(label="Upload another face", type="filepath")
# face_btn = gr.Button("Compare Faces")
run_button = gr.Button("Compare Faces")
output_text = gr.Textbox(label="Result")
# output_gallery = gr.Gallery(label="Matched Results")
run_button.click(compare_faces, inputs=[image1, image2], outputs=[output_text])
# Voice Verification
with gr.Tab("๐ค Voice Verification"):
gr.Markdown("Upload two audio files to check if the voices match.")
audio1 = gr.Audio(type="filepath", label="Voice Sample 1")
audio2 = gr.Audio(type="filepath", label="Voice Sample 2")
voice_btn = gr.Button("Compare Voices")
voice_output = gr.Textbox(label="Result")
voice_btn.click(compare_voices, inputs=[audio1, audio2], outputs=voice_output)
with gr.Tab("๐น Video Deepfake Scan"):
gr.Markdown(
"๐ Upload a video or paste a YouTube link and we'll analyze it for deepfake face swaps."
)
ref_img = gr.Image(type="filepath", label="Reference Face")
video_input = gr.Video(label="Video File (optional)")
youtube_url = gr.Textbox(label="YouTube URL (optional)")
scan_btn = gr.Button("Scan Video")
scan_output = gr.Textbox(label="Scan Results", lines=10)
scan_btn.click(
scan_video, inputs=[video_input, ref_img, youtube_url], outputs=scan_output
)
with gr.Tab("๐ Generate Report"):
report_btn = gr.Button("Generate PDF Report")
report_output = gr.File(label="Download Report")
report_btn.click(generate_report, outputs=report_output)
demo.launch(mcp_server=True)
|