Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -19,16 +19,17 @@ def load_model():
|
|
19 |
|
20 |
model = load_model()
|
21 |
|
22 |
-
# Fault detection
|
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 |
roi = frame[y1:y2, x1:x2]
|
@@ -47,13 +48,20 @@ def detect_faults(frame, results):
|
|
47 |
else:
|
48 |
continue
|
49 |
|
50 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
overlay = annotated_frame.copy()
|
52 |
alpha = 0.3
|
53 |
cv2.rectangle(overlay, (x1, y1), (x2, y2), color, -1)
|
54 |
cv2.addWeighted(overlay, alpha, annotated_frame, 1 - alpha, 0, annotated_frame)
|
55 |
-
|
56 |
-
# Border and label
|
57 |
cv2.rectangle(annotated_frame, (x1, y1), (x2, y2), color, 2)
|
58 |
cv2.putText(annotated_frame, f"{label} ({mean_intensity:.1f})", (x1, y1 - 10),
|
59 |
cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
|
@@ -61,14 +69,14 @@ def detect_faults(frame, results):
|
|
61 |
if faults["Thermal Fault"] or faults["Dust Fault"]:
|
62 |
faults["Power Generation Fault"] = True
|
63 |
|
64 |
-
return annotated_frame, faults
|
65 |
|
66 |
# Video processing
|
67 |
def process_video(video_path):
|
68 |
cap = cv2.VideoCapture(video_path)
|
69 |
if not cap.isOpened():
|
70 |
st.error("Failed to open video.")
|
71 |
-
return None, None
|
72 |
|
73 |
fps = int(cap.get(cv2.CAP_PROP_FPS))
|
74 |
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
|
@@ -80,6 +88,7 @@ def process_video(video_path):
|
|
80 |
|
81 |
frame_count = 0
|
82 |
video_faults = {"Thermal Fault": False, "Dust Fault": False, "Power Generation Fault": False}
|
|
|
83 |
process_every_n_frames = fps # 1 frame per second
|
84 |
|
85 |
with st.spinner("Processing video..."):
|
@@ -90,16 +99,17 @@ def process_video(video_path):
|
|
90 |
break
|
91 |
|
92 |
if frame_count % process_every_n_frames == 0:
|
93 |
-
resized = cv2.resize(frame, (640, 480))
|
94 |
frame_rgb = cv2.cvtColor(resized, cv2.COLOR_BGR2RGB)
|
95 |
results = model(frame_rgb, verbose=False)
|
96 |
|
97 |
-
annotated_frame, faults = detect_faults(frame, results)
|
|
|
98 |
|
99 |
for fault in video_faults:
|
100 |
video_faults[fault] |= faults[fault]
|
101 |
else:
|
102 |
-
annotated_frame = frame
|
103 |
|
104 |
out.write(annotated_frame)
|
105 |
frame_count += 1
|
@@ -107,7 +117,7 @@ def process_video(video_path):
|
|
107 |
|
108 |
cap.release()
|
109 |
out.release()
|
110 |
-
return output_path, video_faults
|
111 |
|
112 |
# File uploader
|
113 |
uploaded_file = st.file_uploader("Upload a thermal video", type=["mp4"])
|
@@ -119,7 +129,7 @@ if uploaded_file:
|
|
119 |
|
120 |
st.video(temp_input_path)
|
121 |
|
122 |
-
output_path, video_faults = process_video(temp_input_path)
|
123 |
|
124 |
if output_path:
|
125 |
st.subheader("Detection Results")
|
@@ -140,6 +150,19 @@ if uploaded_file:
|
|
140 |
else:
|
141 |
st.success("No faults detected. The system seems to be functioning properly.")
|
142 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
os.unlink(output_path)
|
144 |
os.unlink(temp_input_path)
|
145 |
|
|
|
19 |
|
20 |
model = load_model()
|
21 |
|
22 |
+
# Fault detection with frame & location tracking
|
23 |
+
def detect_faults(frame, results, frame_number):
|
24 |
faults = {"Thermal Fault": False, "Dust Fault": False, "Power Generation Fault": False}
|
25 |
+
fault_locations = []
|
26 |
annotated_frame = frame.copy()
|
27 |
|
28 |
for result in results:
|
29 |
boxes = result.boxes
|
30 |
for box in boxes:
|
31 |
x1, y1, x2, y2 = map(int, box.xyxy[0])
|
32 |
+
conf = float(box.conf[0])
|
33 |
cls = int(box.cls[0])
|
34 |
|
35 |
roi = frame[y1:y2, x1:x2]
|
|
|
48 |
else:
|
49 |
continue
|
50 |
|
51 |
+
# Track location
|
52 |
+
fault_locations.append({
|
53 |
+
"frame": frame_number,
|
54 |
+
"label": label,
|
55 |
+
"confidence": round(conf, 2),
|
56 |
+
"intensity": round(mean_intensity, 2),
|
57 |
+
"box": (x1, y1, x2, y2)
|
58 |
+
})
|
59 |
+
|
60 |
+
# Annotate
|
61 |
overlay = annotated_frame.copy()
|
62 |
alpha = 0.3
|
63 |
cv2.rectangle(overlay, (x1, y1), (x2, y2), color, -1)
|
64 |
cv2.addWeighted(overlay, alpha, annotated_frame, 1 - alpha, 0, annotated_frame)
|
|
|
|
|
65 |
cv2.rectangle(annotated_frame, (x1, y1), (x2, y2), color, 2)
|
66 |
cv2.putText(annotated_frame, f"{label} ({mean_intensity:.1f})", (x1, y1 - 10),
|
67 |
cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
|
|
|
69 |
if faults["Thermal Fault"] or faults["Dust Fault"]:
|
70 |
faults["Power Generation Fault"] = True
|
71 |
|
72 |
+
return annotated_frame, faults, fault_locations
|
73 |
|
74 |
# Video processing
|
75 |
def process_video(video_path):
|
76 |
cap = cv2.VideoCapture(video_path)
|
77 |
if not cap.isOpened():
|
78 |
st.error("Failed to open video.")
|
79 |
+
return None, None, None
|
80 |
|
81 |
fps = int(cap.get(cv2.CAP_PROP_FPS))
|
82 |
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
|
|
|
88 |
|
89 |
frame_count = 0
|
90 |
video_faults = {"Thermal Fault": False, "Dust Fault": False, "Power Generation Fault": False}
|
91 |
+
all_fault_locations = []
|
92 |
process_every_n_frames = fps # 1 frame per second
|
93 |
|
94 |
with st.spinner("Processing video..."):
|
|
|
99 |
break
|
100 |
|
101 |
if frame_count % process_every_n_frames == 0:
|
102 |
+
resized = cv2.resize(frame, (640, 480))
|
103 |
frame_rgb = cv2.cvtColor(resized, cv2.COLOR_BGR2RGB)
|
104 |
results = model(frame_rgb, verbose=False)
|
105 |
|
106 |
+
annotated_frame, faults, locations = detect_faults(frame, results, frame_count)
|
107 |
+
all_fault_locations.extend(locations)
|
108 |
|
109 |
for fault in video_faults:
|
110 |
video_faults[fault] |= faults[fault]
|
111 |
else:
|
112 |
+
annotated_frame = frame
|
113 |
|
114 |
out.write(annotated_frame)
|
115 |
frame_count += 1
|
|
|
117 |
|
118 |
cap.release()
|
119 |
out.release()
|
120 |
+
return output_path, video_faults, all_fault_locations
|
121 |
|
122 |
# File uploader
|
123 |
uploaded_file = st.file_uploader("Upload a thermal video", type=["mp4"])
|
|
|
129 |
|
130 |
st.video(temp_input_path)
|
131 |
|
132 |
+
output_path, video_faults, fault_locations = process_video(temp_input_path)
|
133 |
|
134 |
if output_path:
|
135 |
st.subheader("Detection Results")
|
|
|
150 |
else:
|
151 |
st.success("No faults detected. The system seems to be functioning properly.")
|
152 |
|
153 |
+
# Display fault locations
|
154 |
+
if fault_locations:
|
155 |
+
st.subheader("📍 Fault Locations in Video")
|
156 |
+
st.dataframe([
|
157 |
+
{
|
158 |
+
"Frame": loc["frame"],
|
159 |
+
"Fault Type": loc["label"],
|
160 |
+
"Confidence": loc["confidence"],
|
161 |
+
"Intensity": loc["intensity"],
|
162 |
+
"Box": f"{loc['box']}"
|
163 |
+
} for loc in fault_locations
|
164 |
+
])
|
165 |
+
|
166 |
os.unlink(output_path)
|
167 |
os.unlink(temp_input_path)
|
168 |
|