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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +93 -127
app.py CHANGED
@@ -1,174 +1,140 @@
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")
 
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.")