lokesh341 commited on
Commit
5f23738
·
1 Parent(s): 33a8589

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +151 -47
app.py CHANGED
@@ -4,6 +4,7 @@ import time
4
  import os
5
  import json
6
  import random
 
7
  from datetime import datetime
8
  from collections import Counter
9
  from services.video_service import get_next_video_frame, reset_video_index, preload_video, release_video
@@ -30,6 +31,13 @@ from services.plantation.plant_count import process_plants
30
  from services.plantation.plant_health import process_plant_health
31
  from services.plantation.missing_patch_check import process_missing_patches
32
 
 
 
 
 
 
 
 
33
  # Globals
34
  paused = False
35
  frame_rate = 0.5 # Process every 0.5 seconds for real-time feel
@@ -45,7 +53,7 @@ gps_coordinates = []
45
  video_loaded = False
46
  service_toggles = {
47
  "under_construction": False,
48
- "operations_maintenance": True, # Default to crack detection focus
49
  "road_safety": False,
50
  "plantation": False
51
  }
@@ -69,10 +77,12 @@ def initialize_video(video_file=None):
69
  if video_file is not None:
70
  video_path = video_file.name
71
  log_entries.append(f"Using uploaded video: {video_path}")
 
72
 
73
  status = preload_video(video_path)
74
  video_loaded = "Error" not in status
75
  log_entries.append(status)
 
76
  return status
77
 
78
  def toggle_service(service_name, value):
@@ -81,17 +91,20 @@ def toggle_service(service_name, value):
81
  """
82
  global service_toggles
83
  service_toggles[service_name] = value
84
- log_entries.append(f"{service_name.replace('_', ' ').title()} Services {'Enabled' if value else 'Disabled'}")
85
- return f"{service_name.replace('_', ' ').title()} Services: {'Enabled' if value else 'Disabled'}"
 
 
86
 
87
  def monitor_feed():
88
  """
