Abraham E. Tavarez commited on
Commit
9358900
Β·
1 Parent(s): e2d190f

report generated

Browse files
Files changed (4) hide show
  1. app.py +34 -15
  2. pyproject.toml +1 -0
  3. report/report.py +0 -57
  4. uv.lock +8 -0
app.py CHANGED
@@ -2,52 +2,68 @@ import gradio as gr
2
  from detector.face import verify_faces, analyze_face
3
  from detector.voice import verify_voices
4
  from detector.video import verify_faces_in_video
5
- from report.report import generate_pdf_report
6
 
7
  # Holds latest results
8
  last_face_result = None
9
  last_voice_result = None
10
- last_video_results = []
11
 
12
 
13
  def start_scan(image, audio):
14
  return "Scanning in progress...", None
15
 
16
  def compare_faces(img1_path, img2_path):
 
17
  result = verify_faces(img1_path, img2_path)
 
18
 
19
  if "error" in result:
20
  return f"❌ Error: {result['error']}"
21
 
22
  if result["verified"]:
23
- return f"βœ… Match! Distance: {result['distance']:.4f} (Threshold: {result['threshold']})"
 
 
 
24
  else:
25
- return f"❌ No Match. Distance: {result['distance']:.4f} (Threshold: {result['threshold']})"
 
 
26
 
27
 
28
  def compare_voices(audio1, audio2):
 
29
  result = verify_voices(audio1, audio2)
 
30
 
31
  if "error" in result:
32
  return f"❌ Error: {result['error']}"
33
 
34
  if result["match"]:
35
- return f"βœ… Same speaker detected. Similarity: {result['similarity']} (Threshold: {result['threshold']})"
 
 
36
  else:
37
- return f"❌ Different speakers. Similarity: {result['similarity']} (Threshold: {result['threshold']})"
 
 
38
 
39
 
40
  def scan_video(video_path, ref_img):
 
41
  results = verify_faces_in_video(video_path, ref_img)
42
  report = ""
43
-
44
  for r in results:
45
  if "error" in r:
46
  report += f"\n⚠️ Frame {r['frame']}: {r['error']}"
 
47
  else:
48
  status = "βœ… Match" if r["verified"] else "❌ Mismatch"
49
  report += f"\nπŸ–Ό Frame {r['frame']}: {status} (Distance: {r['distance']})"
50
 
 
51
  return report
52
 
53
  def generate_report():
@@ -61,16 +77,19 @@ with gr.Blocks(title="Deepfake Watchdog") as demo:
61
  # Face Verification
62
  gr.Markdown("### πŸ“· Face Verification")
63
  with gr.Tab("Face Verification"):
64
- image = gr.Image(label="Upload your face", type="filepath")
65
- audio = gr.Audio(label="Upload your voice (optional)", type="filepath")
 
 
 
66
 
67
- run_button = gr.Button("Start Scan")
68
- output_text = gr.Textbox(label="Status")
69
- output_gallery = gr.Gallery(label="Matched Results")
70
 
71
- run_button.click(
72
- start_scan, inputs=[image, audio], outputs=[output_text, output_gallery]
73
- )
74
 
75
  # Voice Verification
76
  gr.Markdown("### 🎀 Voice Verification")
 
2
  from detector.face import verify_faces, analyze_face
3
  from detector.voice import verify_voices
4
  from detector.video import verify_faces_in_video
5
+ from reports.pdf_report import generate_pdf_report
6
 
7
  # Holds latest results
8
  last_face_result = None
9
  last_voice_result = None
10
+ last_video_results = None
11
 
12
 
13
  def start_scan(image, audio):
14
  return "Scanning in progress...", None
15
 
16
  def compare_faces(img1_path, img2_path):
17
+ global last_face_result
18
  result = verify_faces(img1_path, img2_path)
19
+ result_text = ""
20
 
21
  if "error" in result:
22
  return f"❌ Error: {result['error']}"
23
 
24
  if result["verified"]:
25
+ result_text = f"βœ… Match! Distance: {result['distance']:.4f} (Threshold: {result['threshold']})"
26
+ last_face_result = result_text
27
+ return result_text
28
+
29
  else:
