Spaces:
Sleeping
Sleeping
File size: 11,481 Bytes
f0f9dff f98a043 0ba77f1 f0f9dff debd205 0ba77f1 24fa59e f0f9dff 24fa59e 36fbec5 cac62cc 36fbec5 13a0ff7 d44cea7 cac62cc d44cea7 36fbec5 24c4f17 cac62cc 36fbec5 24c4f17 cac62cc d44cea7 cac62cc 36fbec5 24c4f17 36fbec5 9d79b23 24fa59e 24c4f17 0ba77f1 24fa59e 0ba77f1 cac62cc 24c4f17 cac62cc 36fbec5 24c4f17 f0f9dff 24fa59e f0f9dff 36fbec5 0ba77f1 24fa59e 36fbec5 24fa59e 36fbec5 24fa59e 13a0ff7 24c4f17 24fa59e 13a0ff7 24c4f17 13a0ff7 f0f9dff 36fbec5 0ba77f1 24fa59e 36fbec5 d44cea7 5c1fa0a 36fbec5 d44cea7 36fbec5 cac62cc 24fa59e cac62cc 24c4f17 cac62cc c0792b2 d44cea7 c0792b2 d44cea7 c0792b2 5c1fa0a c0792b2 5c1fa0a c0792b2 d44cea7 5c1fa0a d44cea7 c0792b2 5c1fa0a c0792b2 5c1fa0a c0792b2 5c1fa0a 0ba77f1 36fbec5 0ba77f1 24fa59e 36fbec5 d44cea7 24fa59e 24c4f17 d44cea7 36fbec5 d44cea7 36fbec5 d44cea7 36fbec5 d44cea7 36fbec5 d44cea7 36fbec5 d44cea7 36fbec5 d44cea7 36fbec5 d44cea7 24c4f17 36fbec5 d44cea7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
import streamlit as st
import cv2
import PIL.Image
from ultralytics import YOLO
import tempfile
import time
import requests
import numpy as np
import streamlink
# Page Config
st.set_page_config(page_title="AI Fire Watch", page_icon="🌍", layout="wide")
# Lighter Background CSS with Darker Text
st.markdown(
"""
<style>
.stApp {
background-color: #cdc0b0;
color: #1a1a1a;
}
h1 {
color: #1a1a1a;
}
.stTabs > div > button {
background-color: #e0e0e0;
color: #333333; /* Darker tab text */
font-weight: bold;
}
.stTabs > div > button:hover {
background-color: #d0d0d0;
color: #333333;
}
.stTabs > div > button[aria-selected="true"] {
background-color: #ffffff;
color: #333333;
}
.stButton > button {
background-color: #e0e0e0;
color: #1a1a1a;
font-weight: bold;
}
.stButton > button:hover {
background-color: #d0d0d0;
color: #1a1a1a;
}
/* Fix container height to prevent scrolling */
.main .block-container {
max-height: 100vh;
overflow-y: auto;
}
.stImage > img {
max-height: 50vh; /* Limit image height */
object-fit: contain;
}
</style>
""",
unsafe_allow_html=True
)
# Load Model
model_path = 'https://huggingface.co/spaces/tstone87/ccr-colorado/resolve/main/best.pt'
try:
model = YOLO(model_path)
except Exception as ex:
st.error(f"Model loading failed: {ex}")
st.stop()
# Initialize Session State
if 'monitoring' not in st.session_state:
st.session_state.monitoring = False
if 'current_webcam_url' not in st.session_state:
st.session_state.current_webcam_url = None
if 'yt_monitoring' not in st.session_state:
st.session_state.yt_monitoring = False
# Header
st.title("AI Fire Watch")
st.markdown("Monitor fire and smoke in real-time with AI vision models.")
# Tabs
tabs = st.tabs(["Upload", "Webcam", "YouTube"])
# Tab 1: Upload
with tabs[0]:
col1, col2 = st.columns([1, 1])
with col1:
st.markdown("**Add Your File**")
st.write("Upload an image or video to scan for fire or smoke.")
uploaded_file = st.file_uploader("", type=["jpg", "jpeg", "png", "mp4"], label_visibility="collapsed")
confidence = st.slider("Detection Threshold", 0.25, 1.0, 0.4, key="upload_conf")
with col2:
frame_placeholder = st.empty()
status_placeholder = st.empty()
if uploaded_file:
try:
file_type = uploaded_file.type.split('/')[0]
status_placeholder.write(f"Processing {file_type} file...")
if file_type == 'image':
image = PIL.Image.open(uploaded_file)
results = model.predict(image, conf=confidence)
detected_image = results[0].plot()[:, :, ::-1]
frame_placeholder.image(detected_image, use_column_width=True)
status_placeholder.write(f"Objects detected: {len(results[0].boxes)}")
elif file_type == 'video':
# Save uploaded file to temporary location
tfile = tempfile.NamedTemporaryFile(delete=False, suffix='.mp4')
tfile.write(uploaded_file.read())
tfile.close()
# Open video with OpenCV
cap = cv2.VideoCapture(tfile.name)
if not cap.isOpened():
status_placeholder.error("Failed to open video file.")
else:
frame_count = 0
while cap.isOpened():
ret, frame = cap.read()
if not ret:
status_placeholder.write(f"Finished processing video. Processed {frame_count} frames.")
break
results = model.predict(frame, conf=confidence)
detected_frame = results[0].plot()[:, :, ::-1]
frame_placeholder.image(detected_frame, use_column_width=True)
status_placeholder.write(f"Frame {frame_count}: Objects detected: {len(results[0].boxes)}")
frame_count += 1
time.sleep(0.05) # Control playback speed
cap.release()
# Clean up temporary file
import os
os.unlink(tfile.name)
except Exception as e:
status_placeholder.error(f"Error processing file: {str(e)}")
# Tab 2: Webcam
with tabs[1]:
col1, col2 = st.columns([1, 1])
with col1:
st.markdown("**Webcam Feed**")
st.write("Provide a webcam URL (image or video stream) to monitor for hazards.")
webcam_url = st.text_input("Webcam URL", "http://<your_webcam_ip>/current.jpg", label_visibility="collapsed")
confidence = st.slider("Detection Threshold", 0.25, 1.0, 0.4, key="webcam_conf")
refresh_rate = st.slider("Refresh Rate (seconds)", 1, 60, 30, key="webcam_rate")
start = st.button("Begin Monitoring", key="webcam_start")
stop = st.button("Stop Monitoring", key="webcam_stop")
if start:
st.session_state.monitoring = True
st.session_state.current_webcam_url = webcam_url
if stop or (st.session_state.monitoring and webcam_url != st.session_state.current_webcam_url):
st.session_state.monitoring = False
st.session_state.current_webcam_url = None
with col2:
frame_placeholder = st.empty()
status_placeholder = st.empty()
timer_placeholder = st.empty()
if st.session_state.monitoring and st.session_state.current_webcam_url:
# Try as video stream first
cap = cv2.VideoCapture(webcam_url)
is_video_stream = cap.isOpened()
if is_video_stream:
status_placeholder.write("Connected to video stream...")
while st.session_state.monitoring:
try:
ret, frame = cap.read()
if not ret:
status_placeholder.error("Video stream interrupted.")
break
results = model.predict(frame, conf=confidence)
detected_frame = results[0].plot()[:, :, ::-1]
frame_placeholder.image(detected_frame, use_column_width=True)
status_placeholder.write(f"Objects detected: {len(results[0].boxes)}")
time.sleep(0.1) # Fast update for video
except Exception as e:
status_placeholder.error(f"Video error: {e}")
st.session_state.monitoring = False
break
cap.release()
else:
# Image-based webcam
status_placeholder.write("Monitoring image-based webcam...")
while st.session_state.monitoring:
try:
start_time = time.time()
response = requests.get(webcam_url, timeout=5)
if response.status_code != 200:
status_placeholder.error(f"Fetch failed: HTTP {response.status_code}")
break
image_array = np.asarray(bytearray(response.content), dtype=np.uint8)
frame = cv2.imdecode(image_array, cv2.IMREAD_COLOR)
if frame is None:
status_placeholder.error("Image decoding failed.")
break
results = model.predict(frame, conf=confidence)
detected_frame = results[0].plot()[:, :, ::-1]
frame_placeholder.image(detected_frame, use_column_width=True)
status_placeholder.write(f"Objects detected: {len(results[0].boxes)}")
# Proper refresh timing for images
elapsed = time.time() - start_time
remaining = max(0, refresh_rate - elapsed)
for i in range(int(remaining), -1, -1):
if not st.session_state.monitoring:
break
timer_placeholder.write(f"Next scan: {i}s")
time.sleep(1)
except Exception as e:
status_placeholder.error(f"Image fetch error: {e}")
st.session_state.monitoring = False
break
if not st.session_state.monitoring:
timer_placeholder.write("Monitoring stopped.")
# Tab 3: YouTube
with tabs[2]:
col1, col2 = st.columns([1, 1])
with col1:
st.markdown("**YouTube Live**")
st.write("Enter a live YouTube URL to auto-analyze the stream.")
youtube_url = st.text_input("YouTube URL", "https://www.youtube.com/watch?v=<id>", label_visibility="collapsed")
confidence = st.slider("Detection Threshold", 0.25, 1.0, 0.4, key="yt_conf")
start_yt = st.button("Start Analysis", key="yt_start")
stop_yt = st.button("Stop Analysis", key="yt_stop")
if start_yt:
st.session_state.yt_monitoring = True
if stop_yt:
st.session_state.yt_monitoring = False
with col2:
frame_placeholder = st.empty()
status_placeholder = st.empty()
if st.session_state.yt_monitoring and youtube_url and youtube_url != "https://www.youtube.com/watch?v=<id>":
try:
status_placeholder.write("Initializing stream...")
streams = streamlink.streams(youtube_url)
if not streams:
status_placeholder.error("No streams found. Check if the URL is a live stream.")
else:
stream_url = streams["best"].url
cap = cv2.VideoCapture(stream_url)
if not cap.isOpened():
status_placeholder.error("Unable to open stream.")
else:
status_placeholder.write("Analyzing live stream...")
while st.session_state.yt_monitoring and cap.isOpened():
ret, frame = cap.read()
if not ret:
status_placeholder.error("Stream interrupted.")
break
results = model.predict(frame, conf=confidence)
detected_frame = results[0].plot()[:, :, ::-1]
frame_placeholder.image(detected_frame, use_column_width=True)
status_placeholder.write(f"Objects detected: {len(results[0].boxes)}")
time.sleep(0.1)
cap.release()
except Exception as e:
status_placeholder.error(f"Error: {e}")
st.session_state.yt_monitoring = False |