asrcoddeploy commited on
Commit
9ca6575
·
verified ·
1 Parent(s): 8c6d609

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +81 -31
app.py CHANGED
@@ -5,6 +5,7 @@ import torch.nn as nn
5
  import numpy as np
6
  from torchvision import transforms
7
  import os
 
8
 
9
  # --- 1. MODEL ARCHITECTURE ---
10
  class LDobjModel(nn.Module):
@@ -43,78 +44,127 @@ transform = transforms.Compose([
43
  transforms.ToTensor()
44
  ])
45
 
46
- # --- 3. PROCESSING LOGIC ---
47
- def analyze_video(input_video_path):
48
  if not input_video_path:
49
- return None
50
 
 
 
51
  cap = cv2.VideoCapture(input_video_path)
52
  width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
53
  height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
54
  fps = cap.get(cv2.CAP_PROP_FPS)
 
55
 
56
  raw_output = "temp_raw.mp4"
57
  fourcc = cv2.VideoWriter_fourcc(*'mp4v')
58
  out = cv2.VideoWriter(raw_output, fourcc, fps, (width, height))
59
  morph_kernel = np.ones((5, 5), np.uint8)
60
 
 
 
 
 
 
61
  while cap.isOpened():
62
  ret, frame = cap.read()
63
  if not ret: break
64
 
 
 
 
 
 
 
65
  input_img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
66
  img_tensor = transform(input_img).unsqueeze(0).to(device)
67
  with torch.no_grad():
68
  pred = model(img_tensor).squeeze().numpy()
69
 
 
70
  mask = (pred > 0.5).astype(np.uint8)
71
  mask_full = cv2.resize(mask, (width, height), interpolation=cv2.INTER_NEAREST)
72
  mask_full = cv2.morphologyEx(mask_full, cv2.MORPH_OPEN, morph_kernel)
73
 
 
74
  moments = cv2.moments(mask_full[int(height*0.75):, :])
