DSatishchandra commited on
Commit
f9291b6
Β·
verified Β·
1 Parent(s): 16d2833

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +112 -35
app.py CHANGED
@@ -1,6 +1,10 @@
1
  import gradio as gr
2
  import cv2
3
  import numpy as np
 
 
 
 
4
  from services.video_service import VideoService
5
  from services.detection_service import DetectionService
6
  from services.thermal_service import ThermalService
@@ -23,78 +27,151 @@ VIDEO_PATHS = {
23
  "Shadow/Dust Feed": "data/shadow_dust_issue.mp4",
24
  }
25
 
26
- def process_video(video_type, confidence_threshold=0.9):
27
- """Process the selected video feed and return results."""
 
 
 
 
 
 
 
 
 
 
 
28
  video_path = VIDEO_PATHS.get(video_type)
 
29
  if not video_path or not os.path.exists(video_path):
30
- return "Video file not found.", None, None
 
 
 
 
 
31
 
32
- # Load and process video
33
- frames = video_service.load_video(video_path)
34
- results = []
35
- output_frames = []
 
36
 
37
- for frame in frames:
38
- # Convert frame to PIL Image
39
  frame_pil = video_service.frame_to_pil(frame)
40
 
 
41
  if video_type == "Thermal Feed":
42
- # Detect overheating (hot spots)
43
  detections = thermal_service.detect_hotspots(frame_pil, detection_service, confidence_threshold)
44
  alert_type = "Overheating"
45
  elif video_type == "Shadow/Dust Feed":
46
- # Detect dusty or shaded panels
47
  detections = shadow_detection.detect_shadow_dust(frame_pil, detection_service, confidence_threshold)
48
  alert_type = "Shadow/Dust"
49
  else:
50
- # General object detection for day/night feeds
51
  detections = detection_service.detect_objects(frame_pil, confidence_threshold)
52
  alert_type = "General"
53
 
54
  # Draw detections on frame
55
  annotated_frame = video_service.draw_detections(frame, detections)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
  # Generate Salesforce case and notifications
58
- if detections:
59
  case_id = salesforce_dispatcher.create_case(
60
- subject=f"{alert_type} Detected in {video_type}",
61
  description=str(detections)
62
  )
63
  salesforce_dispatcher.send_email(
64
  to="admin@solarplant.com",
65
  subject=f"Alert: {alert_type} in {video_type}",
66
- body=f"Case ID: {case_id}\nDetails: {detections}"
67
  )
68
  salesforce_dispatcher.notify_security_team(
69
- message=f"Alert: {alert_type} detected in {video_type}. Case ID: {case_id}"
70
  )
71
 
72
- results.append(detections)
73
- output_frames.append(annotated_frame)
 
 
 
 
 
74
 
75
- # Save output video
76
- output_path = "output_annotated.mp4"
77
- video_service.save_video(output_frames, output_path)
 
 
 
 
 
 
78
 
79
- return str(results), output_path, None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
  # Gradio Interface
82
  with gr.Blocks() as demo:
83
  gr.Markdown("# Solar Panel Monitoring System")
84
- video_type = gr.Dropdown(
85
- choices=["Day Feed", "Night Feed", "Thermal Feed", "Shadow/Dust Feed"],
86
- label="Select Drone Feed"
87
- )
88
- confidence_threshold = gr.Slider(0.5, 1.0, value=0.9, label="Confidence Threshold")
89
- process_button = gr.Button("Process Video")
90
- output_text = gr.Textbox(label="Detection Results")
91
- output_video = gr.Video(label="Annotated Video")
92
- error_message = gr.Textbox(label="Error Message")
93
-
94
- process_button.click(
95
- fn=process_video,
 
 
 
 
 
 
 
 
 
 
96
  inputs=[video_type, confidence_threshold],
97
- outputs=[output_text, output_video, error_message]
 
98
  )
99
 
100
  demo.launch()
 
1
  import gradio as gr
2
  import cv2
3
  import numpy as np
4
+ import time
5
+ from datetime import datetime
6
+ from collections import deque, defaultdict
7
+ import matplotlib.pyplot as plt
8
  from services.video_service import VideoService
9
  from services.detection_service import DetectionService
10
  from services.thermal_service import ThermalService
 
27
  "Shadow/Dust Feed": "data/shadow_dust_issue.mp4",
28
  }
29
 
30
+ # State for live feed
31
+ class LiveFeedState:
32
+ def __init__(self):
33
+ self.anomaly_history = deque(maxlen=100) # Last 100 frames for trend
34
+ self.anomaly_types = defaultdict(int) # Count of each anomaly type
35
+ self.captured_events = deque(maxlen=5) # Last 5 events with frames
36
+ self.total_detected = 0 # Total anomalies detected
37
+ self.logs = deque(maxlen=10) # Last 10 log entries
38
+ self.frame_count = 0 # Frame counter
39
+
40
+ def live_feed_generator(video_type, confidence_threshold=0.9):
41
+ """Generator for live feed with real-time detection."""
42
+ state = LiveFeedState()
43
  video_path = VIDEO_PATHS.get(video_type)
44
+
45
  if not video_path or not os.path.exists(video_path):
46
+ yield gr.update(value="Video file not found."), None, None, None, None, None
47
+ return
48
+
49
+ cap = cv2.VideoCapture(video_path)
50
+ fps = cap.get(cv2.CAP_PROP_FPS)
51
+ frame_interval = 1 / fps # Time between frames for real-time simulation
52
 
53
+ while cap.isOpened():
54
+ ret, frame = cap.read()
55
+ if not ret:
56
+ cap.set(cv2.CAP_PROP_POS_FRAMES, 0) # Loop the video
57
+ continue
58
 
