Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -33,7 +33,7 @@ CONFIG = {
|
|
| 33 |
"domain": "login"
|
| 34 |
},
|
| 35 |
"PUBLIC_URL_BASE": "https://huggingface.co/spaces/PrashanthB461/AI_Safety_Demo1/resolve/main/static/output/",
|
| 36 |
-
"MAX_PROCESSING_TIME":
|
| 37 |
}
|
| 38 |
|
| 39 |
# Setup logging
|
|
@@ -198,9 +198,9 @@ def push_report_to_salesforce(violations, score, pdf_path, pdf_file):
|
|
| 198 |
# ==========================
|
| 199 |
def calculate_safety_score(violations, total_frames):
|
| 200 |
penalties = {
|
| 201 |
-
"no_helmet": 25 / total_frames, # Normalize penalty by video length
|
| 202 |
-
"no_harness": 30 / total_frames,
|
| 203 |
-
"unsafe_posture": 20 / total_frames
|
| 204 |
}
|
| 205 |
score = 100
|
| 206 |
for v in violations:
|
|
@@ -226,10 +226,12 @@ def process_video(video_data):
|
|
| 226 |
frame_count = 0
|
| 227 |
total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
|
| 228 |
start_time = time.time()
|
|
|
|
|
|
|
| 229 |
|
| 230 |
while True:
|
| 231 |
ret, frame = video.read()
|
| 232 |
-
if not ret:
|
| 233 |
break
|
| 234 |
|
| 235 |
results = model(frame, device=device)
|
|
@@ -247,7 +249,7 @@ def process_video(video_data):
|
|
| 247 |
"violation": label,
|
| 248 |
"confidence": round(conf, 2),
|
| 249 |
"bounding_box": [round(x, 2) for x in box.xywh.cpu().numpy()[0]],
|
| 250 |
-
"timestamp": frame_count /
|
| 251 |
}
|
| 252 |
violations.append(violation)
|
| 253 |
|
|
@@ -264,12 +266,12 @@ def process_video(video_data):
|
|
| 264 |
|
| 265 |
frame_count += 1
|
| 266 |
if time.time() - start_time > CONFIG["MAX_PROCESSING_TIME"]:
|
| 267 |
-
logger.warning("Processing time limit of
|
| 268 |
break
|
| 269 |
|
| 270 |
video.release()
|
| 271 |
os.remove(video_path)
|
| 272 |
-
score = calculate_safety_score(violations, max(total_frames,
|
| 273 |
pdf_path, pdf_url, pdf_file = generate_violation_pdf(violations, score)
|
| 274 |
report_id, final_pdf_url = push_report_to_salesforce(violations, score, pdf_path, pdf_file)
|
| 275 |
|
|
@@ -303,8 +305,8 @@ def gradio_interface(video_file):
|
|
| 303 |
|
| 304 |
violation_table = "No violations detected."
|
| 305 |
if result["violations"]:
|
| 306 |
-
header = "| Violation
|
| 307 |
-
separator = "
|
| 308 |
rows = []
|
| 309 |
for v in result["violations"]:
|
| 310 |
violation_name = v["violation"]
|
|
@@ -314,7 +316,7 @@ def gradio_interface(video_file):
|
|
| 314 |
violation_name = "Missing Harness"
|
| 315 |
else:
|
| 316 |
violation_name = "Unsafe Posture"
|
| 317 |
-
row = f"| {violation_name:<
|
| 318 |
rows.append(row)
|
| 319 |
violation_table = header + separator + "\n".join(rows)
|
| 320 |
|
|
@@ -347,7 +349,7 @@ interface = gr.Interface(
|
|
| 347 |
gr.Textbox(label="Violation Details URL")
|
| 348 |
],
|
| 349 |
title="Worksite Safety Violation Analyzer",
|
| 350 |
-
description="Upload
|
| 351 |
)
|
| 352 |
|
| 353 |
if __name__ == "__main__":
|
|
|
|
| 33 |
"domain": "login"
|
| 34 |
},
|
| 35 |
"PUBLIC_URL_BASE": "https://huggingface.co/spaces/PrashanthB461/AI_Safety_Demo1/resolve/main/static/output/",
|
| 36 |
+
"MAX_PROCESSING_TIME": 60 # Set to 60 seconds for 1-minute video
|
| 37 |
}
|
| 38 |
|
| 39 |
# Setup logging
|
|
|
|
| 198 |
# ==========================
|
| 199 |
def calculate_safety_score(violations, total_frames):
|
| 200 |
penalties = {
|
| 201 |
+
"no_helmet": 25 / max(total_frames, 1), # Normalize penalty by video length
|
| 202 |
+
"no_harness": 30 / max(total_frames, 1),
|
| 203 |
+
"unsafe_posture": 20 / max(total_frames, 1)
|
| 204 |
}
|
| 205 |
score = 100
|
| 206 |
for v in violations:
|
|
|
|
| 226 |
frame_count = 0
|
| 227 |
total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
|
| 228 |
start_time = time.time()
|
| 229 |
+
fps = video.get(cv2.CAP_PROP_FPS)
|
| 230 |
+
max_frames = int(fps * CONFIG["MAX_PROCESSING_TIME"]) # Max frames for 60 seconds
|
| 231 |
|
| 232 |
while True:
|
| 233 |
ret, frame = video.read()
|
| 234 |
+
if not ret or frame_count >= max_frames:
|
| 235 |
break
|
| 236 |
|
| 237 |
results = model(frame, device=device)
|
|
|
|
| 249 |
"violation": label,
|
| 250 |
"confidence": round(conf, 2),
|
| 251 |
"bounding_box": [round(x, 2) for x in box.xywh.cpu().numpy()[0]],
|
| 252 |
+
"timestamp": frame_count / max(fps, 1)
|
| 253 |
}
|
| 254 |
violations.append(violation)
|
| 255 |
|
|
|
|
| 266 |
|
| 267 |
frame_count += 1
|
| 268 |
if time.time() - start_time > CONFIG["MAX_PROCESSING_TIME"]:
|
| 269 |
+
logger.warning("Processing time limit of 60 seconds exceeded")
|
| 270 |
break
|
| 271 |
|
| 272 |
video.release()
|
| 273 |
os.remove(video_path)
|
| 274 |
+
score = calculate_safety_score(violations, max(total_frames, frame_count))
|
| 275 |
pdf_path, pdf_url, pdf_file = generate_violation_pdf(violations, score)
|
| 276 |
report_id, final_pdf_url = push_report_to_salesforce(violations, score, pdf_path, pdf_file)
|
| 277 |
|
|
|
|
| 305 |
|
| 306 |
violation_table = "No violations detected."
|
| 307 |
if result["violations"]:
|
| 308 |
+
header = "| Violation | Timestamp | Confidence | Bounding Box | Violation Details |\n"
|
| 309 |
+
separator = "|------------------|-----------|------------|--------------------------|-------------------------|\n"
|
| 310 |
rows = []
|
| 311 |
for v in result["violations"]:
|
| 312 |
violation_name = v["violation"]
|
|
|
|
| 316 |
violation_name = "Missing Harness"
|
| 317 |
else:
|
| 318 |
violation_name = "Unsafe Posture"
|
| 319 |
+
row = f"| {violation_name:<16} | {v['timestamp']:.2f}s | {v['confidence']:.2f} | {v['bounding_box']} | {result['violation_details_url']} |"
|
| 320 |
rows.append(row)
|
| 321 |
violation_table = header + separator + "\n".join(rows)
|
| 322 |
|
|
|
|
| 349 |
gr.Textbox(label="Violation Details URL")
|
| 350 |
],
|
| 351 |
title="Worksite Safety Violation Analyzer",
|
| 352 |
+
description="Upload a video (up to 1 minute) to detect safety violations (missing helmet, missing harness, unsafe posture)."
|
| 353 |
)
|
| 354 |
|
| 355 |
if __name__ == "__main__":
|