30
+ result_text = f"❌ No Match. Distance: {result['distance']:.4f} (Threshold: {result['threshold']})"
31
+ last_face_result = result_text
32
+ return result_text
33
 
34
 
35
  def compare_voices(audio1, audio2):
36
+ global last_voice_result
37
  result = verify_voices(audio1, audio2)
38
+ result_text = ""
39
 
40
  if "error" in result:
41
  return f"❌ Error: {result['error']}"
42
 
43
  if result["match"]:
44
+ result_text = f"βœ… Same speaker detected. Similarity: {result['similarity']} (Threshold: {result['threshold']})"
45
+ last_voice_result = result_text
46
+ return result_text
47
  else:
48
+ result_text = f"❌ Different speakers. Similarity: {result['similarity']} (Threshold: {result['threshold']})"
49
+ last_voice_result = result_text
50
+ return result_text
51
 
52
 
53
  def scan_video(video_path, ref_img):
54
+ global last_video_results
55
  results = verify_faces_in_video(video_path, ref_img)
56
  report = ""
57
+ last_video_results = results
58
  for r in results:
59
  if "error" in r:
60
  report += f"\n⚠️ Frame {r['frame']}: {r['error']}"
61
+ # last_video_results.append(report)
62
  else:
63
  status = "βœ… Match" if r["verified"] else "❌ Mismatch"
64
  report += f"\nπŸ–Ό Frame {r['frame']}: {status} (Distance: {r['distance']})"
65
 
66
+ # last_video_results.append(report)
67
  return report
68
 
69
  def generate_report():
 
77
  # Face Verification
78
  gr.Markdown("### πŸ“· Face Verification")
79
  with gr.Tab("Face Verification"):
80
+ image1 = gr.Image(label="Upload your face", type="filepath")
81
+ # audio = gr.Audio(label="Upload your voice (optional)", type="filepath")
82
+ image2 = gr.Image(label="Upload another face", type="filepath")
83
+
84
+ # face_btn = gr.Button("Compare Faces")
85
 
86
+ run_button = gr.Button("Compare Faces")
87
+ output_text = gr.Textbox(label="Result")
88
+ # output_gallery = gr.Gallery(label="Matched Results")
89
 
90
+ run_button.click(
91
+ compare_faces, inputs=[image1, image2], outputs=[output_text]
92
+ )
93
 
94
  # Voice Verification
95
  gr.Markdown("### 🎀 Voice Verification")
pyproject.toml CHANGED
@@ -6,6 +6,7 @@ readme = "README.md"
6
  requires-python = ">=3.12"
