seifbenayed commited on
Commit
817736f
Β·
1 Parent(s): 8ecb82d
PoseEfficientNet_custom_laanet_model_final.pth DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:2d7cc177dd24ae429b74a651d38754ba05eb6552cc02cfe84ed0be305dc297ac
3
- size 217985170
 
 
 
 
app.py CHANGED
@@ -2,18 +2,6 @@
2
  import importlib.util
3
  import os
4
  import sys
5
-
6
-
7
- # Check if detectron2 is installed
8
- if importlib.util.find_spec("detectron2") is None:
9
- print("Installing PyTorch and Detectron2...")
10
- os.system("pip install torch torchvision --extra-index-url https://download.pytorch.org/whl/cpu")
11
- os.system("pip install git+https://github.com/facebookresearch/detectron2.git")
12
- print("Installation complete!")
13
-
14
- #!/usr/bin/env python3
15
- import os
16
- import sys
17
  import time
18
  import cv2
19
  import torch
@@ -21,14 +9,21 @@ import numpy as np
21
  import gradio as gr
22
  from PIL import Image
23
  from torchvision import transforms
 
 
24
  import traceback
25
- from configs.get_config import load_config
26
- from models import *
27
 
28
  # Add current directory to path
29
  if not os.getcwd() in sys.path:
30
  sys.path.append(os.getcwd())
31
 
 
 
 
 
 
 
 
32
  # Check for detectron2
33
  try:
34
  from detectron2.engine import DefaultPredictor
@@ -40,24 +35,14 @@ except ImportError:
40
  print("Warning: Detectron2 is not installed. Damage detection will not be available.")
41
  DETECTRON2_AVAILABLE = False
42
 
43
- # Check for custom models
44
- try:
45
-
46
- MODELS_IMPORTED = True
47
- except ImportError:
48
- print("Warning: Custom models couldn't be imported. Only damage detection will work.")
49
- MODELS_IMPORTED = False
50
-
51
  # Define model paths
52
  DEFAULT_DAMAGE_MODEL_PATH = "./model_final.pth"
53
- DEFAULT_DEEPFAKE_MODEL_PATH = "./PoseEfficientNet_custom_laanet_model_final.pth"
54
- DEFAULT_DEEPFAKE_CFG_PATH = "./configs/detector2.yaml"
55
 
56
  # Sample images for demo (add your own paths)
57
  SAMPLE_IMAGES = [
58
  "./test3.png",
59
  "./test5.png",
60
-
61
  ]
62
 
63
  def verify_detectron2_installation():
@@ -146,49 +131,43 @@ def setup_damage_detector(model_path, threshold=0.7):
146
  traceback.print_exc()
147
  return None, None
148
 
149
- def load_deepfake_model(model_path, cfg_path, device):
150
- """Load the deepfake detection model"""
151
- if not MODELS_IMPORTED:
152
- print("Custom models module not imported. Cannot load deepfake model.")
153
- return None, None
154
-
155
  if model_path is None or not os.path.exists(model_path):
156
- print(f"Error: Deepfake model file not found at {model_path}")
157
- return None, None
158
-
159
- if cfg_path is None or not os.path.exists(cfg_path):
160
- print(f"Error: Deepfake config file not found at {cfg_path}")
161
- return None, None
162
 
163
  try:
164
- # Load config
165
- cfg = load_config(cfg_path)
166
 
167
- # Build model
168
- model = build_model(cfg.MODEL, MODELS)
 
169
 
170
  # Load weights
 
171
  checkpoint = torch.load(model_path, map_location='cpu')
172
 
173
- if isinstance(checkpoint, dict) and 'state_dict' in checkpoint:
 
 
174
  model.load_state_dict(checkpoint['state_dict'])
175
  else:
176
  model.load_state_dict(checkpoint)
177
 
178
  # Move model to device and set to evaluation mode
179
  model = model.to(device)
180
- if hasattr(cfg.MODEL, 'precision') and cfg.MODEL.precision == 'fp64':
181
- model = model.to(torch.float64)
182
  model.eval()
183
 
184
- return model, cfg
185
  except Exception as e:
186
- print(f"Error loading deepfake model: {e}")
187
  traceback.print_exc()
188
- return None, None
189
 
190
- def preprocess_for_deepfake(image, cfg, device):
191
- """Preprocess an image for deepfake detection"""
192
  try:
193
  # Ensure image is RGB
194
  if len(image.shape) == 3 and image.shape[2] == 3:
@@ -198,28 +177,21 @@ def preprocess_for_deepfake(image, cfg, device):
198
  else:
199
  rgb_img = image
200
 
201
- # Resize to match model input size
202
- img_resized = cv2.resize(rgb_img, (cfg.DATASET.IMAGE_SIZE[0], cfg.DATASET.IMAGE_SIZE[1]))
203
 
204
  # Apply transforms
205
  transform = transforms.Compose([
206
  transforms.ToTensor(),
207
- transforms.Normalize(
208
- mean=cfg.DATASET.TRANSFORM.normalize.mean,
209
- std=cfg.DATASET.TRANSFORM.normalize.std
210
- )
211
  ])
212
 
213
  img_tensor = transform(Image.fromarray(img_resized)).unsqueeze(0)
214
  img_tensor = img_tensor.to(device)
215
 
216
- # Convert precision if needed
217
- if hasattr(cfg.MODEL, 'precision') and cfg.MODEL.precision == 'fp64':
218
- img_tensor = img_tensor.to(torch.float64)
219
-
220
  return img_tensor
221
  except Exception as e:
222
- print(f"Error preprocessing image: {e}")
223
  traceback.print_exc()
224
  return None
225
 
@@ -282,8 +254,8 @@ def detect_damage(img, damage_detector):
282
  return img, None, damage_regions
283
  return None, None, []
284
 
285
- def check_deepfake(image, damage_regions, deepfake_model, deepfake_cfg, device, threshold=0.5):
286
- """Check if damage regions are deepfakes"""
287
  results = []
288
 
289
  if deepfake_model is None:
