Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -64,24 +64,42 @@ def detect_face_local(image_pil):
|
|
| 64 |
if not face_image_processor or not face_detection_model or FACE_LABEL_ID == -1:
|
| 65 |
return None, "Face detection model not loaded or configured properly."
|
| 66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
try:
|
| 68 |
inputs = face_image_processor(images=image_pil, return_tensors="pt")
|
| 69 |
-
with torch.no_grad():
|
| 70 |
outputs = face_detection_model(**inputs)
|
| 71 |
|
| 72 |
target_sizes = torch.tensor([image_pil.size[::-1]])
|
| 73 |
-
|
|
|
|
|
|
|
|
|
|
| 74 |
|
| 75 |
best_box = None
|
| 76 |
-
max_score = 0
|
|
|
|
|
|
|
|
|
|
| 77 |
|
| 78 |
for score, label, box in zip(results["scores"], results["labels"], results["boxes"]):
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
best_box = box.tolist()
|
|
|
|
|
|
|
| 83 |
|
| 84 |
if best_box:
|
|
|
|
|
|
|
| 85 |
padding_w = (best_box[2] - best_box[0]) * 0.15 # 15% padding width
|
| 86 |
padding_h = (best_box[3] - best_box[1]) * 0.15 # 15% padding height
|
| 87 |
|
|
@@ -89,13 +107,26 @@ def detect_face_local(image_pil):
|
|
| 89 |
ymin = max(0, best_box[1] - padding_h)
|
| 90 |
xmax = min(image_pil.width, best_box[2] + padding_w)
|
| 91 |
ymax = min(image_pil.height, best_box[3] + padding_h)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
|
| 93 |
cropped_image = image_pil.crop((xmin, ymin, xmax, ymax))
|
| 94 |
return cropped_image, None
|
| 95 |
else:
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
| 97 |
except Exception as e:
|
| 98 |
print(f"Error during local face detection: {e}")
|
|
|
|
|
|
|
| 99 |
return None, f"Error during face detection: {str(e)}"
|
| 100 |
|
| 101 |
|
|
|
|
| 64 |
if not face_image_processor or not face_detection_model or FACE_LABEL_ID == -1:
|
| 65 |
return None, "Face detection model not loaded or configured properly."
|
| 66 |
|
| 67 |
+
print(f"Detecting face with FACE_LABEL_ID: {FACE_LABEL_ID}")
|
| 68 |
+
detection_threshold = 0.4 # <<-- TRY LOWERING THIS (e.g., 0.5, 0.4, 0.3)
|
| 69 |
+
print(f"Using detection threshold: {detection_threshold}")
|
| 70 |
+
|
| 71 |
try:
|
| 72 |
inputs = face_image_processor(images=image_pil, return_tensors="pt")
|
| 73 |
+
with torch.no_grad():
|
| 74 |
outputs = face_detection_model(**inputs)
|
| 75 |
|
| 76 |
target_sizes = torch.tensor([image_pil.size[::-1]])
|
| 77 |
+
# Setting a lower threshold for post-processing here
|
| 78 |
+
results = face_image_processor.post_process_object_detection(
|
| 79 |
+
outputs, threshold=detection_threshold, target_sizes=target_sizes
|
| 80 |
+
)[0]
|
| 81 |
|
| 82 |
best_box = None
|
| 83 |
+
max_score = 0 # We will still pick the best one above the (now lower) threshold
|
| 84 |
+
|
| 85 |
+
print(f"Detection results: {len(results['scores'])} detections before filtering by label.")
|
| 86 |
+
detected_items_for_label = []
|
| 87 |
|
| 88 |
for score, label, box in zip(results["scores"], results["labels"], results["boxes"]):
|
| 89 |
+
current_score = score.item()
|
| 90 |
+
current_label = label.item()
|
| 91 |
+
print(f" - Detected item: Label {current_label}, Score {current_score:.2f}")
|
| 92 |
+
if current_label == FACE_LABEL_ID:
|
| 93 |
+
detected_items_for_label.append({'score': current_score, 'box': box.tolist()})
|
| 94 |
+
if current_score > max_score:
|
| 95 |
+
max_score = current_score
|
| 96 |
best_box = box.tolist()
|
| 97 |
+
|
| 98 |
+
print(f"Found {len(detected_items_for_label)} items matching FACE_LABEL_ID {FACE_LABEL_ID} with scores: {[item['score'] for item in detected_items_for_label]}")
|
| 99 |
|
| 100 |
if best_box:
|
| 101 |
+
print(f"Selected best box with score: {max_score:.2f}")
|
| 102 |
+
# Add a small padding to the bounding box
|
| 103 |
padding_w = (best_box[2] - best_box[0]) * 0.15 # 15% padding width
|
| 104 |
padding_h = (best_box[3] - best_box[1]) * 0.15 # 15% padding height
|
| 105 |
|
|
|
|
| 107 |
ymin = max(0, best_box[1] - padding_h)
|
| 108 |
xmax = min(image_pil.width, best_box[2] + padding_w)
|
| 109 |
ymax = min(image_pil.height, best_box[3] + padding_h)
|
| 110 |
+
|
| 111 |
+
# Ensure cropped dimensions are valid
|
| 112 |
+
if xmax <= xmin or ymax <= ymin:
|
| 113 |
+
print(f"Warning: Invalid crop dimensions after padding. Original box: {best_box}. Padded: ({xmin},{ymin},{xmax},{ymax})")
|
| 114 |
+
# Fallback to original box if padding made it invalid
|
| 115 |
+
xmin, ymin, xmax, ymax = best_box[0], best_box[1], best_box[2], best_box[3]
|
| 116 |
+
if xmax <= xmin or ymax <= ymin: # If original box itself is invalid
|
| 117 |
+
return None, "Detected box has invalid dimensions."
|
| 118 |
|
| 119 |
cropped_image = image_pil.crop((xmin, ymin, xmax, ymax))
|
| 120 |
return cropped_image, None
|
| 121 |
else:
|
| 122 |
+
if len(detected_items_for_label) > 0:
|
| 123 |
+
return None, f"Faces detected but scores too low (max score: {max_score:.2f} with threshold {detection_threshold}). Try a clearer image or different pose."
|
| 124 |
+
else:
|
| 125 |
+
return None, f"No face/person detected with sufficient confidence (threshold {detection_threshold}). Ensure face is clear and well-lit."
|
| 126 |
except Exception as e:
|
| 127 |
print(f"Error during local face detection: {e}")
|
| 128 |
+
import traceback
|
| 129 |
+
traceback.print_exc() # Print full traceback for debugging
|
| 130 |
return None, f"Error during face detection: {str(e)}"
|
| 131 |
|
| 132 |
|