NaveenKumar5 commited on
Commit
876da31
·
verified ·
1 Parent(s): 87438ff

Create src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +114 -0
src/streamlit_app.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # src/streamlit_app.py
2
+ import streamlit as st
3
+ import cv2
4
+ import numpy as np
5
+ import tempfile
6
+ import os
7
+ import pandas as pd
8
+ from PIL import Image
9
+ import torch
10
+ from transformers import DetrImageProcessor, DetrForObjectDetection
11
+
12
+ # === Hugging Face DETR Configuration ===
13
+ processor = DetrImageProcessor.from_pretrained("NaveenKumar5/Solar_panel_fault_detection")
14
+ model = DetrForObjectDetection.from_pretrained("NaveenKumar5/Solar_panel_fault_detection")
15
+ model.eval()
16
+
17
+ # === Streamlit App Configuration ===
18
+ st.set_page_config(page_title="Solar Panel Fault Detection", layout="wide")
19
+ st.title("\U0001F50D Solar Panel Fault Detection (Hugging Face DETR)")
20
+ st.write("Upload a thermal video (MP4). Faults will be detected using your custom DETR model.")
21
+
22
+ # === Fault Detection Function ===
23
+ def detect_faults(frame, frame_idx, fps):
24
+ image = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
25
+ inputs = processor(images=image, return_tensors="pt")
26
+
27
+ with torch.no_grad():
28
+ outputs = model(**inputs)
29
+
30
+ target_sizes = torch.tensor([image.size[::-1]])
31
+ results = processor.post_process_object_detection(outputs, target_sizes=target_sizes, threshold=0.7)[0]
32
+
33
+ faults = []
34
+ for score, label, box in zip(results["scores"], results["labels"], results["boxes"]):
35
+ x1, y1, x2, y2 = map(int, box.tolist())
36
+ conf = score.item()
37
+ label_id = label.item()
38
+ label_name = f"class_{label_id}"
39
+
40
+ color = (0, 0, 255)
41
+ cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2)
42
+ cv2.putText(frame, f"{label_name} ({conf:.2f})", (x1, y1 - 5),
43
+ cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
44
+
45
+ faults.append({
46
+ "Frame": frame_idx,
47
+ "Time (s)": round(frame_idx / fps, 2),
48
+ "Fault Type": label_name,
49
+ "Confidence": round(conf, 2),
50
+ "Box": f"({x1},{y1},{x2},{y2})"
51
+ })
52
+ return frame, faults
53
+
54
+ # === Video Processing Function ===
55
+ def process_video(video_path):
56
+ cap = cv2.VideoCapture(video_path)
57
+ fps = int(cap.get(cv2.CAP_PROP_FPS))
58
+ total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
59
+ width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
60
+ height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
61
+
62
+ output_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4").name
63
+ writer = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*"mp4v"), fps, (width, height))
64
+
65
+ fault_log = []
66
+ progress = st.progress(0)
67
+
68
+ for frame_idx in range(total_frames):
69
+ ret, frame = cap.read()
70
+ if not ret:
71
+ break
72
+
73
+ if frame_idx % fps == 0:
74
+ frame, faults = detect_faults(frame, frame_idx, fps)
75
+ fault_log.extend(faults)
76
+
77
+ writer.write(frame)
78
+ progress.progress(min(frame_idx / total_frames, 1.0))
79
+
80
+ cap.release()
81
+ writer.release()
82
+ return output_path, fault_log
83
+
84
+ # === CSV Conversion ===
85
+ def convert_df(df):
86
+ return df.to_csv(index=False).encode('utf-8')
87
+
88
+ # === Streamlit UI ===
89
+ uploaded_file = st.file_uploader("\U0001F4E4 Upload thermal video", type=["mp4"])
90
+ if uploaded_file:
91
+ st.video(uploaded_file)
92
+
93
+ temp_input_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4").name
94
+ with open(temp_input_path, "wb") as f:
95
+ f.write(uploaded_file.read())
96
+
97
+ output_path, log = process_video(temp_input_path)
98
+
99
+ st.subheader("\U0001F9EA Processed Output")
100
+ st.video(output_path)
101
+
102
+ if log:
103
+ df = pd.DataFrame(log)
104
+ st.write("### \U0001F4CA Detected Faults Table")
105
+ st.dataframe(df)
106
+ st.download_button("\U0001F4E5 Download Fault Log CSV", convert_df(df), "fault_log.csv", "text/csv")
107
+ else:
108
+ st.success("\u2705 No faults detected.")
109
+
110
+ os.unlink(temp_input_path)
111
+ os.unlink(output_path)
112
+
113
+ st.markdown("---")
114
+ st.caption("Built with Streamlit + Hugging Face DETR + OpenCV")