Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -39,7 +39,7 @@ logger = logging.getLogger(__name__)
|
|
| 39 |
|
| 40 |
# --- HYBRID PRIVACY SETTINGS ---
|
| 41 |
CONFIDENCE_THRESHOLD = 0.3 # High Sensitivity (Catches mostly everything)
|
| 42 |
-
TARGET_MOSAIC_GRID =
|
| 43 |
MIN_PIXEL_SIZE = 15 # Min Block Size: Blocks cannot be smaller than 12px, (Higher = Stronger Blur for small faces)
|
| 44 |
COVERAGE_SCALE = 1.1 # 110% Coverage (Padding around face)
|
| 45 |
|
|
@@ -289,21 +289,45 @@ def apply_blur(image, x, y, w, h):
|
|
| 289 |
image[y:y+h, x:x+w] = pixelated
|
| 290 |
return image
|
| 291 |
|
| 292 |
-
def draw_label(image, x, y, w,
|
| 293 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 294 |
font = cv2.FONT_HERSHEY_SIMPLEX
|
| 295 |
scale = 0.6
|
| 296 |
thickness = 2
|
| 297 |
(tw, th), _ = cv2.getTextSize(text, font, scale, thickness)
|
| 298 |
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
|
| 303 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 304 |
else:
|
| 305 |
-
|
| 306 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 307 |
|
| 308 |
def process_frame(image, mode):
|
| 309 |
"""
|
|
@@ -321,7 +345,10 @@ def process_frame(image, mode):
|
|
| 321 |
x, y, w, h = face['box']
|
| 322 |
|
| 323 |
# 2. Analysis
|
| 324 |
-
|
|
|
|
|
|
|
|
|
|
| 325 |
|
| 326 |
if mode in ["data", "smart"]:
|
| 327 |
# Crop and Check DB
|
|
@@ -330,13 +357,18 @@ def process_frame(image, mode):
|
|
| 330 |
res = FACE_DB.recognize(face_crop)
|
| 331 |
|
| 332 |
if res['match']:
|
| 333 |
-
|
| 334 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 335 |
else:
|
| 336 |
-
|
| 337 |
-
log_entries.append(f"⚠️ Face #{i+1}:
|
|
|
|
| 338 |
|
| 339 |
-
|
| 340 |
else:
|
| 341 |
log_entries.append(f"🔒 Face #{i+1}: Anonymized")
|
| 342 |
|
|
@@ -345,12 +377,14 @@ def process_frame(image, mode):
|
|
| 345 |
processed_img = apply_blur(processed_img, x, y, w, h)
|
| 346 |
|
| 347 |
elif mode == "data":
|
| 348 |
-
|
| 349 |
-
|
|
|
|
| 350 |
|
| 351 |
elif mode == "smart":
|
|
|
|
| 352 |
processed_img = apply_blur(processed_img, x, y, w, h)
|
| 353 |
-
draw_label(processed_img, x, y, w,
|
| 354 |
|
| 355 |
# Create Log String
|
| 356 |
if not log_entries:
|
|
@@ -410,14 +444,13 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue"), title="Smart Redaction
|
|
| 410 |
# Unified Config Info Row
|
| 411 |
with gr.Row():
|
| 412 |
gr.Markdown(f"**System Status:** {FACE_DB.get_stats()}")
|
| 413 |
-
gr.Markdown(f"**Config:** Hybrid Pixelate | High Sensitivity | 110% Coverage")
|
| 414 |
|
| 415 |
with gr.Tabs():
|
| 416 |
|
| 417 |
# --- TAB 1: RAW PRIVACY ---
|
| 418 |
with gr.TabItem("1️⃣ Raw Privacy (Baseline)"):
|
| 419 |
gr.Markdown("### 🔒 Total Anonymization")
|
| 420 |
-
gr.Markdown("*
|
| 421 |
|
| 422 |
with gr.Tabs():
|
| 423 |
with gr.TabItem("Image"):
|
|
@@ -437,7 +470,7 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue"), title="Smart Redaction
|
|
| 437 |
# --- TAB 2: THE DATA LAYER ---
|
| 438 |
with gr.TabItem("2️⃣ The Data Layer (Security)"):
|
| 439 |
gr.Markdown("### 🔍 Recognition & Intelligence")
|
| 440 |
-
gr.Markdown("*
|
| 441 |
|
| 442 |
with gr.Tabs():
|
| 443 |
with gr.TabItem("Image"):
|
|
@@ -460,7 +493,7 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue"), title="Smart Redaction
|
|
| 460 |
# --- TAB 3: SMART REDACTION ---
|
| 461 |
with gr.TabItem("3️⃣ Smart Redaction (Combined)"):
|
| 462 |
gr.Markdown("### 🛡️ Intelligent Privacy")
|
| 463 |
-
gr.Markdown("*
|
| 464 |
|
| 465 |
with gr.Tabs():
|
| 466 |
with gr.TabItem("Image"):
|
|
|
|
| 39 |
|
| 40 |
# --- HYBRID PRIVACY SETTINGS ---
|
| 41 |
CONFIDENCE_THRESHOLD = 0.3 # High Sensitivity (Catches mostly everything)
|
| 42 |
+
TARGET_MOSAIC_GRID = 8 # Max Resolution: Face is divided into 12x12 grid, (Lower = Stronger Blur)
|
| 43 |
MIN_PIXEL_SIZE = 15 # Min Block Size: Blocks cannot be smaller than 12px, (Higher = Stronger Blur for small faces)
|
| 44 |
COVERAGE_SCALE = 1.1 # 110% Coverage (Padding around face)
|
| 45 |
|
|
|
|
| 289 |
image[y:y+h, x:x+w] = pixelated
|
| 290 |
return image
|
| 291 |
|
| 292 |
+
def draw_label(image, x, y, w, h, text, color):
|
| 293 |
+
"""
|
| 294 |
+
Smart Annotation:
|
| 295 |
+
- Draws text OUTSIDE the face box.
|
| 296 |
+
- Tries to draw ABOVE. If no space, draws BELOW.
|
| 297 |
+
- Background box matches text size.
|
| 298 |
+
"""
|
| 299 |
font = cv2.FONT_HERSHEY_SIMPLEX
|
| 300 |
scale = 0.6
|
| 301 |
thickness = 2
|
| 302 |
(tw, th), _ = cv2.getTextSize(text, font, scale, thickness)
|
| 303 |
|
| 304 |
+
margin = 10 # Gap between face and text
|
| 305 |
+
|
| 306 |
+
# Check if we have space above the face
|
| 307 |
+
# We need space for Text Height (th) + Padding (~15px)
|
| 308 |
+
space_above = y - th - 15
|
| 309 |
+
|
| 310 |
+
if space_above > 0:
|
| 311 |
+
# === DRAW ABOVE ===
|
| 312 |
+
text_y = y - margin
|
| 313 |
+
|
| 314 |
+
# Coordinates for the background rectangle
|
| 315 |
+
box_tl = (x, text_y - th - 5)
|
| 316 |
+
box_br = (x + tw + 10, text_y + 5)
|
| 317 |
+
|
| 318 |
+
cv2.rectangle(image, box_tl, box_br, color, -1)
|
| 319 |
+
cv2.putText(image, text, (x + 5, text_y), font, scale, (255, 255, 255), thickness)
|
| 320 |
else:
|
| 321 |
+
# === DRAW BELOW ===
|
| 322 |
+
# y + h is the bottom of the face
|
| 323 |
+
text_y = y + h + th + margin
|
| 324 |
+
|
| 325 |
+
# Coordinates for the background rectangle
|
| 326 |
+
box_tl = (x, text_y - th - 5)
|
| 327 |
+
box_br = (x + tw + 10, text_y + 5)
|
| 328 |
+
|
| 329 |
+
cv2.rectangle(image, box_tl, box_br, color, -1)
|
| 330 |
+
cv2.putText(image, text, (x + 5, text_y), font, scale, (255, 255, 255), thickness)
|
| 331 |
|
| 332 |
def process_frame(image, mode):
|
| 333 |
"""
|
|
|
|
| 345 |
x, y, w, h = face['box']
|
| 346 |
|
| 347 |
# 2. Analysis
|
| 348 |
+
# Default vars
|
| 349 |
+
full_log_text = "Unknown" # Goes to text box
|
| 350 |
+
img_label_text = "Unknown" # Goes to image overlay
|
| 351 |
+
color = (0, 255, 0)
|
| 352 |
|
| 353 |
if mode in ["data", "smart"]:
|
| 354 |
# Crop and Check DB
|
|
|
|
| 357 |
res = FACE_DB.recognize(face_crop)
|
| 358 |
|
| 359 |
if res['match']:
|
| 360 |
+
# 1. LOG GETS FULL DETAILS
|
| 361 |
+
full_log_text = f"MATCH - {res['name']} (ID: {res['id']})"
|
| 362 |
+
log_entries.append(f"✅ Face #{i+1}: {full_log_text}")
|
| 363 |
+
|
| 364 |
+
# 2. IMAGE GETS ID ONLY
|
| 365 |
+
img_label_text = f"ID: {res['id']}"
|
| 366 |
else:
|
| 367 |
+
full_log_text = "UNKNOWN"
|
| 368 |
+
log_entries.append(f"⚠️ Face #{i+1}: {full_log_text}")
|
| 369 |
+
img_label_text = "Unknown"
|
| 370 |
|
| 371 |
+
color = res['color']
|
| 372 |
else:
|
| 373 |
log_entries.append(f"🔒 Face #{i+1}: Anonymized")
|
| 374 |
|
|
|
|
| 377 |
processed_img = apply_blur(processed_img, x, y, w, h)
|
| 378 |
|
| 379 |
elif mode == "data":
|
| 380 |
+
# Draw Box + Label (passing 'h' for smart positioning)
|
| 381 |
+
cv2.rectangle(processed_img, (x, y), (x+w, y+h), color, 2)
|
| 382 |
+
draw_label(processed_img, x, y, w, h, img_label_text, color)
|
| 383 |
|
| 384 |
elif mode == "smart":
|
| 385 |
+
# Blur + Label (passing 'h' for smart positioning)
|
| 386 |
processed_img = apply_blur(processed_img, x, y, w, h)
|
| 387 |
+
draw_label(processed_img, x, y, w, h, img_label_text, color)
|
| 388 |
|
| 389 |
# Create Log String
|
| 390 |
if not log_entries:
|
|
|
|
| 444 |
# Unified Config Info Row
|
| 445 |
with gr.Row():
|
| 446 |
gr.Markdown(f"**System Status:** {FACE_DB.get_stats()}")
|
|
|
|
| 447 |
|
| 448 |
with gr.Tabs():
|
| 449 |
|
| 450 |
# --- TAB 1: RAW PRIVACY ---
|
| 451 |
with gr.TabItem("1️⃣ Raw Privacy (Baseline)"):
|
| 452 |
gr.Markdown("### 🔒 Total Anonymization")
|
| 453 |
+
gr.Markdown("*GDPR Compliance: Everyone is hidden. No data is extracted.*")
|
| 454 |
|
| 455 |
with gr.Tabs():
|
| 456 |
with gr.TabItem("Image"):
|
|
|
|
| 470 |
# --- TAB 2: THE DATA LAYER ---
|
| 471 |
with gr.TabItem("2️⃣ The Data Layer (Security)"):
|
| 472 |
gr.Markdown("### 🔍 Recognition & Intelligence")
|
| 473 |
+
gr.Markdown("*Security Control Room. We identify Known vs Unknown. No Privacy.*")
|
| 474 |
|
| 475 |
with gr.Tabs():
|
| 476 |
with gr.TabItem("Image"):
|
|
|
|
| 493 |
# --- TAB 3: SMART REDACTION ---
|
| 494 |
with gr.TabItem("3️⃣ Smart Redaction (Combined)"):
|
| 495 |
gr.Markdown("### 🛡️ Intelligent Privacy")
|
| 496 |
+
gr.Markdown("*The Solution: Faces are blurred for privacy, but Identities are overlaid for security.*")
|
| 497 |
|
| 498 |
with gr.Tabs():
|
| 499 |
with gr.TabItem("Image"):
|