Kiransubedi545 commited on
Commit
e86ac17
·
verified ·
1 Parent(s): 04d3733

Upload 5 files

Browse files
Files changed (5) hide show
  1. alert_icon.png +0 -0
  2. app.py.py +60 -0
  3. best.pt +3 -0
  4. helmet_detect_alert.py +140 -0
  5. requirements.txt +5 -0
alert_icon.png ADDED
app.py.py ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import cv2
3
+ import os
4
+ from ultralytics import YOLO
5
+ from helmet_detect_alert import detect_from_images, detect_and_alert, MODEL_PATHS, CONFIDENCE_THRESHOLD
6
+
7
+ model_cache = {}
8
+
9
+ def load_model(model_name):
10
+ if model_name not in model_cache:
11
+ model_cache[model_name] = YOLO(MODEL_PATHS[model_name])
12
+ return model_cache[model_name]
13
+
14
+ def process_image(image, model_name, confidence):
15
+ model = load_model(model_name)
16
+ results = model.predict(source=image, conf=confidence, verbose=False)
17
+ annotated = results[0].plot()
18
+ return annotated
19
+
20
+ def process_video(video, model_name, confidence):
21
+ input_path = "temp_input_video.mp4"
22
+ output_path = "temp_output_video.mp4"
23
+ with open(input_path, "wb") as f:
24
+ f.write(video.read())
25
+ model = load_model(model_name)
26
+ detect_and_alert(input_path, output_path, model, confidence)
27
+ return output_path
28
+
29
+ with gr.Blocks() as demo:
30
+ gr.Markdown("# 🪖 Helmet Detection App (YOLOv8)")
31
+
32
+ with gr.Tab("📷 Image Detection"):
33
+ with gr.Row():
34
+ image_input = gr.Image(type="numpy", label="Upload Image")
35
+ image_output = gr.Image(label="Detection Result")
36
+
37
+ with gr.Row():
38
+ conf_slider_img = gr.Slider(0.1, 1.0, value=CONFIDENCE_THRESHOLD, label="Confidence Threshold")
39
+ model_selector_img = gr.Dropdown(choices=list(MODEL_PATHS.keys()), value="YOLOv8n", label="YOLO Model")
40
+ btn_detect_img = gr.Button("🔍 Detect Helmet")
41
+
42
+ btn_detect_img.click(fn=process_image, inputs=[image_input, model_selector_img, conf_slider_img], outputs=image_output)
43
+
44
+ with gr.Tab("🎥 Video Detection"):
45
+ with gr.Row():
46
+ video_input = gr.File(file_types=[".mp4"], label="Upload Video")
47
+ video_output = gr.Video(label="Detection Result")
48
+
49
+ with gr.Row():
50
+ conf_slider_vid = gr.Slider(0.1, 1.0, value=CONFIDENCE_THRESHOLD, label="Confidence Threshold")
51
+ model_selector_vid = gr.Dropdown(choices=list(MODEL_PATHS.keys()), value="YOLOv8n", label="YOLO Model")
52
+ btn_detect_vid = gr.Button("🎬 Detect Helmet in Video")
53
+
54
+ btn_detect_vid.click(fn=process_video, inputs=[video_input, model_selector_vid, conf_slider_vid], outputs=video_output)
55
+
56
+ gr.Markdown("---")
57
+ gr.Markdown("Developed by **Kiran Subedi** | kiransubedi545@gmail.com | [Website](http://kiransubedi545.com.np)")
58
+
59
+ if __name__ == "__main__":
60
+ demo.launch()
best.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4b87f454e987b44a6d2baa1286aaae7562a6db1e6f81a407b8cc9ed190d7a4be
3
+ size 6213219
helmet_detect_alert.py ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import os
3
+ import pyttsx3
4
+ from ultralytics import YOLO
5
+ import numpy as np
6
+ from tkinter import filedialog, messagebox
7
+ import tkinter as tk
8
+ from PIL import Image, ImageTk
9
+ import csv
10
+ from gtts import gTTS
11
+ import tempfile
12
+ import pygame
13
+ from datetime import datetime
14
+
15
+ # ----------------- Configuration -----------------
16
+ DOWNLOAD_PATH = r"D:\Learning Programming\Python\Deep learning\YOLOv8\Test_videos"
17
+ MODEL_PATHS = {
18
+ "YOLOv8n": r"D:\Learning Programming\Python\Deep learning\YOLOv8\runs\detect\train5\weights\best.pt"
19
+ }
20
+ ALERT_ICON_PATH = "alert_icon.png"
21
+ ALERT_LOG_PATH = "alert_log.csv"
22
+ CONFIDENCE_THRESHOLD = 0.3
23
+ ALERT_LANGUAGE = "en"
24
+
25
+ # ----------------- Initialize Modules -----------------
26
+ pygame.init()
27
+ os.makedirs(DOWNLOAD_PATH, exist_ok=True)
28
+
29
+ # ----------------- Add Alert Symbol -----------------
30
+ def overlay_alert_icon(frame, x, y):
31
+ if not os.path.exists(ALERT_ICON_PATH):
32
+ return frame
33
+ icon = cv2.imread(ALERT_ICON_PATH, cv2.IMREAD_UNCHANGED)
34
+ if icon is None:
35
+ return frame
36
+ icon = cv2.resize(icon, (50, 50))
37
+ ih, iw = icon.shape[:2]
38
+ if y+ih > frame.shape[0] or x+iw > frame.shape[1]:
39
+ return frame
40
+ alpha_s = icon[:, :, 3] / 255.0
41
+ alpha_l = 1.0 - alpha_s
42
+ for c in range(3):
43
+ frame[y:y+ih, x:x+iw, c] = (alpha_s * icon[:, :, c] + alpha_l * frame[y:y+ih, x:x+iw, c])
44
+ return frame
45
+
46
+ # ----------------- Voice Alert -----------------
47
+ def speak_alert(text, lang="en"):
48
+ with tempfile.NamedTemporaryFile(delete=True) as fp:
49
+ tts = gTTS(text=text, lang=lang)
50
+ temp_path = f"{fp.name}.mp3"
51
+ tts.save(temp_path)
52
+ pygame.mixer.music.load(temp_path)
53
+ pygame.mixer.music.play()
54
+ while pygame.mixer.music.get_busy():
55
+ continue
56
+
57
+ # ----------------- Save Alert Log -----------------
58
+ def log_alert(message):
59
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
60
+ with open(ALERT_LOG_PATH, mode='a', newline='') as file:
61
+ writer = csv.writer(file)
62
+ writer.writerow([timestamp, message])
63
+
64
+ # ----------------- Run YOLO Prediction + Alerts -----------------
65
+ def detect_and_alert(video_path, model, confidence=CONFIDENCE_THRESHOLD):
66
+ cap = cv2.VideoCapture(video_path)
67
+ frame_count = 0
68
+ alert_cooldown = 15
69
+ while cap.isOpened():
70
+ ret, frame = cap.read()
71
+ if not ret:
72
+ break
73
+ frame_count += 1
74
+ if frame_count % 3 != 0:
75
+ continue
76
+ results = model.predict(source=frame, conf=confidence, verbose=False)
77
+ annotated_frame = results[0].plot()
78
+ helmets, heads = [], []
79
+ for box in results[0].boxes:
80
+ cls_id = int(box.cls[0].item())
81
+ x1, y1, x2, y2 = box.xyxy[0].cpu().numpy().astype(int)
82
+ center_x = (x1 + x2) // 2
83
+ center_y = (y1 + y2) // 2
84
+ if cls_id == 0:
85
+ helmets.append(((x1, y1, x2, y2), (center_x, center_y)))
86
+ elif cls_id == 2:
87
+ heads.append(((x1, y1, x2, y2), (center_x, center_y)))
88
+ alert_triggered = False
89
+ for (hx1, hy1, hx2, hy2), (hcx, hcy) in heads:
90
+ covered = any(abs(hcx - hel_x) < 30 and abs(hcy - hel_y) < 30 for (_, _, _, _), (hel_x, hel_y) in helmets)
91
+ if not covered:
92
+ annotated_frame = overlay_alert_icon(annotated_frame, hx1, hy1)
93
+ cv2.putText(annotated_frame, "⚠ No Helmet!", (hx1, hy1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
94
+ alert_triggered = True
95
+ log_alert(f"Alert at frame {frame_count}: No helmet at ({hx1}, {hy1})")
96
+ if alert_triggered and frame_count % alert_cooldown == 0:
97
+ speak_alert("Alert! Person without helmet detected", ALERT_LANGUAGE)
98
+ cv2.imshow("Helmet Detection", annotated_frame)
99
+ if cv2.waitKey(1) & 0xFF == ord('q'):
100
+ break
101
+ cap.release()
102
+ cv2.destroyAllWindows()
103
+
104
+ # ----------------- Detect from Multiple Images -----------------
105
+ def detect_from_images(image_paths, model, confidence=CONFIDENCE_THRESHOLD):
106
+ for image_path in image_paths:
107
+ frame = cv2.imread(image_path)
108
+ results = model.predict(source=frame, conf=confidence, verbose=False)
109
+ annotated_frame = results[0].plot()
110
+ helmets, heads = [], []
111
+ for box in results[0].boxes:
112
+ cls_id = int(box.cls[0].item())
113
+ x1, y1, x2, y2 = box.xyxy[0].cpu().numpy().astype(int)
114
+ center_x = (x1 + x2) // 2
115
+ center_y = (y1 + y2) // 2
116
+ if cls_id == 0:
117
+ helmets.append(((x1, y1, x2, y2), (center_x, center_y)))
118
+ elif cls_id == 2:
119
+ heads.append(((x1, y1, x2, y2), (center_x, center_y)))
120
+ alert_triggered = False
121
+ for (hx1, hy1, hx2, hy2), (hcx, hcy) in heads:
122
+ covered = any(abs(hcx - hel_x) < 30 and abs(hcy - hel_y) < 30 for (_, _, _, _), (hel_x, hel_y) in helmets)
123
+ if not covered:
124
+ annotated_frame = overlay_alert_icon(annotated_frame, hx1, hy1)
125
+ cv2.putText(annotated_frame, "⚠ No Helmet!", (hx1, hy1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
126
+ alert_triggered = True
127
+ log_alert(f"Alert: No helmet at ({hx1}, {hy1}) in image {image_path}")
128
+ if alert_triggered:
129
+ speak_alert("Alert! Person without helmet detected", ALERT_LANGUAGE)
130
+ cv2.imshow(f"Result - {os.path.basename(image_path)}", annotated_frame)
131
+ cv2.waitKey(0)
132
+ cv2.destroyAllWindows()
133
+
134
+ # ----------------- Snapshot -----------------
135
+ def save_snapshot(frame, path="snapshot.jpg"):
136
+ cv2.imwrite(path, frame)
137
+
138
+ # ----------------- Main Execution -----------------
139
+ model = YOLO(MODEL_PATHS["YOLOv8n"])
140
+ # This script is now module-only: import and use functions from app.py
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ ultralytics
2
+ opencv-python
3
+ Pillow
4
+ gTTS
5
+ pygame