Spaces:
Sleeping
Sleeping
Add detailed logging for debugging detection pipeline
Browse files
model.py
CHANGED
|
@@ -84,8 +84,10 @@ class TrafficSignDetector:
|
|
| 84 |
if hasattr(self.model, 'model') and hasattr(self.model.model, 'parameters'):
|
| 85 |
total_params = sum(p.numel() for p in self.model.model.parameters())
|
| 86 |
trainable_params = sum(p.numel() for p in self.model.model.parameters() if p.requires_grad)
|
|
|
|
| 87 |
print(f" - Total parameters: {total_params:,}")
|
| 88 |
print(f" - Trainable parameters: {trainable_params:,}")
|
|
|
|
| 89 |
except Exception as e:
|
| 90 |
print(f" - Could not retrieve architecture details: {e}")
|
| 91 |
|
|
@@ -154,16 +156,27 @@ class TrafficSignDetector:
|
|
| 154 |
:return: tuple of (image with drawn bounding boxes, preprocessed image for visualization)
|
| 155 |
"""
|
| 156 |
print(f"\n{'='*80}")
|
| 157 |
-
print(f"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
|
| 159 |
# Store original image for drawing (uint8)
|
| 160 |
original_image = image.copy()
|
| 161 |
|
| 162 |
# Apply letterbox preprocessing to ensure 640x640 matching training size
|
| 163 |
# Returns both processed image and transformation info
|
|
|
|
| 164 |
image, scale, pad_x, pad_y = self._ensure_square(image, target_size=640)
|
|
|
|
|
|
|
|
|
|
| 165 |
|
| 166 |
# Normalize pixel values for inference
|
|
|
|
| 167 |
image = self._preprocess(image)
|
| 168 |
|
| 169 |
# Store preprocessed image for visualization (convert back to 0-255 for display)
|
|
@@ -171,22 +184,35 @@ class TrafficSignDetector:
|
|
| 171 |
|
| 172 |
# Use imgsz=640 to match training size
|
| 173 |
# Use iou_threshold for NMS (Non-Maximum Suppression) to remove overlapping boxes
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
results = self.model(image, conf=self.conf_threshold, imgsz=640, iou=0.45)
|
| 175 |
-
print(f"Number of results: {len(results)}")
|
| 176 |
|
| 177 |
# Get original dimensions for coordinate transformation
|
| 178 |
orig_h, orig_w = original_image.shape[:2]
|
| 179 |
|
|
|
|
| 180 |
for result in results:
|
| 181 |
boxes = result.boxes
|
| 182 |
-
print(f"Total boxes
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 183 |
|
| 184 |
# Debug: print summary
|
| 185 |
if len(boxes) > 0:
|
| 186 |
confidences = [float(box.conf[0]) for box in boxes]
|
| 187 |
-
print(f"Confidence range: {min(confidences):.4f} - {max(confidences):.4f}")
|
|
|
|
| 188 |
else:
|
| 189 |
-
print(f"No detections above threshold {self.conf_threshold}")
|
|
|
|
| 190 |
|
| 191 |
for box in boxes:
|
| 192 |
# Get bounding box coordinates from letterboxed image
|
|
@@ -211,5 +237,7 @@ class TrafficSignDetector:
|
|
| 211 |
label = f"{self.classes[cls]}: {conf:.2f}"
|
| 212 |
cv2.putText(original_image, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, self.text_color, 2)
|
| 213 |
|
| 214 |
-
print("=
|
|
|
|
|
|
|
| 215 |
return original_image, preprocessed_display
|
|
|
|
| 84 |
if hasattr(self.model, 'model') and hasattr(self.model.model, 'parameters'):
|
| 85 |
total_params = sum(p.numel() for p in self.model.model.parameters())
|
| 86 |
trainable_params = sum(p.numel() for p in self.model.model.parameters() if p.requires_grad)
|
| 87 |
+
weights_sum = sum(p.sum().item() for p in self.model.model.parameters())
|
| 88 |
print(f" - Total parameters: {total_params:,}")
|
| 89 |
print(f" - Trainable parameters: {trainable_params:,}")
|
| 90 |
+
print(f" - Weights sum: {weights_sum:.6f}")
|
| 91 |
except Exception as e:
|
| 92 |
print(f" - Could not retrieve architecture details: {e}")
|
| 93 |
|
|
|
|
| 156 |
:return: tuple of (image with drawn bounding boxes, preprocessed image for visualization)
|
| 157 |
"""
|
| 158 |
print(f"\n{'='*80}")
|
| 159 |
+
print(f"DETECTION PIPELINE START")
|
| 160 |
+
print(f"{'='*80}")
|
| 161 |
+
print(f"[STEP 1] INPUT IMAGE")
|
| 162 |
+
print(f" - Shape: {image.shape}")
|
| 163 |
+
print(f" - dtype: {image.dtype}")
|
| 164 |
+
print(f" - Range: [{image.min()}, {image.max()}]")
|
| 165 |
+
print(f" - Mean: {image.mean():.2f}, Std: {image.std():.2f}")
|
| 166 |
|
| 167 |
# Store original image for drawing (uint8)
|
| 168 |
original_image = image.copy()
|
| 169 |
|
| 170 |
# Apply letterbox preprocessing to ensure 640x640 matching training size
|
| 171 |
# Returns both processed image and transformation info
|
| 172 |
+
print(f"\n[STEP 2] LETTERBOX PREPROCESSING")
|
| 173 |
image, scale, pad_x, pad_y = self._ensure_square(image, target_size=640)
|
| 174 |
+
print(f" - Letterboxed shape: {image.shape}")
|
| 175 |
+
print(f" - Scale factor: {scale:.3f}")
|
| 176 |
+
print(f" - Padding X: {pad_x}, Y: {pad_y}")
|
| 177 |
|
| 178 |
# Normalize pixel values for inference
|
| 179 |
+
print(f"\n[STEP 3] IMAGE NORMALIZATION")
|
| 180 |
image = self._preprocess(image)
|
| 181 |
|
| 182 |
# Store preprocessed image for visualization (convert back to 0-255 for display)
|
|
|
|
| 184 |
|
| 185 |
# Use imgsz=640 to match training size
|
| 186 |
# Use iou_threshold for NMS (Non-Maximum Suppression) to remove overlapping boxes
|
| 187 |
+
print(f"\n[STEP 4] MODEL INFERENCE")
|
| 188 |
+
print(f" - Input shape to model: {image.shape}")
|
| 189 |
+
print(f" - Confidence threshold: {self.conf_threshold}")
|
| 190 |
+
print(f" - IOU threshold: 0.45")
|
| 191 |
results = self.model(image, conf=self.conf_threshold, imgsz=640, iou=0.45)
|
| 192 |
+
print(f" - Number of results: {len(results)}")
|
| 193 |
|
| 194 |
# Get original dimensions for coordinate transformation
|
| 195 |
orig_h, orig_w = original_image.shape[:2]
|
| 196 |
|
| 197 |
+
print(f"\n[STEP 5] DETECTION RESULTS")
|
| 198 |
for result in results:
|
| 199 |
boxes = result.boxes
|
| 200 |
+
print(f" - Total boxes after NMS (confidence >= {self.conf_threshold}): {len(boxes)}")
|
| 201 |
+
|
| 202 |
+
# Debug: print all raw predictions before NMS
|
| 203 |
+
if hasattr(result, 'boxes') and len(result.boxes) == 0:
|
| 204 |
+
print(f" - Note: Model raw output available but filtered by NMS/confidence")
|
| 205 |
+
if hasattr(result, 'probs'):
|
| 206 |
+
print(f" - Raw predictions present: {result.probs}")
|
| 207 |
|
| 208 |
# Debug: print summary
|
| 209 |
if len(boxes) > 0:
|
| 210 |
confidences = [float(box.conf[0]) for box in boxes]
|
| 211 |
+
print(f" - Confidence range: {min(confidences):.4f} - {max(confidences):.4f}")
|
| 212 |
+
print(f" - Mean confidence: {np.mean(confidences):.4f}")
|
| 213 |
else:
|
| 214 |
+
print(f" - No detections above threshold {self.conf_threshold}")
|
| 215 |
+
print(f" - Model may not have detected any objects in this image")
|
| 216 |
|
| 217 |
for box in boxes:
|
| 218 |
# Get bounding box coordinates from letterboxed image
|
|
|
|
| 237 |
label = f"{self.classes[cls]}: {conf:.2f}"
|
| 238 |
cv2.putText(original_image, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, self.text_color, 2)
|
| 239 |
|
| 240 |
+
print(f"\n{'='*80}")
|
| 241 |
+
print(f"DETECTION PIPELINE COMPLETE")
|
| 242 |
+
print(f"{'='*80}\n")
|
| 243 |
return original_image, preprocessed_display
|