Rasleen commited on
Commit
dc55ff0
Β·
verified Β·
1 Parent(s): 9cf7a06

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +123 -41
src/streamlit_app.py CHANGED
@@ -3,6 +3,8 @@ from PIL import Image
3
  import time
4
  from ultralytics import YOLO
5
  import io
 
 
6
 
7
  # --- Page Config ---
8
  st.set_page_config(page_title="Smart Traffic Light System", layout="wide")
@@ -27,7 +29,7 @@ uploaded_images = {}
27
  for col, direction in zip(cols, directions):
28
  with col:
29
  uploaded_images[direction] = st.file_uploader(f"{direction}", type=["jpg", "png"], key=direction)
30
-
31
  # --- Process Once All Images Are Uploaded ---
32
  if all(uploaded_images.values()):
33
  # Initialize session state attributes if not already initialized
@@ -64,6 +66,7 @@ if all(uploaded_images.values()):
64
  yellow_time = 3 # Fixed yellow duration
65
 
66
  # --- Enhanced Signal Status Visualization ---
 
67
  st.markdown("### πŸš₯ Current Signal Status")
68
 
69
  signal_cols = st.columns(4)
@@ -102,10 +105,12 @@ if all(uploaded_images.values()):
102
  st.markdown(f"### {status}\n**{direction}**\n**{count} Vehicles**")
103
 
104
  # --- Timer UI ---
 
105
  st.markdown("### ⏱ Signal Timer")
106
  timer_placeholder = st.empty()
107
 
108
  # --- Display Annotated Images Below Timer ---
 
109
  st.markdown("### πŸ–ΌοΈ Detected Vehicles (Annotated Images)")
110
  img_cols = st.columns(4)
111
  for idx, direction in enumerate(directions):
@@ -138,59 +143,136 @@ if all(uploaded_images.values()):
138
  else:
139
  # Show completion message when all directions are done
140
  st.success("### 🚦 Simulation Complete! All directions have completed their green and yellow phases.")
141
- # Add restart button
 
 
 
142
  st.markdown("<br>", unsafe_allow_html=True)
143
- if st.button("πŸ”„ Restart Simulation"):
144
- for key in [
145
- "annotated_images", "counts", "sorted_directions",
146
- "current_index", "phase", "finished"
147
- ]:
148
- if key in st.session_state:
149
- del st.session_state[key]
150
- st.rerun()
151
-
152
- # --- Dashboard ---
153
  st.markdown("## πŸ“Š Traffic Analysis Dashboard")
154
 
155
  # 1. Total vehicles
156
- total_vehicles = sum(st.session_state.counts.values())
157
- st.markdown(f"<h3 style='font-size: 24px; font-weight: bold;'>πŸš— Total Vehicles Detected: {total_vehicles}</h3>", unsafe_allow_html=True)
158
-
 
 
 
159
  # 2. Bar chart for vehicle count
160
- st.markdown("<h4 style='font-size: 20px; font-weight: bold;'>🚦 Vehicle Count per Direction</h4>", unsafe_allow_html=True)
161
- st.bar_chart(st.session_state.counts)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163
  # 3. Most congested direction
164
  busiest = max(st.session_state.counts.items(), key=lambda x: x[1])
165
- st.markdown(f"<h4 style='font-size: 20px; font-weight: bold;'>**πŸ₯‡ Busiest Direction:** {busiest[0]} with {busiest[1]} vehicles</h4>", unsafe_allow_html=True)
 
 
 
 
 
 
 
 
166
 
167
- # 4. Green time per direction
168
  base_time = 5
169
  time_per_vehicle = 1
170
- max_time = 30
171
-
172
- green_times = {
173
- direction: min(base_time + count * time_per_vehicle, max_time)
174
- for direction, count in st.session_state.counts.items()
175
- }
176
- st.markdown("<h4 style='font-size: 20px; font-weight: bold;'>⏱️ Assigned Green Time</h4>" , unsafe_allow_html=True)
177
- st.markdown("""
178
- <style>
179
- .dataframe th, .dataframe td {
180
- font-size: 14px;
181
- padding: 8px;
182
- text-align: center;
183
- }
184
- .dataframe {
185
- width: 60%;
186
- margin: 0 auto;
187
- }
188
- </style>
189
- """, unsafe_allow_html=True)
190
- st.table(green_times)
191
 
192
  # 5. Pie chart (optional)
