Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import tempfile | |
| import os | |
| import pandas as pd | |
| import base64 | |
| from inference import InferencePipeline | |
| # === Streamlit App Configuration === | |
| st.set_page_config(page_title="Solar Panel Fault Detection", layout="wide") | |
| st.title("π Solar Panel Fault Detection (Roboflow Workflow)") | |
| st.write("Upload a thermal video (MP4). Faults will be detected using your custom Roboflow model.") | |
| # === Globals for Fault Logging === | |
| fault_log = [] | |
| # === Fault Handler Callback === | |
| def my_sink(result, video_frame): | |
| global fault_log | |
| if result.get("predictions"): | |
| frame_idx = result.get("frame_id", -1) | |
| timestamp = result.get("timestamp", -1.0) | |
| for pred in result["predictions"]: | |
| label = pred["class"] | |
| conf = round(pred["confidence"], 2) | |
| x, y, w, h = pred["x"], pred["y"], pred["width"], pred["height"] | |
| x1, y1 = int(x - w / 2), int(y - h / 2) | |
| x2, y2 = int(x + w / 2), int(y + h / 2) | |
| fault_log.append({ | |
| "Frame": frame_idx, | |
| "Time (s)": round(timestamp, 2), | |
| "Fault Type": label, | |
| "Confidence": conf, | |
| "Box": f"({x1},{y1},{x2},{y2})" | |
| }) | |
| # === CSV Conversion === | |
| def convert_df(df): | |
| return df.to_csv(index=False).encode("utf-8") | |
| # === Streamlit UI === | |
| uploaded_file = st.file_uploader("π€ Upload thermal video", type=["mp4"]) | |
| if uploaded_file: | |
| st.video(uploaded_file) | |
| # Save uploaded file temporarily | |
| temp_input_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4").name | |
| with open(temp_input_path, "wb") as f: | |
| f.write(uploaded_file.read()) | |
| st.info("β³ Running fault detection...") | |
| # Initialize and start the inference pipeline | |
| pipeline = InferencePipeline.init_with_workflow( | |
| api_key="dxkgGGHSZ3DI8XzVn29U", | |
| workspace_name="naveen-kumar-hnmil", | |
| workflow_id="custom-workflow", | |
| video_reference=temp_input_path, | |
| max_fps=0.5, | |
| on_prediction=my_sink | |
| # max_duration_seconds=30 # Optional: limit for testing | |
| ) | |
| pipeline.start() | |
| pipeline.join() | |
| # Display results | |
| if fault_log: | |
| df = pd.DataFrame(fault_log) | |
| st.subheader("π Detected Faults Table") | |
| st.dataframe(df) | |
| st.download_button( | |
| "π₯ Download Fault Log CSV", | |
| convert_df(df), | |
| "fault_log.csv", | |
| "text/csv" | |
| ) | |
| else: | |
| st.success("β No faults detected.") | |
| os.unlink(temp_input_path) | |
| st.markdown("---") | |
| st.caption("Built with Streamlit + Roboflow Inference SDK") | |