75
- if moments["m00"] > 0 and abs(int(moments["m10"] / moments["m00"]) - width // 2) > (width * 0.1):
 
76
  overlay = frame.copy()
77
  overlay[mask_full > 0] = (0, 0, 255)
78
  frame = cv2.addWeighted(frame, 0.7, overlay, 0.3, 0)
79
- cv2.putText(frame, "LANE DEPARTURE", (width//10, 80), cv2.FONT_HERSHEY_DUPLEX, 1.5, (0, 0, 255), 3)
 
 
 
80
 
81
  out.write(frame)
82
 
83
- cap.release(); out.release()
 
 
 
84
  web_output = "ldobj_final.mp4"
85
- os.system(f"ffmpeg -y -i {raw_output} -c:v libx264 -pix_fmt yuv420p -movflags +faststart {web_output}")
86
- return web_output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
- # --- 4. FRONTEND DESIGN (Corrected for Gradio 6.0) ---
89
  custom_css = """
90
- #video-container { min-height: 400px; }
91
- .gradio-container { background-color: #f7f9fc; }
92
  footer { visibility: hidden; }
 
 
93
  """
94
 
95
- # Theme and CSS removed from constructor as per the warning
96
- with gr.Blocks() as app:
97
- gr.HTML("<h1 style='text-align: center; color: #d32f2f;'>🚗 LDobj Safety Interface</h1>")
98
- gr.HTML("<p style='text-align: center;'>AI-Powered Lane Departure Detection & Alert System</p>")
99
 
100
  with gr.Group():
101
  with gr.Row():
102
- with gr.Column(scale=1):
103
- # mirror_webcam argument removed to fix TypeError
104
- video_in = gr.Video(label="Source Dashcam Feed")
105
- run_btn = gr.Button("START AI ANALYSIS", variant="primary")
 
 
 
 
 
 
 
 
 
106
 
107
- with gr.Column(scale=1):
108
- video_out = gr.Video(label="LDobj Alert Output", interactive=False, autoplay=True)
109
-
110
- gr.Markdown("---")
111
- gr.Markdown("### How it works\n1. **Monitor:** System analyzes lanes in the background.\n2. **Active Alert:** Warnings only appear when a lane departure is detected.")
112
-
113
- run_btn.click(fn=analyze_video, inputs=video_in, outputs=video_out)
 
 
 
 
 
 
114
 
115
  if __name__ == "__main__":
116
- # Theme and CSS moved here to comply with Gradio 6.0
117
- app.launch(
118
- theme=gr.themes.Default(primary_hue="red"),
119
- css=custom_css
120
- )
 
5
  import numpy as np
6
  from torchvision import transforms
7
  import os
8
+ import time
9
 
10
  # --- 1. MODEL ARCHITECTURE ---
11
  class LDobjModel(nn.Module):
 
44
  transforms.ToTensor()
45
  ])
46
 
47
+ # --- 3. ADVANCED PROCESSING LOGIC (With Progress & Analytics) ---
48
+ def analyze_video(input_video_path, sensitivity, progress=gr.Progress()):
49
  if not input_video_path:
50
+ return None, "⚠️ Please upload a video first."
51
 
52
+ start_time = time.time()
53
+
54
  cap = cv2.VideoCapture(input_video_path)
55
  width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
56
  height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
57
  fps = cap.get(cv2.CAP_PROP_FPS)
58
+ total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
59
 
60
  raw_output = "temp_raw.mp4"
61
  fourcc = cv2.VideoWriter_fourcc(*'mp4v')
62
  out = cv2.VideoWriter(raw_output, fourcc, fps, (width, height))
63
  morph_kernel = np.ones((5, 5), np.uint8)
64
 
65
+ # Calculate threshold based on user slider (e.g., 10% = 0.10)
66
+ drift_threshold = width * (sensitivity / 100.0)
67
+ frame_count = 0
68
+ alerts_triggered = 0
69
+
70
  while cap.isOpened():
71
  ret, frame = cap.read()
72
  if not ret: break
73
 
74
+ # Report progress to the UI
75
+ frame_count += 1
76
+ if frame_count % 5 == 0:
77
+ progress(frame_count / total_frames, desc=f"Processing AI Vision: Frame {frame_count}/{total_frames}")
78
+
79
+ # AI Prediction
80
  input_img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
81
  img_tensor = transform(input_img).unsqueeze(0).to(device)
82
  with torch.no_grad():
83
  pred = model(img_tensor).squeeze().numpy()
84
 
85
+ # Mask Cleaning
86
  mask = (pred > 0.5).astype(np.uint8)
87
  mask_full = cv2.resize(mask, (width, height), interpolation=cv2.INTER_NEAREST)
88
  mask_full = cv2.morphologyEx(mask_full, cv2.MORPH_OPEN, morph_kernel)
89
 
90
+ # Departure Alert Logic
91
  moments = cv2.moments(mask_full[int(height*0.75):, :])
92
+ if moments["m00"] > 0 and abs(int(moments["m10"] / moments["m00"]) - width // 2) > drift_threshold:
93
+ alerts_triggered += 1
94
  overlay = frame.copy()
95
  overlay[mask_full > 0] = (0, 0, 255)
96
  frame = cv2.addWeighted(frame, 0.7, overlay, 0.3, 0)
97
+
98
+ # Draw sleek UI elements
99
+ cv2.rectangle(frame, (0, 0), (width, 120), (0, 0, 0), -1) # Black header bar
100
+ cv2.putText(frame, "LANE DEPARTURE DETECTED", (30, 80), cv2.FONT_HERSHEY_DUPLEX, 1.5, (0, 0, 255), 3)
101
 
102
  out.write(frame)
103
 
104
+ cap.release()
105
+ out.release()
106
+
107
+ progress(0.95, desc="Optimizing Video for Web...")
108
  web_output = "ldobj_final.mp4"
109
+ os.system(f"ffmpeg -y -i {raw_output} -c:v libx264 -preset fast -pix_fmt yuv420p -movflags +faststart {web_output}")
110
+
111
+ # Calculate Telemetry
112
+ process_time = time.time() - start_time
113
+ avg_fps = frame_count / process_time
114
+
115
+ telemetry_report = (
116
+ f"✅ Analysis Complete\n"
117
+ f"------------------------\n"
118
+ f"⏱️ Processing Time: {process_time:.1f} seconds\n"
119
+ f"🎞️ Total Frames: {frame_count}\n"
120
+ f"🚀 AI Speed: {avg_fps:.1f} FPS\n"
121
+ f"🚨 Alerts Triggered: {alerts_triggered} frames"
122
+ )
123
+
124
+ return web_output, telemetry_report
125
 
126
+ # --- 4. ULTIMATE FRONTEND DESIGN ---
127
  custom_css = """
128
+ #video-in, #video-out { min-height: 450px; border-radius: 10px; border: 1px solid #333; }
129
+ .gradio-container { max-width: 1200px !important; margin: auto; }
130
  footer { visibility: hidden; }
131
+ .glow-title { color: #ff4a4a; text-shadow: 0px 0px 15px rgba(255, 74, 74, 0.5); text-align: center; margin-bottom: 5px; }
132
+ .sub-title { text-align: center; color: #888; margin-top: 0px; margin-bottom: 30px; }
133
  """
134
 
135
+ with gr.Blocks(theme=gr.themes.Slate(primary_hue="red")) as app:
136
+ gr.HTML("<h1 class='glow-title'>🛡️ LDobj ADAS Command Center</h1>")
137
+ gr.HTML("<h3 class='sub-title'>Advanced Driver Assistance System Neural Lane Tracking</h3>")
 
138
 
139
  with gr.Group():
140
  with gr.Row():
141
+ # LEFT COLUMN: Controls
142
+ with gr.Column(scale=4):
143
+ gr.Markdown("### 1. Input Source")
144
+ video_in = gr.Video(label="Dashcam Feed", elem_id="video-in")
145
+
146
+ gr.Markdown("### 2. AI Parameters")
147
+ sensitivity_slider = gr.Slider(
148
+ minimum=5, maximum=25, value=10, step=1,
149
+ label="Drift Sensitivity Threshold (%)",
150
+ info="Lower % = Stricter alerts. Higher % = Allows more drift before alerting."
151
+ )
152
+
153
+ run_btn = gr.Button("INITIALIZE SCAN", variant="primary", size="lg")
154
 
155
+ # RIGHT COLUMN: Output
156
+ with gr.Column(scale=5):
157
+ gr.Markdown("### Live Output Feed")
158
+ video_out = gr.Video(label="LDobj Processed Feed", interactive=False, autoplay=True, elem_id="video-out")
159
+
160
+ gr.Markdown("### System Telemetry")
161
+ telemetry_out = gr.Textbox(label="Analytics Console", lines=6, interactive=False)
162
+
163
+ run_btn.click(
164
+ fn=analyze_video,
165
+ inputs=[video_in, sensitivity_slider],
166
+ outputs=[video_out, telemetry_out]
167
+ )
168
 
169
  if __name__ == "__main__":
170
+ app.launch(css=custom_css)