193
  import pandas as pd
194
  df = pd.DataFrame.from_dict(st.session_state.counts, orient='index', columns=['Vehicles'])
195
  st.markdown("<h4 style='font-size: 20px; font-weight: bold;'>πŸ“ˆ Traffic Share by Direction</h4>", unsafe_allow_html=True)
196
- st.pyplot(df.plot.pie(y='Vehicles', autopct='%1.1f%%', legend=False, figsize=(3,3)).figure)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  import time
4
  from ultralytics import YOLO
5
  import io
6
+ import matplotlib.pyplot as plt
7
+ import pandas as pd
8
 
9
  # --- Page Config ---
10
  st.set_page_config(page_title="Smart Traffic Light System", layout="wide")
 
29
  for col, direction in zip(cols, directions):
30
  with col:
31
  uploaded_images[direction] = st.file_uploader(f"{direction}", type=["jpg", "png"], key=direction)
32
+
33
  # --- Process Once All Images Are Uploaded ---
34
  if all(uploaded_images.values()):
35
  # Initialize session state attributes if not already initialized
 
66
  yellow_time = 3 # Fixed yellow duration
67
 
68
  # --- Enhanced Signal Status Visualization ---
69
+ st.markdown("<br>", unsafe_allow_html=True)
70
  st.markdown("### πŸš₯ Current Signal Status")
71
 
72
  signal_cols = st.columns(4)
 
105
  st.markdown(f"### {status}\n**{direction}**\n**{count} Vehicles**")
106
 
107
  # --- Timer UI ---
108
+ st.markdown("<br>", unsafe_allow_html=True)
109
  st.markdown("### ⏱ Signal Timer")
110
  timer_placeholder = st.empty()
111
 
112
  # --- Display Annotated Images Below Timer ---
113
+ st.markdown("<br>", unsafe_allow_html=True)
114
  st.markdown("### πŸ–ΌοΈ Detected Vehicles (Annotated Images)")
115
  img_cols = st.columns(4)
116
  for idx, direction in enumerate(directions):
 
143
  else:
144
  # Show completion message when all directions are done
145
  st.success("### 🚦 Simulation Complete! All directions have completed their green and yellow phases.")
146
+ counts = st.session_state.counts
147
+ sorted_directions = st.session_state.sorted_directions
148
+ # st.session_state.clear()
149
+
150
  st.markdown("<br>", unsafe_allow_html=True)
151
+
 
 
 
 
 
 
 
 
 
152
  st.markdown("## πŸ“Š Traffic Analysis Dashboard")
153
 
154
  # 1. Total vehicles
155
+ total_vehicles = sum(st.session_state.counts.values())
156
+ st.markdown(
157
+ f"""
158
+ <br>
159
+ <h3 style='font-size: 24px; font-weight: bold;'>πŸš— Total Vehicles Detected: <span style='color: #4da6ff;'>{total_vehicles}</span></h3>""",unsafe_allow_html=True)
160
+
161
  # 2. Bar chart for vehicle count
162
+ st.markdown("<br><h3 style='font-size: 24px; font-weight: bold;'>🚦 Vehicle Count per Direction</h3>", unsafe_allow_html=True)
163
+ # Create the bar chart
164
+ vehicle_counts = st.session_state.counts
165
+ fig, ax = plt.subplots(figsize=(4,4))
166
+
167
+ # Plot the bar char
168
+ ax.bar(vehicle_counts.keys(), vehicle_counts.values(), color='teal')
169
+
170
+ # Add numbers on top of the bars
171
+ for i, count in enumerate(vehicle_counts.values()):
172
+ ax.text(i, count + 0.5, str(count), ha='center', va='bottom', fontweight='bold', fontsize=8)
173
+
174
+ # Customize the chart
175
+ ax.set_ylabel('Vehicle Count')
176
+ ax.set_xlabel('Directions')
177
+ ax.set_title('Vehicle Count per Direction')
178
+ # Display the chart in Streamlit
179
+ # Show in small column
180
+ col1, col2, _ = st.columns([.3, .4, .3])
181
+ with col2:
182
+ st.pyplot(fig)
183
 
184
  # 3. Most congested direction
185
  busiest = max(st.session_state.counts.items(), key=lambda x: x[1])