89
- Main function to process video frames in real-time.
90
  """
91
  global paused, frame_count, last_frame, last_detections, last_timestamp, gps_coordinates, last_detected_images, video_loaded
92
 
93
  if not video_loaded:
94
  log_entries.append("Cannot start streaming: Video not loaded successfully.")
 
95
  return None, json.dumps({"error": "Video not loaded. Please upload a video file."}, indent=2), "\n".join(log_entries[-10:]), None, None, last_detected_images
96
 
97
  if paused and last_frame is not None:
@@ -102,54 +115,140 @@ def monitor_feed():
102
  frame = get_next_video_frame()
103
  except RuntimeError as e:
104
  log_entries.append(f"Error: {str(e)}")
 
105
  return None, json.dumps(last_detections, indent=2), "\n".join(log_entries[-10:]), None, None, last_detected_images
106
 
107
- # Initialize detected items list
 
108
  all_detected_items = []
 
 
 
 
 
109
 
110
- # Run services based on toggles
111
  if service_toggles["under_construction"]:
112
- earthwork_dets, frame = process_earthwork(frame)
113
- culvert_dets, frame = process_culverts(frame)
114
- bridge_pier_dets, frame = process_bridge_piers(frame)
115
- all_detected_items.extend(earthwork_dets + culvert_dets + bridge_pier_dets)
 
 
 
 
 
 
 
 
 
 
116
 
117
  if service_toggles["operations_maintenance"]:
118
- crack_items = detect_cracks_and_objects(frame)
119
- frame = overlay_boxes(frame, crack_items)
120
- pothole_dets, frame = process_potholes(frame)
121
- signage_dets, frame = process_signages(frame)
122
- all_detected_items.extend(crack_items + pothole_dets + signage_dets)
 
 
 
 
 
 
 
 
 
 
 
123
 
124
  if service_toggles["road_safety"]:
125
- barrier_dets, frame = process_barriers(frame)
126
- lighting_dets, frame = process_lighting(frame)
127
- accident_dets, frame = process_accident_spots(frame)
128
- all_detected_items.extend(barrier_dets + lighting_dets + accident_dets)
 
 
 
 
 
 
 
 
 
 
129
 
130
  if service_toggles["plantation"]:
131
- plant_dets, frame = process_plants(frame)
132
- health_dets, frame = process_plant_health(frame)
133
- missing_dets, frame = process_missing_patches(frame)
134
- all_detected_items.extend(plant_dets + health_dets + missing_dets)
135
-
136
- # Fallback: Run generic detection if no items detected
137
- if not all_detected_items:
138
- generic_dets, frame = process_generic(frame)
139
- all_detected_items.extend(generic_dets)
140
-
141
- # Optional: Run shadow detection
142
- shadow_results = detect_shadows(frame)
143
- shadow_dets = shadow_results["detections"]
144
- frame = shadow_results["frame"]
145
- all_detected_items.extend(shadow_dets)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
 
147
  # Optional: Run thermal processing if frame is grayscale (simulated check)
148
- if len(frame.shape) == 2: # Grayscale frame (simulating thermal input)
149
- thermal_results = process_thermal(frame)
150
- thermal_dets = thermal_results["detections"]
151
- frame = thermal_results["frame"]
152
- all_detected_items.extend(thermal_dets)
 
 
 
 
 
 
 
 
 
 
 
 
 
153
 
154
  # Save frame with overlays
155
  cv2.imwrite(TEMP_IMAGE_PATH, frame, [int(cv2.IMWRITE_JPEG_QUALITY), 95])
@@ -160,7 +259,7 @@ def monitor_feed():
160
  gps_coordinates.append(gps_coord)
161
 
162
  # Save frame if cracks are detected (only if operations_maintenance is enabled)
163
- if service_toggles["operations_maintenance"] and any(item['type'] == 'crack' for item in all_detected_items if 'type' in item):
164
  captured_frame_path = os.path.join(CAPTURED_FRAMES_DIR, f"crack_{frame_count}.jpg")
165
  cv2.imwrite(captured_frame_path, frame)
166
  last_detected_images.append(captured_frame_path)
@@ -177,7 +276,11 @@ def monitor_feed():
177
  }
178
 
179
  # Dispatch to Salesforce
180
- dispatch_to_salesforce(all_detections, all_detections["timestamp"])
 
 
 
 
181
 
182
  # Save annotated frame
183
  frame_path = os.path.join(OUTPUT_DIR, f"frame_{frame_count:04d}.jpg")
@@ -189,16 +292,17 @@ def monitor_feed():
189
  last_detections = metrics
190
 
191
  # Update logs and stats (focus on cracks if operations_maintenance is enabled)
192
- crack_detected = 0
193
  if service_toggles["operations_maintenance"]:
194
- crack_detected = len([item for item in all_detected_items if 'type' in item and item['type'] == 'crack'])
195
  crack_severity_all.extend([
196
  item['severity']
197
- for item in all_detected_items
198
- if 'type' in item and item['type'] == 'crack' and 'severity' in item
199
  ])
200
 
201
- log_entries.append(f"{last_timestamp} - Frame {frame_count} - Cracks: {crack_detected} - Total Detections: {len(all_detected_items)} - GPS: {gps_coord} - Avg Conf: {metrics['avg_confidence']:.2f}")
 
 
202
  crack_counts.append(crack_detected)
203
 
204
  if len(log_entries) > 100:
@@ -326,7 +430,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as app:
326
  uc_status = gr.Textbox(label="Under Construction Status", value="Under Construction Services: Disabled")
327
  with gr.Column():
328
  om_toggle = gr.Checkbox(label="Enable Operations Maintenance Services", value=service_toggles["operations_maintenance"])
329
- om_status = gr.Textbox(label="Operations Maintenance Status", value="Operations Maintenance Services: Enabled")
330
  with gr.Column():
331
  rs_toggle = gr.Checkbox(label="Enable Road Safety Services", value=service_toggles["road_safety"])
332
  rs_status = gr.Textbox(label="Road Safety Status", value="Road Safety Services: Disabled")
 
4
  import os
5
  import json
6
  import random
7
+ import logging
8
  from datetime import datetime
9
  from collections import Counter
10
  from services.video_service import get_next_video_frame, reset_video_index, preload_video, release_video
 
31
  from services.plantation.plant_health import process_plant_health
32
  from services.plantation.missing_patch_check import process_missing_patches
33
 
34
+ # Setup logging
35
+ logging.basicConfig(
36
+ filename="app.log",
37
+ level=logging.INFO,
38
+ format="%(asctime)s - %(levelname)s - %(message)s"
39
+ )
40
+
41
  # Globals
42
  paused = False
43
  frame_rate = 0.5 # Process every 0.5 seconds for real-time feel
 
53
  video_loaded = False
54
  service_toggles = {
55
  "under_construction": False,
56
+ "operations_maintenance": False,
57
  "road_safety": False,
58
  "plantation": False
59
  }
 
77
  if video_file is not None:
78
  video_path = video_file.name
79
  log_entries.append(f"Using uploaded video: {video_path}")
80
+ logging.info(f"Using uploaded video: {video_path}")
81
 
82
  status = preload_video(video_path)
83
  video_loaded = "Error" not in status
84
  log_entries.append(status)
85
+ logging.info(status)
86
  return status
87
 
88
  def toggle_service(service_name, value):
 
91
  """