7
  dependencies = [
8
  "deepface>=0.0.93",
 
9
  "gradio[mcp]>=5.32.1",
10
  "opencv-python-headless>=4.11.0.86",
11
  "pydub>=0.25.1",
 
6
  requires-python = ">=3.12"
7
  dependencies = [
8
  "deepface>=0.0.93",
9
+ "fpdf>=1.7.2",
10
  "gradio[mcp]>=5.32.1",
11
  "opencv-python-headless>=4.11.0.86",
12
  "pydub>=0.25.1",
report/report.py DELETED
@@ -1,57 +0,0 @@
1
- from fpdf import FPDF
2
- import os
3
- import datetime
4
-
5
- class ReportGenerator(FPDF):
6
- def header(self):
7
- self.set_font("Arial", "B", 16)
8
- self.cell(0, 10, "Deepfake Watchdog Report", ln=1, align="C")
9
- self.ln(5)
10
-
11
- def add_section_title(self, title):
12
- self.set_font("Arial", "B", 12)
13
- self.cell(0, 10, title, ln=1, align="L")
14
- self.ln(2)
15
-
16
- def add_text(self, text):
17
- self.set_font("Arial", "", 12)
18
- self.multi_cell(0, 8, text)
19
- self.ln(2)
20
-
21
- def add_image(self, image_path, w=60):
22
- if os.path.exists(image_path):
23
- self.image(image_path, w=w)
24
- self.ln(5)
25
- else:
26
- print(f"Image not found: {image_path}")
27
-
28
- # Generate PDF Report
29
- def generate_pdf_report(face_result, voice_result, video_results, output_path=f"report{datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.pdf"):
30
- pdf = ReportGenerator()
31
- pdf.add_page()
32
-
33
- # Section 1: Face Verification
34
- pdf.add_section_title("Face Verification Results")
35
- pdf.add_text(face_result)
36
-
37
- # Section 2: Voice Verification
38
- pdf.add_section_title("Voice Verification Results")
39
- pdf.add_text(voice_result)
40
-
41
- # Section 3: Video Verification
42
- pdf.add_section_title("Video Verification Results")
43
-
44
- for frame in video_results:
45
- if "error" in frame:
46
- pdf.add_text(f"{frame['frame']}: ERROR - {frame['error']}")
47
- else:
48
- status = "βœ… Match" if frame["verified"] else "❌ Mismatch"
49
- pdf.add_text(f"{frame['frame']} - {status} (Distance: {frame['distance']})")
50
-
51
- if not frame["verified"]:
52
- pdf.add_image(frame["frame"], w=80)
53
-
54
- pdf.output(output_path)
55
- print(f"PDF report generated at: {output_path}")
56
- return output_path
57
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
uv.lock CHANGED
@@ -274,6 +274,7 @@ version = "0.1.0"
274
  source = { virtual = "." }
275
  dependencies = [
276
  { name = "deepface" },
 
277
  { name = "gradio", extra = ["mcp"] },
278
  { name = "opencv-python-headless" },
279
  { name = "pydub" },
@@ -284,6 +285,7 @@ dependencies = [
284
  [package.metadata]
285
  requires-dist = [
286
  { name = "deepface", specifier = ">=0.0.93" },
 
287
  { name = "gradio", extras = ["mcp"], specifier = ">=5.32.1" },
288
  { name = "opencv-python-headless", specifier = ">=4.11.0.86" },
289
  { name = "pydub", specifier = ">=0.25.1" },
@@ -371,6 +373,12 @@ wheels = [
371
  { url = "https://files.pythonhosted.org/packages/b8/25/155f9f080d5e4bc0082edfda032ea2bc2b8fab3f4d25d46c1e9dd22a1a89/flatbuffers-25.2.10-py2.py3-none-any.whl", hash = "sha256:ebba5f4d5ea615af3f7fd70fc310636fbb2bbd1f566ac0a23d98dd412de50051", size = 30953, upload-time = "2025-02-11T04:26:44.484Z" },
372
  ]
373
 
 
 
 
 
 
 
374
  [[package]]
375
  name = "fsspec"
376
  version = "2025.5.1"
 
274
  source = { virtual = "." }
275
  dependencies = [
276
  { name = "deepface" },
277
+ { name = "fpdf" },
278
  { name = "gradio", extra = ["mcp"] },
279
  { name = "opencv-python-headless" },
280
  { name = "pydub" },
 
285
  [package.metadata]
286
  requires-dist = [
287
  { name = "deepface", specifier = ">=0.0.93" },
288
+ { name = "fpdf", specifier = ">=1.7.2" },
289
  { name = "gradio", extras = ["mcp"], specifier = ">=5.32.1" },
290
  { name = "opencv-python-headless", specifier = ">=4.11.0.86" },
291
  { name = "pydub", specifier = ">=0.25.1" },
 
373
  { url = "https://files.pythonhosted.org/packages/b8/25/155f9f080d5e4bc0082edfda032ea2bc2b8fab3f4d25d46c1e9dd22a1a89/flatbuffers-25.2.10-py2.py3-none-any.whl", hash = "sha256:ebba5f4d5ea615af3f7fd70fc310636fbb2bbd1f566ac0a23d98dd412de50051", size = 30953, upload-time = "2025-02-11T04:26:44.484Z" },
374
  ]
375
 
376
+ [[package]]
377
+ name = "fpdf"
378
+ version = "1.7.2"
379
+ source = { registry = "https://pypi.org/simple" }
380
+ sdist = { url = "https://files.pythonhosted.org/packages/37/c6/608a9e6c172bf9124aa687ec8b9f0e8e5d697d59a5f4fad0e2d5ec2a7556/fpdf-1.7.2.tar.gz", hash = "sha256:125840783289e7d12552b1e86ab692c37322e7a65b96a99e0ea86cca041b6779", size = 39504, upload-time = "2015-01-21T00:07:47.493Z" }
381
+
382
  [[package]]
383
  name = "fsspec"
384
  version = "2025.5.1"