186
+ st.markdown(
187
+ f"""
188
+ <br>
189
+ <h3 style='font-size: 24px; font-weight: bold;'>
190
+ πŸ₯‡ Busiest Direction: <span style='color: red;'>{busiest[0]}</span> with {busiest[1]} vehicles
191
+ </h3>
192
+ """,
193
+ unsafe_allow_html=True
194
+ )
195
 
196
+ # 4. Green time per direction
197
  base_time = 5
198
  time_per_vehicle = 1
199
+ max_time = 25
200
+ # Use the same formula applied earlier
201
+ green_times = [
202
+ min(base_time + int(st.session_state.counts[d] / 2) * time_per_vehicle, max_time)
203
+ for d, _ in st.session_state.sorted_directions
204
+ ]
205
+ green_df = pd.DataFrame({
206
+ "Direction": [d for d, _ in sorted_directions],
207
+ "Assigned Green Time (sec)": green_times
208
+ })
209
+ st.markdown("<br><h3 style='font-size: 24px; font-weight: bold;'>⏱️ Assigned Green Time</h3>" , unsafe_allow_html=True)
210
+ col1, col2, _ = st.columns([.3, .4, .3])
211
+ with col2:
212
+ st.dataframe(green_df.style.set_properties(**{
213
+ 'background-color': '#e8f5e9',
214
+ 'color': 'green',
215
+ 'font-size': '12px',
216
+ 'font-weight': 'bold',
217
+ 'text-align' : 'left'
218
+ }), use_container_width=True)
 
219
 
220
  # 5. Pie chart (optional)
221
  import pandas as pd
222
  df = pd.DataFrame.from_dict(st.session_state.counts, orient='index', columns=['Vehicles'])
223
  st.markdown("<h4 style='font-size: 20px; font-weight: bold;'>πŸ“ˆ Traffic Share by Direction</h4>", unsafe_allow_html=True)
224
+ fig2, ax2 = plt.subplots(figsize=(4, 4)) # Smaller size
225
+ ax2.pie(counts.values(), labels=counts.keys(), autopct='%1.1f%%', textprops={'fontsize': 8})
226
+ ax2.set_title("Traffic Distribution", fontsize=10)
227
+ col1, col2, _ = st.columns([.2, .4, .2])
228
+ with col2:
229
+ st.pyplot(fig2)
230
+
231
+ # 6. Waiting Time Calculation ---
232
+ st.markdown("<br>", unsafe_allow_html=True)
233
+ st.markdown("### ⏱️ Waiting Time Analysis")
234
+ # Use the already computed busiest direction
235
+ busiest_direction = busiest[0]
236
+
237
+ # Define green time per vehicle
238
+ time_per_vehicle = 1
239
+ # Initialize dictionary to store waiting times
240
+ waiting_times = {}
241
+
242
+ # Calculate waiting times for all directions except the busiest one
243
+ for direction in directions:
244
+ if direction == busiest_direction:
245
+ waiting_times[direction] = 0 # No wait for the first green
246
+ else:
247
+ # Waiting time is the sum of green times of all directions before this one (excluding busiest and current)
248
+ preceding_directions = [d for d, _ in st.session_state.sorted_directions if d != direction and d != busiest_direction]
249
+ wait = sum(min(5 + st.session_state.counts[d] * time_per_vehicle, 30) + 3 # green + yellow
250
+ for d in preceding_directions)
251
+ waiting_times[direction] = wait
252
+
253
+ # Display waiting times for each direction
254
+ waiting_time_data = pd.DataFrame({
255
+ "Direction": directions,
256
+ "Waiting Time (sec)": [waiting_times[direction] for direction in directions]
257
+ })
258
+
259
+ # Display waiting times in a table
260
+ # Show in small column
261
+ col1, col2, _ = st.columns([.3, .4, .3])
262
+ with col2:
263
+ st.dataframe(waiting_time_data.style.set_properties(**{
264
+ 'background-color': '#f3f4f6',
265
+ 'color': 'black',
266
+ 'font-size': '12px',
267
+ 'font-weight': 'bold'
268
+ }))
269
+
270
+ # Optionally, add a message for the waiting times
271
+ st.markdown("<br>", unsafe_allow_html=True)
272
+ st.markdown(
273
+ """
274
+ The waiting times represent the total waiting time for vehicles at each direction based on the vehicle counts in other directions.
275
+ The higher the vehicle count in other directions, the higher the waiting time for the current direction.
276
+ """
277
+ )
278
+ st.session_state.clear()