92
  global service_toggles
93
  service_toggles[service_name] = value
94
+ status_msg = f"{service_name.replace('_', ' ').title()} Services {'Enabled' if value else 'Disabled'}"
95
+ log_entries.append(status_msg)
96
+ logging.info(status_msg)
97
+ return status_msg
98
 
99
  def monitor_feed():
100
  """
101
+ Main function to process video frames in real-time, showing only enabled service detections.
102
  """
103
  global paused, frame_count, last_frame, last_detections, last_timestamp, gps_coordinates, last_detected_images, video_loaded
104
 
105
  if not video_loaded:
106
  log_entries.append("Cannot start streaming: Video not loaded successfully.")
107
+ logging.error("Cannot start streaming: Video not loaded successfully.")
108
  return None, json.dumps({"error": "Video not loaded. Please upload a video file."}, indent=2), "\n".join(log_entries[-10:]), None, None, last_detected_images
109
 
110
  if paused and last_frame is not None:
 
115
  frame = get_next_video_frame()
116
  except RuntimeError as e:
117
  log_entries.append(f"Error: {str(e)}")
118
+ logging.error(f"Video Frame Error: {str(e)}")
119
  return None, json.dumps(last_detections, indent=2), "\n".join(log_entries[-10:]), None, None, last_detected_images
120
 
121
+ # Reset frame for overlay
122
+ original_frame = frame.copy()
123
  all_detected_items = []
124
+ display_items = [] # Items to display in the live feed
125
+ crack_items = [] # Track crack items separately for charts and gallery
126
+
127
+ # Counter for numbered labels, reset per frame
128
+ line_counter = 1
129
 
130
+ # Process enabled services
131
  if service_toggles["under_construction"]:
132
+ try:
133
+ earthwork_dets, _ = process_earthwork(original_frame.copy())
134
+ culvert_dets, _ = process_culverts(original_frame.copy())
135
+ bridge_pier_dets, _ = process_bridge_piers(original_frame.copy())
136
+ uc_items = earthwork_dets + culvert_dets + bridge_pier_dets
137
+ # Add numbered labels
138
+ for item in uc_items:
139
+ item["label"] = f"Line {line_counter} - {item.get('type', 'Unknown').capitalize()} (Conf: {item.get('confidence', 0):.2f})"
140
+ line_counter += 1
141
+ all_detected_items.extend(uc_items)
142
+ display_items.extend(uc_items)
143
+ except Exception as e:
144
+ log_entries.append(f"Under Construction Error: {str(e)}")
145
+ logging.error(f"Under Construction Error: {str(e)}")
146
 
147
  if service_toggles["operations_maintenance"]:
148
+ try:
149
+ crack_dets = detect_cracks_and_objects(original_frame.copy())
150
+ pothole_dets, _ = process_potholes(original_frame.copy())
151
+ signage_dets, _ = process_signages(original_frame.copy())
152
+ om_items = crack_dets + pothole_dets + signage_dets
153
+ # Add numbered labels
154
+ for item in om_items:
155
+ item["label"] = f"Line {line_counter} - {item.get('type', 'Unknown').capitalize()} (Conf: {item.get('confidence', 0):.2f})"
156
+ line_counter += 1
157
+ all_detected_items.extend(om_items)
158
+ display_items.extend(om_items)
159
+ # Track cracks for charts and gallery
160
+ crack_items = [item for item in om_items if item.get('type') == 'crack']
161
+ except Exception as e:
162
+ log_entries.append(f"Operations Maintenance Error: {str(e)}")
163
+ logging.error(f"Operations Maintenance Error: {str(e)}")
164
 
165
  if service_toggles["road_safety"]:
166
+ try:
167
+ barrier_dets, _ = process_barriers(original_frame.copy())
168
+ lighting_dets, _ = process_lighting(original_frame.copy())
169
+ accident_dets, _ = process_accident_spots(original_frame.copy())
170
+ rs_items = barrier_dets + lighting_dets + accident_dets
171
+ # Add numbered labels
172
+ for item in rs_items:
173
+ item["label"] = f"Line {line_counter} - {item.get('type', 'Unknown').replace('_', ' ').capitalize()} (Conf: {item.get('confidence', 0):.2f})"
174
+ line_counter += 1
175
+ all_detected_items.extend(rs_items)
176
+ display_items.extend(rs_items)
177
+ except Exception as e:
178
+ log_entries.append(f"Road Safety Error: {str(e)}")
179
+ logging.error(f"Road Safety Error: {str(e)}")
180
 
181
  if service_toggles["plantation"]:
182
+ try:
183
+ plant_dets, _ = process_plants(original_frame.copy())
184
+ health_dets, _ = process_plant_health(original_frame.copy())
185
+ missing_dets, _ = process_missing_patches(original_frame.copy())
186
+ pl_items = plant_dets + health_dets + missing_dets
187
+ # Add numbered labels
188
+ for item in pl_items:
189
+ label_type = item.get('type', 'Unknown')
190
+ if label_type == "plant" and "health" in item:
191
+ label_str = f"Line {line_counter} - Plant (Health: {item['health'].capitalize()})"
192
+ else:
193
+ label_str = f"Line {line_counter} - {label_type.replace('_', ' ').capitalize()}"
194
+ if "confidence" in item:
195
+ label_str += f" (Conf: {item['confidence']:.2f})"
196
+ item["label"] = label_str
197
+ line_counter += 1
198
+ all_detected_items.extend(pl_items)
199
+ display_items.extend(pl_items)
200
+ except Exception as e:
201
+ log_entries.append(f"Plantation Error: {str(e)}")
202
+ logging.error(f"Plantation Error: {str(e)}")
203
+
204
+ # Fallback: Run generic detection if no services are enabled
205
+ if not any(service_toggles.values()) or not all_detected_items:
206
+ try:
207
+ generic_dets, _ = process_generic(original_frame.copy())
208
+ # Add numbered labels
209
+ for item in generic_dets:
210
+ item["label"] = f"Line {line_counter} - {item.get('type', 'Unknown').capitalize()} (Conf: {item.get('confidence', 0):.2f})"
211
+ line_counter += 1
212
+ all_detected_items.extend(generic_dets)
213
+ display_items.extend(generic_dets)
214
+ except Exception as e:
215
+ log_entries.append(f"Generic Detection Error: {str(e)}")
216
+ logging.error(f"Generic Detection Error: {str(e)}")
217
+
218
+ # Optional: Run shadow detection (only log results for now)
219
+ try:
220
+ shadow_results = detect_shadows(original_frame.copy())
221
+ shadow_dets = shadow_results["detections"]
222
+ # Add numbered labels if shadows are to be displayed
223
+ if any(service_toggles.values()): # Only append if a service is enabled
224
+ for item in shadow_dets:
225
+ item["label"] = f"Line {line_counter} - Shadow (Conf: {item.get('confidence', 0):.2f})"
226
+ line_counter += 1
227
+ all_detected_items.extend(shadow_dets)
228
+ display_items.extend(shadow_dets)
229
+ except Exception as e:
230
+ log_entries.append(f"Shadow Detection Error: {str(e)}")
231
+ logging.error(f"Shadow Detection Error: {str(e)}")
232
 
