Naveenkumar1546 commited on
Commit
2948299
·
verified ·
1 Parent(s): b4d7818

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +127 -93
app.py CHANGED
@@ -1,140 +1,174 @@
1
  import streamlit as st
 
 
2
  import cv2
3
  import numpy as np
4
  import tempfile
5
  import os
6
- import torch
7
- from ultralytics import YOLO
8
 
9
- # Set page config
10
  st.set_page_config(page_title="Solar Panel Fault Detection", layout="wide")
11
- st.title("Solar Panel Fault Detection (Optimized)")
12
- st.write("Upload a thermal video (MP4) to detect thermal, dust, and power generation faults.")
13
 
14
- # Load YOLO model
 
 
 
 
15
  @st.cache_resource
16
  def load_model():
17
- model = YOLO("yolov5s.pt") # Replace with your custom-trained model if available
18
- return model
19
-
20
- model = load_model()
21
-
22
- # Fault detection based on intensity simulation
23
- def detect_faults(frame, results):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  faults = {"Thermal Fault": False, "Dust Fault": False, "Power Generation Fault": False}
25
  annotated_frame = frame.copy()
26
-
27
- for result in results:
28
- boxes = result.boxes
29
- for box in boxes:
30
- x1, y1, x2, y2 = map(int, box.xyxy[0])
31
- conf = box.conf[0]
32
- cls = int(box.cls[0])
33
-
34
- # Simulated intensity-based fault logic
35
- roi = frame[y1:y2, x1:x2]
36
- if roi.size == 0:
37
- continue
38
- mean_intensity = np.mean(roi)
39
-
40
- if mean_intensity > 200:
41
- faults["Thermal Fault"] = True
42
- color = (255, 0, 0)
43
- label = "Thermal Fault"
44
- elif mean_intensity < 100:
45
- faults["Dust Fault"] = True
46
- color = (0, 255, 0)
47
- label = "Dust Fault"
48
- else:
49
- continue
50
-
51
- cv2.rectangle(annotated_frame, (x1, y1), (x2, y2), color, 2)
52
- cv2.putText(annotated_frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
53
-
54
- if faults["Thermal Fault"] or faults["Dust Fault"]:
55
- faults["Power Generation Fault"] = True
56
-
57
  return annotated_frame, faults
58
 
59
- # Video processing
60
  def process_video(video_path):
 
61
  cap = cv2.VideoCapture(video_path)
62
  if not cap.isOpened():
63
- st.error("Failed to open video.")
64
  return None, None
65
-
 
 
 
66
  fps = int(cap.get(cv2.CAP_PROP_FPS))
67
  total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
68
- width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
69
- height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
70
-
71
  output_path = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False).name
72
- out = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*"mp4v"), fps, (width, height))
73
-
74
- frame_count = 0
 
75
  video_faults = {"Thermal Fault": False, "Dust Fault": False, "Power Generation Fault": False}
76
- process_every_n_frames = fps # 1 frame per second
77
-
78
- with st.spinner("Processing video..."):
 
79
  progress = st.progress(0)
80
  while cap.isOpened():
81
  ret, frame = cap.read()
82
  if not ret:
83
  break
84
-
85
- if frame_count % process_every_n_frames == 0:
86
- resized = cv2.resize(frame, (640, 480)) # Resize for faster inference
87
- frame_rgb = cv2.cvtColor(resized, cv2.COLOR_BGR2RGB)
88
- results = model(frame_rgb, verbose=False)
89
-
90
- annotated_frame, faults = detect_faults(frame, results)
91
-
92
- for fault in video_faults:
93
- video_faults[fault] |= faults[fault]
94
- else:
95
- annotated_frame = frame # Keep original for non-processed frames
96
-
97
- out.write(annotated_frame)
 
 
98
  frame_count += 1
99
- progress.progress(min(frame_count / total_frames, 1.0))
100
-
101
  cap.release()
102
  out.release()
 
103
  return output_path, video_faults
104
 
105
  # File uploader
106
  uploaded_file = st.file_uploader("Upload a thermal video", type=["mp4"])
107
 