59
+ state.frame_count += 1
 
60
  frame_pil = video_service.frame_to_pil(frame)
61
 
62
+ # Perform detection based on video type
63
  if video_type == "Thermal Feed":
 
64
  detections = thermal_service.detect_hotspots(frame_pil, detection_service, confidence_threshold)
65
  alert_type = "Overheating"
66
  elif video_type == "Shadow/Dust Feed":
 
67
  detections = shadow_detection.detect_shadow_dust(frame_pil, detection_service, confidence_threshold)
68
  alert_type = "Shadow/Dust"
69
  else:
 
70
  detections = detection_service.detect_objects(frame_pil, confidence_threshold)
71
  alert_type = "General"
72
 
73
  # Draw detections on frame
74
  annotated_frame = video_service.draw_detections(frame, detections)
75
+ annotated_frame_rgb = cv2.cvtColor(annotated_frame, cv2.COLOR_BGR2RGB)
76
+
77
+ # Update state
78
+ num_anomalies = len(detections)
79
+ state.anomaly_history.append(num_anomalies)
80
+ state.total_detected += num_anomalies
81
+
82
+ # Update anomaly types
83
+ for detection in detections:
84
+ label = detection["label"]
85
+ state.anomaly_types[label] += 1
86
+
87
+ # Log detection
88
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
89
+ log_entry = f"{timestamp} - Frame {state.frame_count} - Anomalies: {num_anomalies}"
90
+ state.logs.append(log_entry)
91
+
92
+ # Capture events (frames with anomalies)
93
+ if num_anomalies > 0:
94
+ state.captured_events.append(annotated_frame_rgb)
95
 
96
  # Generate Salesforce case and notifications
97
+ if num_anomalies > 0:
98
  case_id = salesforce_dispatcher.create_case(
99
+ subject=f"{alert_type} Detected in {video_type} (Frame {state.frame_count})",
100
  description=str(detections)
101
  )
102
  salesforce_dispatcher.send_email(
103
  to="admin@solarplant.com",
104
  subject=f"Alert: {alert_type} in {video_type}",
105
+ body=f"Case ID: {case_id}\nDetails: {detections}\nFrame: {state.frame_count}"
106
  )
107
  salesforce_dispatcher.notify_security_team(
108
+ message=f"Alert: {alert_type} detected in {video_type}. Case ID: {case_id}, Frame: {state.frame_count}"
109
  )
110
 
111
+ # Generate live metrics
112
+ metrics = []
113
+ for detection in detections:
114
+ box = detection["box"]
115
+ coords = f"[{box['xmin']},{box['ymin']},{box['xmax']},{box['ymax']}]"
116
+ metrics.append(coords)
117
+ metrics_str = f"anomalies: {metrics}, total_detected: {state.total_detected}"
118
 
119
+ # Generate detection trend plot
120
+ plt.figure(figsize=(4, 2))
121
+ plt.plot(list(state.anomaly_history), marker='o')
122
+ plt.title("Anomalies Over Time")
123
+ plt.xlabel("Frame")
124
+ plt.ylabel("Count")
125
+ plt.grid(True)
126
+ trend_plot = plt.gcf()
127
+ plt.close()
128
 
129
+ # Generate anomaly types summary
130
+ anomaly_types_str = "\n".join([f"{k}: {v}" for k, v in state.anomaly_types.items()])
131
+
132
+ # Yield updated UI components
133
+ yield (
134
+ gr.update(value=annotated_frame_rgb), # Live Video Feed
135
+ gr.update(value=metrics_str), # Live Metrics
136
+ gr.update(value="\n".join(state.logs)), # Live Logs
137
+ gr.update(value=trend_plot), # Detection Trend
138
+ gr.update(value=anomaly_types_str), # Anomaly Types
139
+ gr.update(value=list(state.captured_events)) # Captured Events
140
+ )
141
+
142
+ # Simulate real-time by sleeping between frames
143
+ time.sleep(frame_interval)
144
+
145
+ cap.release()
146
 
147
  # Gradio Interface
148
  with gr.Blocks() as demo:
149
  gr.Markdown("# Solar Panel Monitoring System")
150
+ with gr.Row():
151
+ with gr.Column():
152
+ video_type = gr.Dropdown(
153
+ choices=["Day Feed", "Night Feed", "Thermal Feed", "Shadow/Dust Feed"],
154
+ label="Select Drone Feed",
155
+ value="Thermal Feed"
156
+ )
157
+ confidence_threshold = gr.Slider(0.5, 1.0, value=0.9, label="Confidence Threshold")
158
+ start_button = gr.Button("Start Live Feed")
159
+ with gr.Column():
160
+ live_feed = gr.Image(label="Live Video Feed", streaming=True)
161
+ with gr.Row():
162
+ with gr.Column():
163
+ live_metrics = gr.Textbox(label="Live Metrics")
164
+ live_logs = gr.Textbox(label="Live Logs")
165
+ with gr.Column():
166
+ detection_trend = gr.Plot(label="Detection Trend")
167
+ anomaly_types = gr.Textbox(label="Anomaly Types")
168
+ captured_events = gr.Gallery(label="Captured Events (Last 5)")
169
+
170
+ start_button.click(
171
+ fn=live_feed_generator,
172
  inputs=[video_type, confidence_threshold],
173
+ outputs=[live_feed, live_metrics, live_logs, detection_trend, anomaly_types, captured_events],
174
+ _js="() => {return [document.querySelector('select').value, document.querySelector('input[type=range]').value]}"
175
  )
176
 
177
  demo.launch()