Faethon88 commited on
Commit
46e5a5c
Β·
verified Β·
1 Parent(s): 6bd11d4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -37
app.py CHANGED
@@ -7,21 +7,26 @@ from collections import Counter
7
  import numpy as np
8
  from huggingface_hub import hf_hub_download
9
  from PIL import Image
 
 
 
 
 
10
 
11
  # -------------------------------
12
- # Load model safely
13
  # -------------------------------
14
  def load_model():
15
- model = None
16
  try:
17
  print("πŸ”§ Attempting to load YOLO model...")
18
 
19
- # Prefer local cache to avoid re-download
20
  model_path = os.path.join("models", "best.pt")
21
  os.makedirs("models", exist_ok=True)
22
 
 
23
  if not os.path.exists(model_path):
24
  print("🌐 Model not found locally, downloading from Hugging Face...")
 
25
  if "HF_TOKEN" in os.environ:
26
  model_path = hf_hub_download(
27
  repo_id="Faethon88/sar",
@@ -36,16 +41,16 @@ def load_model():
36
  else:
37
  print(f"πŸ“ Using local model: {model_path}")
38
 
39
- # Load YOLO model (this handles custom weights automatically)
40
  model = YOLO(model_path)
41
  print("βœ… Model loaded successfully!")
42
  print(f"πŸ“‹ Classes: {list(model.names.values())}")
 
43
 
44
  except Exception as e:
45
  print(f"❌ Model load failed: {e}")
46
- model = None
47
-
48
- return model
49
 
50
 
51
  # -------------------------------
@@ -60,9 +65,9 @@ print(f"πŸ“Š Model loaded: {MODEL_LOADED}")
60
  # Detection function
61
  # -------------------------------
62
  def detect_ships(image_input, confidence=0.5):
63
- """Detect ships in SAR image β€” supports both demo and real mode."""
64
  try:
65
- # Load input image properly
66
  if isinstance(image_input, str):
67
  print(f"πŸ“ Loading image from path: {image_input}")
68
  image = Image.open(image_input).convert("RGB")
@@ -72,45 +77,45 @@ def detect_ships(image_input, confidence=0.5):
72
  else:
73
  image_np = np.array(image_input)
74
 
75
- # Convert to BGR for OpenCV drawing
76
  if len(image_np.shape) == 3 and image_np.shape[2] == 3:
77
  image_np = cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
78
 
79
  # DEMO MODE
80
  if not MODEL_LOADED:
81
- print("🎭 Running in DEMO mode (no model loaded)")
82
- annotated_image = image_np.copy()
83
- h, w = annotated_image.shape[:2]
84
- cv2.rectangle(annotated_image, (w//4, h//4), (w//2, h//2), (0, 255, 0), 3)
85
- cv2.putText(annotated_image, "ship 0.85", (w//4, h//4 - 10),
86
  cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 0), 2)
87
- summary = f"Demo Results (Model not loaded):\n- ship: 1\n\nConfidence: {confidence:.2f}\nTotal: 1"
88
- annotated_image = cv2.cvtColor(annotated_image, cv2.COLOR_BGR2RGB)
89
- return annotated_image, summary
90
 
91
  # REAL MODEL PREDICTION
92
  print(f"πŸ” Running real model (conf={confidence})...")
93
  results = model.predict(image_np, conf=confidence, verbose=False)
94
  result = results[0]
95
 
96
- annotated_image = image_np.copy()
97
- boxes = result.boxes.xyxy.cpu().numpy() if result.boxes is not None else []
98
- confs = result.boxes.conf.cpu().numpy().tolist() if result.boxes is not None else []
99
- class_ids = result.boxes.cls.cpu().numpy().tolist() if result.boxes is not None else []
100
 
101
- # Draw detections
102
  class_names = []
103
  for box, cls_id, conf in zip(boxes, class_ids, confs):
104
  x1, y1, x2, y2 = map(int, box)
105
  cls_name = model.names.get(int(cls_id), "unknown")
106
  class_names.append(cls_name)
107
  label = f"{cls_name} {conf:.2f}"
108
- cv2.rectangle(annotated_image, (x1, y1), (x2, y2), (0, 255, 0), 3)
109
- cv2.putText(annotated_image, label, (x1, y1 - 10),
110
  cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 0), 2)
111
 
112
- annotated_image = cv2.cvtColor(annotated_image, cv2.COLOR_BGR2RGB)
113
  counts = Counter(class_names)
 
114
  summary = "Detection Results:\n"
115
  if counts:
116
  summary += "\n".join([f"- {cls}: {cnt}" for cls, cnt in counts.items()])
@@ -120,11 +125,11 @@ def detect_ships(image_input, confidence=0.5):
120
  summary += f"\nTotal detections: {len(class_names)}"
121
 
122
  print(f"βœ… Detected {len(class_names)} objects.")
123
- return annotated_image, summary
124
 
125
  except Exception as e:
126
  print(f"❌ Error during detection: {e}")
127
- return None, f"Processing error: {str(e)}"
128
 
129
 
130
  # -------------------------------
@@ -143,18 +148,11 @@ demo = gr.Interface(
143
  title="πŸ›°οΈ SAR Ship Detection",
144
  description="Upload a SAR image to detect ships"
145
  + (" (DEMO MODE - Model not loaded)" if not MODEL_LOADED else ""),
146
- examples=[
147
- ["https://upload.wikimedia.org/wikipedia/commons/6/6d/Sentinel-1_SAR_image_of_ship_traffic.jpg", 0.5]
148
- ] if not MODEL_LOADED else None
149
  )
150
 
151
  # -------------------------------
152
- # Main
153
  # -------------------------------
154
  if __name__ == "__main__":
155
  print("πŸš€ Starting SAR Ship Detection App...")
156
- demo.launch(
157
- server_name="0.0.0.0",
158
- server_port=7860,
159
- share=True
160
- )
 
7
  import numpy as np
8
  from huggingface_hub import hf_hub_download
9
  from PIL import Image
10
+ import torch.serialization
11
+ from ultralytics.nn.tasks import DetectionModel
12
+
13
+ # Allow YOLO model class when loading torch checkpoints
14
+ torch.serialization.add_safe_globals([DetectionModel])
15
 
16
  # -------------------------------
17
+ # Load YOLO model safely
18
  # -------------------------------
19
  def load_model():
 
20
  try:
21
  print("πŸ”§ Attempting to load YOLO model...")
22
 
 
23
  model_path = os.path.join("models", "best.pt")
24
  os.makedirs("models", exist_ok=True)
25
 
26
+ # Check if model exists locally
27
  if not os.path.exists(model_path):
28
  print("🌐 Model not found locally, downloading from Hugging Face...")
29
+
30
  if "HF_TOKEN" in os.environ:
31
  model_path = hf_hub_download(
32
  repo_id="Faethon88/sar",
 
41
  else:
42
  print(f"πŸ“ Using local model: {model_path}")
43
 
44
+ # Load YOLO model
45
  model = YOLO(model_path)
46
  print("βœ… Model loaded successfully!")
47
  print(f"πŸ“‹ Classes: {list(model.names.values())}")
48
+ return model
49
 
50
  except Exception as e:
51
  print(f"❌ Model load failed: {e}")
52
+ print("⚠️ Running in DEMO mode without model...")
53
+ return None
 
54
 
55
 
56
  # -------------------------------
 
65
  # Detection function
66
  # -------------------------------
67
  def detect_ships(image_input, confidence=0.5):
68
+ """Detect ships in SAR image β€” works in real or demo mode."""
69
  try:
70
+ # Load image from file path or numpy
71
  if isinstance(image_input, str):
72
  print(f"πŸ“ Loading image from path: {image_input}")
73
  image = Image.open(image_input).convert("RGB")
 
77
  else:
78
  image_np = np.array(image_input)
79
 
80
+ # Convert to BGR for OpenCV
81
  if len(image_np.shape) == 3 and image_np.shape[2] == 3:
82
  image_np = cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
83
 
84
  # DEMO MODE
85
  if not MODEL_LOADED:
86
+ print("🎭 Running in DEMO mode")
87
+ annotated = image_np.copy()
88
+ h, w = annotated.shape[:2]
89
+ cv2.rectangle(annotated, (w//4, h//4), (w//2, h//2), (0, 255, 0), 3)
90
+ cv2.putText(annotated, "ship 0.85", (w//4, h//4 - 10),
91
  cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 0), 2)
92
+ annotated = cv2.cvtColor(annotated, cv2.COLOR_BGR2RGB)
93
+ summary = "Demo Mode:\n- ship: 1\n\nConfidence: 0.85\nTotal: 1"
94
+ return annotated, summary
95
 
96
  # REAL MODEL PREDICTION
97
  print(f"πŸ” Running real model (conf={confidence})...")
98
  results = model.predict(image_np, conf=confidence, verbose=False)
99
  result = results[0]
100
 
101
+ annotated = image_np.copy()
102
+ boxes = result.boxes.xyxy.cpu().numpy() if result.boxes else []
103
+ confs = result.boxes.conf.cpu().numpy().tolist() if result.boxes else []
104
+ class_ids = result.boxes.cls.cpu().numpy().tolist() if result.boxes else []
105
 
 
106
  class_names = []
107
  for box, cls_id, conf in zip(boxes, class_ids, confs):
108
  x1, y1, x2, y2 = map(int, box)
109
  cls_name = model.names.get(int(cls_id), "unknown")
110
  class_names.append(cls_name)
111
  label = f"{cls_name} {conf:.2f}"
112
+ cv2.rectangle(annotated, (x1, y1), (x2, y2), (0, 255, 0), 3)
113
+ cv2.putText(annotated, label, (x1, y1 - 10),
114
  cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 0), 2)
115
 
116
+ annotated = cv2.cvtColor(annotated, cv2.COLOR_BGR2RGB)
117
  counts = Counter(class_names)
118
+
119
  summary = "Detection Results:\n"
120
  if counts:
121
  summary += "\n".join([f"- {cls}: {cnt}" for cls, cnt in counts.items()])
 
125
  summary += f"\nTotal detections: {len(class_names)}"
126
 
127
  print(f"βœ… Detected {len(class_names)} objects.")
128
+ return annotated, summary
129
 
130
  except Exception as e:
131
  print(f"❌ Error during detection: {e}")
132
+ return None, f"Processing error: {e}"
133
 
134
 
135
  # -------------------------------
 
148
  title="πŸ›°οΈ SAR Ship Detection",
149
  description="Upload a SAR image to detect ships"
150
  + (" (DEMO MODE - Model not loaded)" if not MODEL_LOADED else ""),
 
 
 
151
  )
152
 
153
  # -------------------------------
154
+ # Main Entry Point
155
  # -------------------------------
156
  if __name__ == "__main__":
157
  print("πŸš€ Starting SAR Ship Detection App...")
158
+ demo.launch(server_name="0.0.0.0", server_port=7860, share=True)