108
- if uploaded_file:
109
- temp_input_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4").name
110
- with open(temp_input_path, "wb") as f:
111
- f.write(uploaded_file.read())
112
-
113
- st.video(temp_input_path)
114
-
115
- output_path, video_faults = process_video(temp_input_path)
116
-
 
 
 
117
  if output_path:
118
- st.subheader("Detection Results")
119
- st.video(output_path)
120
- st.write("### Detected Faults:")
 
 
 
121
  for fault, detected in video_faults.items():
 
122
  color = "red" if detected else "green"
123
- st.markdown(f"- **{fault}**: <span style='color:{color}'>{'Detected' if detected else 'Not Detected'}</span>", unsafe_allow_html=True)
124
-
 
125
  if any(video_faults.values()):
126
  st.subheader("Recommendations")
127
  if video_faults["Thermal Fault"]:
128
- st.write("- Check for overheating components.")
129
  if video_faults["Dust Fault"]:
130
- st.write("- Clean dust from solar panel surface.")
131
  if video_faults["Power Generation Fault"]:
132
- st.write("- Investigate potential efficiency issues.")
133
  else:
134
- st.success("No faults detected. The system seems to be functioning properly.")
135
-
 
136
  os.unlink(output_path)
137
- os.unlink(temp_input_path)
 
 
138
 
 
139
  st.markdown("---")
140
- st.caption("Built with Streamlit + YOLOv5 (Ultralytics) for fast fault detection.")
 
1
  import streamlit as st
2
+ import torch
3
+ from transformers import DetrImageProcessor, DetrForObjectDetection
4
  import cv2
5
  import numpy as np
6
  import tempfile
7
  import os
 
 
8
 
9
+ # Set page configuration
10
  st.set_page_config(page_title="Solar Panel Fault Detection", layout="wide")
 
 
11
 
12
+ # Title and description
13
+ st.title("Solar Panel Fault Detection PoC")
14
+ st.write("Upload a thermal video (MP4) of a solar panel to detect thermal, dust, and power generation faults.")
15
+
16
+ # Load model and processor
17
  @st.cache_resource
18
  def load_model():
19
+ processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
20
+ model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
21
+ return processor, model
22
+
23
+ processor, model = load_model()
24
+
25
+ # Function to process frame and detect faults
26
+ def detect_faults(frame):
27
+ # Convert frame to RGB if necessary
28
+ if frame.shape[-1] == 4:
29
+ frame = frame[:, :, :3]
30
+
31
+ # Prepare frame for model
32
+ inputs = processor(images=frame, return_tensors="pt")
33
+
34
+ # Run inference
35
+ with torch.no_grad():
36
+ outputs = model(**inputs)
37
+
38
+ # Post-process outputs
39
+ target_sizes = torch.tensor([frame.shape[:2]])
40
+ results = processor.post_process_object_detection(outputs, target_sizes=target_sizes, threshold=0.9)[0]
41
+
42
+ # Initialize fault detection
43
  faults = {"Thermal Fault": False, "Dust Fault": False, "Power Generation Fault": False}
44
  annotated_frame = frame.copy()