233
  # Optional: Run thermal processing if frame is grayscale (simulated check)
234
+ if len(original_frame.shape) == 2:
235
+ try:
236
+ thermal_results = process_thermal(original_frame.copy())
237
+ thermal_dets = thermal_results["detections"]
238
+ # Add numbered labels
239
+ for item in thermal_dets:
240
+ item["label"] = f"Line {line_counter} - Thermal Anomaly (Conf: {item.get('confidence', 0):.2f})"
241
+ line_counter += 1
242
+ all_detected_items.extend(thermal_dets)
243
+ display_items.extend(thermal_dets)
244
+ except Exception as e:
245
+ log_entries.append(f"Thermal Processing Error: {str(e)}")
246
+ logging.error(f"Thermal Processing Error: {str(e)}")
247
+
248
+ # Overlay only the display_items on the frame
249
+ frame = original_frame.copy()
250
+ if display_items:
251
+ frame = overlay_boxes(frame, display_items)
252
 
253
  # Save frame with overlays
254
  cv2.imwrite(TEMP_IMAGE_PATH, frame, [int(cv2.IMWRITE_JPEG_QUALITY), 95])
 
259
  gps_coordinates.append(gps_coord)
260
 
261
  # Save frame if cracks are detected (only if operations_maintenance is enabled)
262
+ if service_toggles["operations_maintenance"] and crack_items:
263
  captured_frame_path = os.path.join(CAPTURED_FRAMES_DIR, f"crack_{frame_count}.jpg")
264
  cv2.imwrite(captured_frame_path, frame)
265
  last_detected_images.append(captured_frame_path)
 
276
  }
277
 
278
  # Dispatch to Salesforce
279
+ try:
280
+ dispatch_to_salesforce(all_detections, all_detections["timestamp"])
281
+ except Exception as e:
282
+ log_entries.append(f"Salesforce Dispatch Error: {str(e)}")
283
+ logging.error(f"Salesforce Dispatch Error: {str(e)}")
284
 
285
  # Save annotated frame
286
  frame_path = os.path.join(OUTPUT_DIR, f"frame_{frame_count:04d}.jpg")
 
292
  last_detections = metrics
293
 
294
  # Update logs and stats (focus on cracks if operations_maintenance is enabled)
295
+ crack_detected = len(crack_items)
296
  if service_toggles["operations_maintenance"]:
 
297
  crack_severity_all.extend([
298
  item['severity']
299
+ for item in crack_items
300
+ if 'severity' in item
301
  ])
302
 
303
+ log_msg = f"{last_timestamp} - Frame {frame_count} - Cracks: {crack_detected} - Total Displayed Detections: {len(display_items)} - GPS: {gps_coord} - Avg Conf: {metrics['avg_confidence']:.2f}"
304
+ log_entries.append(log_msg)
305
+ logging.info(log_msg)
306
  crack_counts.append(crack_detected)
307
 
308
  if len(log_entries) > 100:
 
430
  uc_status = gr.Textbox(label="Under Construction Status", value="Under Construction Services: Disabled")
431
  with gr.Column():
432
  om_toggle = gr.Checkbox(label="Enable Operations Maintenance Services", value=service_toggles["operations_maintenance"])
433
+ om_status = gr.Textbox(label="Operations Maintenance Status", value="Operations Maintenance Services: Disabled")
434
  with gr.Column():
435
  rs_toggle = gr.Checkbox(label="Enable Road Safety Services", value=service_toggles["road_safety"])
436
  rs_status = gr.Textbox(label="Road Safety Status", value="Road Safety Services: Disabled")