@@ -292,7 +264,7 @@ def check_deepfake(image, damage_regions, deepfake_model, deepfake_cfg, device,
292
  try:
293
  # If no damage regions, check entire image
294
  if not damage_regions:
295
- img_tensor = preprocess_for_deepfake(image, deepfake_cfg, device)
296
  if img_tensor is None:
297
  return []
298
 
@@ -300,25 +272,16 @@ def check_deepfake(image, damage_regions, deepfake_model, deepfake_cfg, device,
300
  with torch.no_grad():
301
  outputs = deepfake_model(img_tensor)
302
 
303
- # Extract outputs
304
- if isinstance(outputs, list):
305
- outputs = outputs[0]
 
306
 
307
- if isinstance(outputs, dict) and 'cls' in outputs:
308
- cls_outputs = outputs['cls']
309
- cls_prob = cls_outputs.sigmoid().cpu().numpy()
310
- else:
311
- cls_prob = outputs.sigmoid().cpu().numpy() if hasattr(outputs, 'sigmoid') else outputs.cpu().numpy()
312
-
313
- if cls_prob.size > 0:
314
- is_fake = cls_prob[0][0] > threshold if cls_prob.ndim > 1 else cls_prob[0] > threshold
315
- confidence = cls_prob[0][0] if cls_prob.ndim > 1 else cls_prob[0]
316
-
317
- results.append({
318
- "region": "full_image",
319
- "deepfake_prob": float(confidence),
320
- "is_fake": bool(is_fake)
321
- })
322
 
323
  return results
324
 
@@ -334,7 +297,7 @@ def check_deepfake(image, damage_regions, deepfake_model, deepfake_cfg, device,
334
  roi = image[y1:y2, x1:x2]
335
 
336
  # Preprocess
337
- img_tensor = preprocess_for_deepfake(roi, deepfake_cfg, device)
338
  if img_tensor is None:
339
  continue
340
 
@@ -342,25 +305,17 @@ def check_deepfake(image, damage_regions, deepfake_model, deepfake_cfg, device,
342
  with torch.no_grad():
343
  outputs = deepfake_model(img_tensor)
344
 
345
- if isinstance(outputs, list):
346
- outputs = outputs[0]
347
-
348
- if isinstance(outputs, dict) and 'cls' in outputs:
349
- cls_outputs = outputs['cls']
350
- cls_prob = cls_outputs.sigmoid().cpu().numpy()
351
- else:
352
- cls_prob = outputs.sigmoid().cpu().numpy() if hasattr(outputs, 'sigmoid') else outputs.cpu().numpy()
353
 
354
- if cls_prob.size > 0:
355
- is_fake = cls_prob[0][0] > threshold if cls_prob.ndim > 1 else cls_prob[0] > threshold
356
- confidence = cls_prob[0][0] if cls_prob.ndim > 1 else cls_prob[0]
357
-
358
- results.append({
359
- "region_id": i,
360
- "box": (x1, y1, x2, y2),
361
- "deepfake_prob": float(confidence),
362
- "is_fake": bool(is_fake)
363
- })
364
 
365
  return results
366
  except Exception as e:
@@ -428,23 +383,18 @@ def visualize_results(image, damage_outputs, deepfake_results, damage_threshold)
428
  traceback.print_exc()
429
  return np.array(image, dtype=np.uint8)
430
 
431
- def process_image(input_image, damage_model_path, deepfake_model_path, deepfake_cfg_path,
432
- damage_threshold, deepfake_threshold, skip_damage, device_str):
433
  """Process an image through the detection pipeline"""
434
  progress_info = []
435
 
436
- # Debug: log input parameters
437
-
438
  # Check model files
439
  if not skip_damage and damage_model_path:
440
  if not os.path.exists(damage_model_path):
441
  progress_info.append(f"ERROR: Damage model not found at {damage_model_path}")
442
 
443
  if deepfake_model_path and not os.path.exists(deepfake_model_path):
444
- progress_info.append(f"ERROR: Deepfake model not found at {deepfake_model_path}")
445
-
446
- if deepfake_cfg_path and not os.path.exists(deepfake_cfg_path):
447
- progress_info.append(f"ERROR: Config not found at {deepfake_cfg_path}")
448
 
449
  # Convert image to proper format
450
  try:
@@ -464,40 +414,55 @@ def process_image(input_image, damage_model_path, deepfake_model_path, deepfake_
464
  except Exception as e:
465
  return None, f"Error loading image: {str(e)}"
466
 
467
-
468
  # Setup device
469
  device = setup_device(device_str)
 
470
 
471
  # Initialize models
472
  damage_detector = None
473
  deepfake_model = None
474
- deepfake_cfg = None
475
 
476
  # Setup damage detector
477
  if not skip_damage and damage_model_path:
 
478
  damage_detector, _ = setup_damage_detector(damage_model_path, float(damage_threshold))
479
-
480
- # Setup deepfake detector
481
- if deepfake_model_path and deepfake_cfg_path:
482
- deepfake_model, deepfake_cfg = load_deepfake_model(deepfake_model_path, deepfake_cfg_path, device)
483
-
 
 
 
 
 
 
 
 
484
 
485
  # Step 1: Detect damage
 
486
  start_time = time.time()
487
  img, damage_outputs, damage_regions = detect_damage(img, damage_detector)
488
  damage_time = time.time() - start_time
489
 
490
-
491
- # Step 2: Check for deepfakes
 
 
 
 
492
  deepfake_results = []
493
  if deepfake_model is not None:
 
494
  start_time = time.time()
495
- deepfake_results = check_deepfake(
496
- img, damage_regions, deepfake_model, deepfake_cfg, device, float(deepfake_threshold)
497
  )
498
  deepfake_time = time.time() - start_time
499
 
500
  if deepfake_results:
 
501
 
502
  # Generate report
503
  for result in deepfake_results:
@@ -505,17 +470,21 @@ def process_image(input_image, damage_model_path, deepfake_model_path, deepfake_
505
  region_id = result["region_id"]
506
  fake_prob = result["deepfake_prob"]
507
  is_fake = result["is_fake"]
 
508
  elif "region" in result and result["region"] == "full_image":
509
  fake_prob = result["deepfake_prob"]
510
  is_fake = result["is_fake"]
 
511
  else:
512
  progress_info.append("No deepfake detection results")
513
 
 
514
  fake_regions = [r for r in deepfake_results if r.get("is_fake", False)]
515
  if fake_regions:
516
  progress_info.append("\n🚨 VERDICT: This image contains FAKE damage 🚨")
517
  else:
518
  progress_info.append("\nβœ… VERDICT: All damage appears REAL")
 
519
  # Step 3: Visualize results
520
  result_img = visualize_results(img, damage_outputs, deepfake_results, float(damage_threshold))
521
 
@@ -523,7 +492,6 @@ def process_image(input_image, damage_model_path, deepfake_model_path, deepfake_
523
  if len(result_img.shape) == 3 and result_img.shape[2] == 3:
524
  result_img = cv2.cvtColor(result_img, cv2.COLOR_BGR2RGB)
525
 
526
-
527
  return result_img, "\n".join(progress_info)
528
 
529
  def auto_install_dependencies():
@@ -561,13 +529,13 @@ def create_gradio_interface():
561
 
562
  with gr.Blocks(title="Car Damage & Deepfake Detector", theme=theme) as app:
563
  gr.Markdown("""
564
- # πŸš— Car Damage fraud Detector
565
 
566
  Upload a car image to:
567
  1. Detect damaged areas
568
  2. Verify if the damage is real or artificially generated (deepfake)
569
 
570
- *This app requires both damage detection and deepfake models to be installed.*
571
  """)
572
 
573
  # Main Interface Tab
@@ -620,6 +588,7 @@ def create_gradio_interface():
620
  output.append(f"**CUDA Available:** {'Yes βœ…' if torch.cuda.is_available() else 'No ❌'}")
621
  if torch.cuda.is_available():
622
  output.append(f"**GPU:** {torch.cuda.get_device_name(0)}")
 
623
  except ImportError:
624
  output.append("**PyTorch:** Not installed ❌")
625
 
@@ -634,14 +603,9 @@ def create_gradio_interface():
634
 
635
  if os.path.exists(DEFAULT_DEEPFAKE_MODEL_PATH):
636
  file_size = os.path.getsize(DEFAULT_DEEPFAKE_MODEL_PATH) / (1024 * 1024) # Size in MB
637
- output.append(f"**Deepfake Model:** Available βœ… ({file_size:.2f} MB)")
638
  else:
639
- output.append(f"**Deepfake Model:** Not found ❌ at {DEFAULT_DEEPFAKE_MODEL_PATH}")
640
-
641
- if os.path.exists(DEFAULT_DEEPFAKE_CFG_PATH):
642
- output.append(f"**Deepfake Config:** Available βœ…")
643
- else:
644
- output.append(f"**Deepfake Config:** Not found ❌ at {DEFAULT_DEEPFAKE_CFG_PATH}")
645
 
646
  output.append("\n## Detectron2 Status")
647
  output.append(f"**Installed:** {'Yes βœ…' if detectron2_results['detectron2_installed'] else 'No ❌'}")
@@ -664,10 +628,7 @@ def create_gradio_interface():
664
  recommendations.append(f"Place the damage model file at: {DEFAULT_DAMAGE_MODEL_PATH}")
665
 
666
  if not os.path.exists(DEFAULT_DEEPFAKE_MODEL_PATH):
667
- recommendations.append(f"Place the deepfake model file at: {DEFAULT_DEEPFAKE_MODEL_PATH}")
668
-
669
- if not os.path.exists(DEFAULT_DEEPFAKE_CFG_PATH):
670
- recommendations.append(f"Place the deepfake config file at: {DEFAULT_DEEPFAKE_CFG_PATH}")
671
 
672
  if recommendations:
673
  for rec in recommendations:
@@ -708,7 +669,7 @@ def create_gradio_interface():
708
 
709
  return "\n".join(output)
710
 
711
- # Settings Tab
712
  with gr.Tab("Settings"):
713
  gr.Markdown("## Model Settings")
714
 
@@ -721,49 +682,16 @@ def create_gradio_interface():
721
  )
722
 
723
  custom_deepfake_model = gr.Textbox(
724
- label="Custom Deepfake Model Path",
725
  value=DEFAULT_DEEPFAKE_MODEL_PATH,
726
- placeholder="Path to deepfake detection model (.pth)"
727
- )
728
-
729
- custom_deepfake_cfg = gr.Textbox(
730
- label="Custom Deepfake Config Path",
731
- value=DEFAULT_DEEPFAKE_CFG_PATH,
732
- placeholder="Path to deepfake model config (.yaml)"
733
  )
734
 
735
  check_paths_btn = gr.Button("Verify Paths", variant="primary")
736
 
737
  with gr.Column():
738
  paths_result = gr.Markdown(label="Path Verification Results")
739
-
740
- # Function to check model paths
741
- def check_model_paths(damage_path, deepfake_path, cfg_path):
742
- output = ["## Path Verification Results\n"]
743
-
744
- # Check damage model
745
- if os.path.exists(damage_path):
746
- file_size = os.path.getsize(damage_path) / (1024 * 1024) # Size in MB
747
- output.append(f"βœ… **Damage model:** Found at {damage_path} ({file_size:.2f} MB)")
748
- else:
749
- output.append(f"❌ **Damage model:** NOT found at {damage_path}")
750
-
751
- # Check deepfake model
752
- if os.path.exists(deepfake_path):
753
- file_size = os.path.getsize(deepfake_path) / (1024 * 1024) # Size in MB
754
- output.append(f"βœ… **Deepfake model:** Found at {deepfake_path} ({file_size:.2f} MB)")
755
- else:
756
- output.append(f"❌ **Deepfake model:** NOT found at {deepfake_path}")
757
-
758
- # Check deepfake config
759
- if os.path.exists(cfg_path):
760
- output.append(f"βœ… **Deepfake config:** Found at {cfg_path}")
761
- else:
762
- output.append(f"❌ **Deepfake config:** NOT found at {cfg_path}")
763
-
764
- return "\n".join(output)
765
-
766
- # Help Tab
767
  with gr.Tab("Help"):
768
  gr.Markdown("""
769
  ## πŸ“‹ How to Use This Tool
@@ -780,8 +708,12 @@ def create_gradio_interface():
780
 
781
  ### Requirements
782
  - Damage detection model file (Detectron2 Mask R-CNN)
783
- - Deepfake detection model file
784
- - Deepfake model configuration file
 
 
 
 
785
 
786
  ### Troubleshooting
787
  - If models aren't loading, check the "System Diagnostics" tab
@@ -793,7 +725,7 @@ def create_gradio_interface():
793
  - **Deepfake Threshold:** Higher values make the system more selective in flagging fakes
794
  - **Skip Damage Detection:** Analyze the entire image for deepfakes without damage detection
795
  """)
796
-
797
  # Examples
798
  if any(os.path.exists(img) for img in SAMPLE_IMAGES):
799
  gr.Markdown("## Example Images")
@@ -805,7 +737,7 @@ def create_gradio_interface():
805
  outputs=[output_image, output_text],
806
  fn=lambda x: process_image(
807
  x, DEFAULT_DAMAGE_MODEL_PATH, DEFAULT_DEEPFAKE_MODEL_PATH,
808
- DEFAULT_DEEPFAKE_CFG_PATH, 0.7, 0.5, False, "auto"
809
  ),
810
  cache_examples=True
811
  )
@@ -817,7 +749,6 @@ def create_gradio_interface():
817
  input_image,
818
  custom_damage_model,
819
  custom_deepfake_model,
820
- custom_deepfake_cfg,
821
  damage_threshold,
822
  deepfake_threshold,
823
  skip_damage,
@@ -849,16 +780,14 @@ def create_gradio_interface():
849
  # Settings tab
850
  check_paths_btn.click(
851
  fn=check_model_paths,
852
- inputs=[custom_damage_model, custom_deepfake_model, custom_deepfake_cfg],
853
  outputs=paths_result
854
  )
855
 
856
  return app
857
 
858
  if __name__ == "__main__":
859
- # Try to auto-install dependencies on startup
860
- auto_install_dependencies()
861
 
862
  # Create and launch the Gradio app
863
  app = create_gradio_interface()
864
- app.launch(share=False) # Set share=True to create a public link
 
2
  import importlib.util
3
  import os
4
  import sys
 
 
 
 
 
 
 
 
 
 
 
 
5
  import time
6
  import cv2
7
  import torch
 
9
  import gradio as gr
10
  from PIL import Image
11
  from torchvision import transforms
12
+ from torchvision.models import vit_b_16
13
+ import torch.nn as nn
14
  import traceback
 
 
15
 
16
  # Add current directory to path
17
  if not os.getcwd() in sys.path:
18
  sys.path.append(os.getcwd())
19
 
20
+ # Check if detectron2 is installed
21
+ if importlib.util.find_spec("detectron2") is None:
22
+ print("Installing PyTorch and Detectron2...")
23
+ os.system("pip install torch torchvision --extra-index-url https://download.pytorch.org/whl/cpu")
24
+ os.system("pip install git+https://github.com/facebookresearch/detectron2.git")
25
+ print("Installation complete!")
26
+
27
  # Check for detectron2
28
  try:
29
  from detectron2.engine import DefaultPredictor
 
35
  print("Warning: Detectron2 is not installed. Damage detection will not be available.")
36
  DETECTRON2_AVAILABLE = False
37
 
 
 
 
 
 
 
 
 
38
  # Define model paths
39
  DEFAULT_DAMAGE_MODEL_PATH = "./model_final.pth"
40
+ DEFAULT_DEEPFAKE_MODEL_PATH = "./vit_deepfake_best_20250422_222444.pth"
 
41
 
42
  # Sample images for demo (add your own paths)
43
  SAMPLE_IMAGES = [
44
  "./test3.png",
45
  "./test5.png",
 
46
  ]
47
 
48
  def verify_detectron2_installation():
 
131
  traceback.print_exc()
132
  return None, None
133
 
134
+ def load_vit_deepfake_model(model_path, device):
135
+ """Load the Vision Transformer (ViT) model for deepfake detection"""
 
 
 
 
136
  if model_path is None or not os.path.exists(model_path):
137
+ print(f"Error: ViT deepfake model file not found at {model_path}")
138
+ return None
 
 
 
 
139
 
140
  try:
141
+ # Create ViT model with binary classification head
142
+ model = vit_b_16(weights=None)
143
 
144
+ # Modify the classifier head for binary classification (real vs fake)
145
+ in_features = model.heads.head.in_features
146
+ model.heads.head = nn.Linear(in_features, 2)
147
 
148
  # Load weights
149
+ print(f"Loading ViT deepfake model from: {model_path}")
150
  checkpoint = torch.load(model_path, map_location='cpu')
151
 
152
+ if isinstance(checkpoint, dict) and 'model_state_dict' in checkpoint:
153
+ model.load_state_dict(checkpoint['model_state_dict'])
154
+ elif isinstance(checkpoint, dict) and 'state_dict' in checkpoint:
155
  model.load_state_dict(checkpoint['state_dict'])
156
  else:
157
  model.load_state_dict(checkpoint)
158
 
159
  # Move model to device and set to evaluation mode
160
  model = model.to(device)
 
 
161
  model.eval()
162
 
163
+ return model
164
  except Exception as e:
165
+ print(f"Error loading ViT deepfake model: {e}")
166
  traceback.print_exc()
167
+ return None
168
 
169
+ def preprocess_for_vit(image, device):
170
+ """Preprocess an image for Vision Transformer deepfake detection"""
171
  try:
172
  # Ensure image is RGB
173
  if len(image.shape) == 3 and image.shape[2] == 3:
 
177
  else:
178
  rgb_img = image
179
 
180
+ # Resize to standard ViT input size (224x224)
181
+ img_resized = cv2.resize(rgb_img, (224, 224))
182
 
183
  # Apply transforms
184
  transform = transforms.Compose([
185
  transforms.ToTensor(),
186
+ transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
 
 
 
187
  ])
188
 
189
  img_tensor = transform(Image.fromarray(img_resized)).unsqueeze(0)
190
  img_tensor = img_tensor.to(device)
191
 
 
 
 
 
192
  return img_tensor
193
  except Exception as e:
194
+ print(f"Error preprocessing image for ViT: {e}")
195
  traceback.print_exc()
196
  return None
197
 
 
254
  return img, None, damage_regions
255
  return None, None, []
256
 
257
+ def check_deepfake_vit(image, damage_regions, deepfake_model, device, threshold=0.5):
258
+ """Check if damage regions are deepfakes using ViT model"""
259
  results = []
260
 
261
  if deepfake_model is None:
 
264
  try:
265
  # If no damage regions, check entire image
266
  if not damage_regions:
267
+ img_tensor = preprocess_for_vit(image, device)
268
  if img_tensor is None:
269
  return []
270
 
 
272
  with torch.no_grad():
273
  outputs = deepfake_model(img_tensor)
274
 
275
+ # Get predictions
276
+ probabilities = torch.nn.functional.softmax(outputs, dim=1)
277
+ fake_prob = probabilities[0, 1].item() # Probability of being fake (class 1)
278
+ is_fake = fake_prob > threshold
279
 
280
+ results.append({
281
+ "region": "full_image",
282
+ "deepfake_prob": float(fake_prob),
283
+ "is_fake": bool(is_fake)
284
+ })
 
 
 
 
 
 
 
 
 
 
285
 
286
  return results
287
 
 
297
  roi = image[y1:y2, x1:x2]
298
 
299
  # Preprocess
300
+ img_tensor = preprocess_for_vit(roi, device)
301
  if img_tensor is None:
302
  continue
303
 
 
305
  with torch.no_grad():
306
  outputs = deepfake_model(img_tensor)
307
 
308
+ # Get predictions
309
+ probabilities = torch.nn.functional.softmax(outputs, dim=1)
310
+ fake_prob = probabilities[0, 1].item() # Probability of being fake (class 1)
311
+ is_fake = fake_prob > threshold
 
 
 
 
312
 
313
+ results.append({
314
+ "region_id": i,
315
+ "box": (x1, y1, x2, y2),
316
+ "deepfake_prob": float(fake_prob),
317
+ "is_fake": bool(is_fake)
318
+ })
 
 
 
 
319
 
320
  return results
321
  except Exception as e:
 
383
  traceback.print_exc()
384
  return np.array(image, dtype=np.uint8)
385
 
386
+ def process_image(input_image, damage_model_path, deepfake_model_path, damage_threshold,
387
+ deepfake_threshold, skip_damage, device_str):
388
  """Process an image through the detection pipeline"""
389
  progress_info = []
390
 
 
 
391
  # Check model files
392
  if not skip_damage and damage_model_path:
393
  if not os.path.exists(damage_model_path):
394
  progress_info.append(f"ERROR: Damage model not found at {damage_model_path}")
395
 
396
  if deepfake_model_path and not os.path.exists(deepfake_model_path):
397
+ progress_info.append(f"ERROR: ViT deepfake model not found at {deepfake_model_path}")
 
 
 
398
 
399
  # Convert image to proper format
400
  try:
 
414
  except Exception as e:
415
  return None, f"Error loading image: {str(e)}"
416
 
 
417
  # Setup device
418
  device = setup_device(device_str)
419
+ progress_info.append(f"Using device: {device}")
420
 
421
  # Initialize models
422
  damage_detector = None
423
  deepfake_model = None
 
424
 
425
  # Setup damage detector
426
  if not skip_damage and damage_model_path:
427
+ progress_info.append("Setting up damage detector...")
428
  damage_detector, _ = setup_damage_detector(damage_model_path, float(damage_threshold))
429
+ if damage_detector:
430
+ progress_info.append("βœ… Damage detector initialized")
431
+ else:
432
+ progress_info.append("❌ Failed to initialize damage detector")
433
+
434
+ # Setup ViT deepfake detector
435
+ if deepfake_model_path:
436
+ progress_info.append("Setting up ViT deepfake detector...")
437
+ deepfake_model = load_vit_deepfake_model(deepfake_model_path, device)
438
+ if deepfake_model:
439
+ progress_info.append("βœ… ViT deepfake detector initialized")
440
+ else:
441
+ progress_info.append("❌ Failed to initialize ViT deepfake detector")
442
 
443
  # Step 1: Detect damage
444
+ progress_info.append("Detecting damaged regions...")
445
  start_time = time.time()
446
  img, damage_outputs, damage_regions = detect_damage(img, damage_detector)
447
  damage_time = time.time() - start_time
448
 
449
+ if damage_regions:
450
+ progress_info.append(f"Found {len(damage_regions)} damage regions in {damage_time:.2f} seconds")
451
+ else:
452
+ progress_info.append("No damage regions detected")
453
+
454
+ # Step 2: Check for deepfakes using ViT
455
  deepfake_results = []
456
  if deepfake_model is not None:
457
+ progress_info.append("Analyzing regions for deepfakes using ViT model...")
458
  start_time = time.time()
459
+ deepfake_results = check_deepfake_vit(
460
+ img, damage_regions, deepfake_model, device, float(deepfake_threshold)
461
  )
462
  deepfake_time = time.time() - start_time
463
 
464
  if deepfake_results:
465
+ progress_info.append(f"Deepfake analysis completed in {deepfake_time:.2f} seconds")
466
 
467
  # Generate report
468
  for result in deepfake_results:
 
470
  region_id = result["region_id"]
471
  fake_prob = result["deepfake_prob"]
472
  is_fake = result["is_fake"]
473
+ progress_info.append(f"Region {region_id}: {'FAKE' if is_fake else 'REAL'} (Probability: {fake_prob*100:.2f}%)")
474
  elif "region" in result and result["region"] == "full_image":
475
  fake_prob = result["deepfake_prob"]
476
  is_fake = result["is_fake"]
477
+ progress_info.append(f"Whole image: {'FAKE' if is_fake else 'REAL'} (Probability: {fake_prob*100:.2f}%)")
478
  else:
479
  progress_info.append("No deepfake detection results")
480
 
481
+ # Final verdict
482
  fake_regions = [r for r in deepfake_results if r.get("is_fake", False)]
483
  if fake_regions:
484
  progress_info.append("\n🚨 VERDICT: This image contains FAKE damage 🚨")
485
  else:
486
  progress_info.append("\nβœ… VERDICT: All damage appears REAL")
487
+
488
  # Step 3: Visualize results
489
  result_img = visualize_results(img, damage_outputs, deepfake_results, float(damage_threshold))
490
 
 
492
  if len(result_img.shape) == 3 and result_img.shape[2] == 3:
493
  result_img = cv2.cvtColor(result_img, cv2.COLOR_BGR2RGB)
494
 
 
495
  return result_img, "\n".join(progress_info)
496
 
497
  def auto_install_dependencies():
 
529
 
530
  with gr.Blocks(title="Car Damage & Deepfake Detector", theme=theme) as app:
531
  gr.Markdown("""
532
+ # πŸš— Car Damage Fraud Detector with Vision Transformer
533
 
534
  Upload a car image to:
535
  1. Detect damaged areas
536
  2. Verify if the damage is real or artificially generated (deepfake)
537
 
538
+ *This app uses a Vision Transformer (ViT) model for deepfake detection.*
539
  """)
540
 
541
  # Main Interface Tab
 
588
  output.append(f"**CUDA Available:** {'Yes βœ…' if torch.cuda.is_available() else 'No ❌'}")
589
  if torch.cuda.is_available():
590
  output.append(f"**GPU:** {torch.cuda.get_device_name(0)}")
591
+ output.append(f"**MPS Available:** {'Yes βœ…' if hasattr(torch.backends, 'mps') and torch.backends.mps.is_available() else 'No ❌'}")
592
  except ImportError:
593
  output.append("**PyTorch:** Not installed ❌")
594
 
 
603
 
604
  if os.path.exists(DEFAULT_DEEPFAKE_MODEL_PATH):
605
  file_size = os.path.getsize(DEFAULT_DEEPFAKE_MODEL_PATH) / (1024 * 1024) # Size in MB
606
+ output.append(f"**ViT Deepfake Model:** Available βœ… ({file_size:.2f} MB)")
607
  else:
608
+ output.append(f"**ViT Deepfake Model:** Not found ❌ at {DEFAULT_DEEPFAKE_MODEL_PATH}")
 
 
 
 
 
609
 
610
  output.append("\n## Detectron2 Status")
611
  output.append(f"**Installed:** {'Yes βœ…' if detectron2_results['detectron2_installed'] else 'No ❌'}")
 
628
  recommendations.append(f"Place the damage model file at: {DEFAULT_DAMAGE_MODEL_PATH}")
629
 
630
  if not os.path.exists(DEFAULT_DEEPFAKE_MODEL_PATH):
631
+ recommendations.append(f"Place the ViT deepfake model file at: {DEFAULT_DEEPFAKE_MODEL_PATH}")
 
 
 
632
 
633
  if recommendations:
634
  for rec in recommendations:
 
669
 
670
  return "\n".join(output)
671
 
672
+ # Settings Tab
673
  with gr.Tab("Settings"):
674
  gr.Markdown("## Model Settings")
675
 
 
682
  )
683
 
684
  custom_deepfake_model = gr.Textbox(
685
+ label="Custom ViT Deepfake Model Path",
686
  value=DEFAULT_DEEPFAKE_MODEL_PATH,
687
+ placeholder="Path to ViT deepfake detection model (.pth)"
 
 
 
 
 
 
688
  )
689
 
690
  check_paths_btn = gr.Button("Verify Paths", variant="primary")
691
 
692
  with gr.Column():
693
  paths_result = gr.Markdown(label="Path Verification Results")
694
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
695
  with gr.Tab("Help"):
696
  gr.Markdown("""
697
  ## πŸ“‹ How to Use This Tool
 
708
 
709
  ### Requirements
710
  - Damage detection model file (Detectron2 Mask R-CNN)
711
+ - Vision Transformer (ViT) deepfake detection model file
712
+
713
+ ### About the Vision Transformer (ViT)
714
+ - This version uses a state-of-the-art Vision Transformer model for deepfake detection
715
+ - The ViT model has been trained specifically to detect artificially generated car damage
716
+ - ViT models are better at capturing global features in images compared to traditional CNNs
717
 
718
  ### Troubleshooting
719
  - If models aren't loading, check the "System Diagnostics" tab
 
725
  - **Deepfake Threshold:** Higher values make the system more selective in flagging fakes
726
  - **Skip Damage Detection:** Analyze the entire image for deepfakes without damage detection
727
  """)
728
+
729
  # Examples
730
  if any(os.path.exists(img) for img in SAMPLE_IMAGES):
731
  gr.Markdown("## Example Images")
 
737
  outputs=[output_image, output_text],
738
  fn=lambda x: process_image(
739
  x, DEFAULT_DAMAGE_MODEL_PATH, DEFAULT_DEEPFAKE_MODEL_PATH,
740
+ 0.7, 0.5, False, "auto"
741
  ),
742
  cache_examples=True
743
  )
 
749
  input_image,
750
  custom_damage_model,
751
  custom_deepfake_model,
 
752
  damage_threshold,
753
  deepfake_threshold,
754
  skip_damage,
 
780
  # Settings tab
781
  check_paths_btn.click(
782
  fn=check_model_paths,
783
+ inputs=[custom_damage_model, custom_deepfake_model],
784
  outputs=paths_result
785
  )
786
 
787
  return app
788
 
789
  if __name__ == "__main__":
 
 
790
 
791
  # Create and launch the Gradio app
792
  app = create_gradio_interface()
793
+ app.launch(share=False) # Set share=True to create a public link#!/usr/bin/env python3