45
+
46
+ # Analyze frame for faults
47
+ for score, label, box in zip(results["scores"], results["labels"], results["boxes"]):
48
+ box = [int(i) for i in box.tolist()]
49
+ # Simulate fault detection based on bounding box and pixel intensity
50
+ roi = frame[box[1]:box[3], box[0]:box[2]]
51
+ mean_intensity = np.mean(roi)
52
+
53
+ # Thermal Fault: High intensity (hotspot)
54
+ if mean_intensity > 200: # Adjust threshold based on thermal video scale
55
+ faults["Thermal Fault"] = True
56
+ cv2.rectangle(annotated_frame, (box[0], box[1]), (box[2], box[3]), (255, 0, 0), 2)
57
+ cv2.putText(annotated_frame, "Thermal Fault", (box[0], box[1]-10),
58
+ cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
59
+
60
+ # Dust Fault: Low intensity or irregular patterns
61
+ elif mean_intensity < 100: # Adjust threshold
62
+ faults["Dust Fault"] = True
63
+ cv2.rectangle(annotated_frame, (box[0], box[1]), (box[2], box[3]), (0, 255, 0), 2)
64
+ cv2.putText(annotated_frame, "Dust Fault", (box[0], box[1]-10),
65
+ cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
66
+
67
+ # Power Generation Fault: Any detected anomaly may indicate reduced efficiency
68
+ if faults["Thermal Fault"] or faults["Dust Fault"]:
69
+ faults["Power Generation Fault"] = True
70
+
 
 
 
 
 
71
  return annotated_frame, faults
72
 
73
+ # Function to process video and generate annotated output
74
  def process_video(video_path):
75
+ # Open video
76
  cap = cv2.VideoCapture(video_path)
77
  if not cap.isOpened():
78
+ st.error("Error: Could not open video file.")
79
  return None, None
80
+
81
+ # Get video properties
82
+ frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
83
+ frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
84
  fps = int(cap.get(cv2.CAP_PROP_FPS))
85
  total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
86
+
87
+ # Create temporary file for output video
 
88
  output_path = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False).name
89
+ fourcc = cv2.VideoWriter_fourcc(*"mp4v")
90
+ out = cv2.VideoWriter(output_path, fourcc, fps, (frame_width, frame_height))
91
+
92
+ # Initialize fault summary
93
  video_faults = {"Thermal Fault": False, "Dust Fault": False, "Power Generation Fault": False}
94
+
95
+ # Process each frame
96
+ frame_count = 0
97
+ with st.spinner("Analyzing video..."):
98
  progress = st.progress(0)
99
  while cap.isOpened():
100
  ret, frame = cap.read()
101
  if not ret:
102
  break
103
+
104
+ # Convert BGR to RGB
105
+ frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
106
+
107
+ # Detect faults in frame
108
+ annotated_frame, faults = detect_faults(frame_rgb)
109
+
110
+ # Update video faults
111
+ for fault in video_faults:
112
+ video_faults[fault] |= faults[fault]
113
+
114
+ # Convert back to BGR for writing
115
+ annotated_frame_bgr = cv2.cvtColor(annotated_frame, cv2.COLOR_RGB2BGR)
116
+ out.write(annotated_frame_bgr)
117
+
118
+ # Update progress
119
  frame_count += 1
120
+ progress.progress(frame_count / total_frames)
121
+
122
  cap.release()
123
  out.release()
124
+
125
  return output_path, video_faults
126
 
127
  # File uploader
128
  uploaded_file = st.file_uploader("Upload a thermal video", type=["mp4"])
129
 
130
+ if uploaded_file is not None:
131
+ # Save uploaded video to temporary file
132
+ tfile = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False)
133
+ tfile.write(uploaded_file.read())
134
+ tfile.close()
135
+
136
+ # Display uploaded video
137
+ st.video(tfile.name, format="video/mp4")
138
+
139
+ # Process video
140
+ output_path, video_faults = process_video(tfile.name)
141
+
142
  if output_path:
143
+ # Display results
144
+ st.subheader("Fault Detection Results")
145
+ st.video(output_path, format="video/mp4")
146
+
147
+ # Show fault summary
148
+ st.write("**Detected Faults in Video:**")
149
  for fault, detected in video_faults.items():
150
+ status = "Detected" if detected else "Not Detected"
151
  color = "red" if detected else "green"
152
+ st.markdown(f"- **{fault}**: <span style='color:{color}'>{status}</span>", unsafe_allow_html=True)
153
+
154
+ # Provide recommendations
155
  if any(video_faults.values()):
156
  st.subheader("Recommendations")
157
  if video_faults["Thermal Fault"]:
158
+ st.write("- **Thermal Fault**: Inspect for damaged components or overheating issues.")
159
  if video_faults["Dust Fault"]:
160
+ st.write("- **Dust Fault**: Schedule cleaning to remove dust accumulation.")
161
  if video_faults["Power Generation Fault"]:
162
+ st.write("- **Power Generation Fault**: Investigate efficiency issues due to detected faults.")
163
  else:
164
+ st.write("No faults detected. The solar panel appears to be functioning normally.")
165
+
166
+ # Clean up temporary files
167
  os.unlink(output_path)
168
+
169
+ # Clean up uploaded file
170
+ os.unlink(tfile.name)
171
 
172
+ # Footer
173
  st.markdown("---")
174
+ st.write("Built with Streamlit, Hugging Face Transformers, and OpenCV for Solar Panel Fault Detection PoC")