Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -3,9 +3,9 @@ import cv2
|
|
3 |
import PIL.Image
|
4 |
from ultralytics import YOLO
|
5 |
import tempfile
|
|
|
6 |
import requests
|
7 |
import numpy as np
|
8 |
-
import time
|
9 |
import streamlink # pip install streamlink
|
10 |
|
11 |
# -------------------------------
|
@@ -17,132 +17,123 @@ st.set_page_config(
|
|
17 |
initial_sidebar_state="expanded"
|
18 |
)
|
19 |
|
20 |
-
# IMPORTANT: Ensure the model
|
21 |
-
|
22 |
-
model_path = 'best.pt' # Change this to a valid path or direct URL to your model file
|
23 |
try:
|
24 |
model = YOLO(model_path)
|
25 |
except Exception as ex:
|
26 |
st.error(f"Unable to load model from: {model_path}")
|
27 |
st.error(ex)
|
28 |
-
st.stop() # Stop the app if the model
|
29 |
|
30 |
-
|
31 |
-
# App Title and Description
|
32 |
-
st.title("WildfireWatch: Detecting Wildfire using AI")
|
33 |
st.markdown("""
|
34 |
-
Wildfires are a major
|
35 |
-
|
|
|
|
|
36 |
""")
|
37 |
|
38 |
# -------------------------------
|
39 |
-
#
|
40 |
-
tabs = st.tabs(["File Upload", "Image URL", "YouTube Live Stream"])
|
41 |
|
42 |
# ===============================
|
43 |
-
# Tab 1: File Upload Mode
|
44 |
with tabs[0]:
|
45 |
-
st.header("
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
uploaded_file = st.file_uploader(
|
50 |
-
"Choose an image or video...",
|
51 |
-
type=["jpg", "jpeg", "png", "bmp", "webp", "mp4"]
|
52 |
-
)
|
53 |
file_confidence = st.slider("Select Detection Confidence", 25, 100, 40) / 100
|
54 |
-
|
55 |
if uploaded_file:
|
56 |
file_type = uploaded_file.type.split('/')[0]
|
57 |
-
if file_type ==
|
58 |
-
# Load image and allow toggle between Original and Detection result
|
59 |
image = PIL.Image.open(uploaded_file)
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
|
|
64 |
else:
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
for box in results[0].boxes:
|
71 |
-
col_result.write("Box (xywh):", box.xywh)
|
72 |
-
|
73 |
-
elif file_type == "video":
|
74 |
tfile = tempfile.NamedTemporaryFile(delete=False)
|
75 |
tfile.write(uploaded_file.read())
|
76 |
cap = cv2.VideoCapture(tfile.name)
|
77 |
-
|
78 |
-
if st.button("Detect Wildfire in Video", key="detect_file_video"):
|
79 |
while cap.isOpened():
|
80 |
ret, frame = cap.read()
|
81 |
if not ret:
|
82 |
break
|
83 |
results = model.predict(frame, conf=file_confidence)
|
84 |
-
|
85 |
-
|
86 |
time.sleep(0.05)
|
87 |
cap.release()
|
88 |
|
89 |
# ===============================
|
90 |
-
# Tab 2:
|
91 |
with tabs[1]:
|
92 |
-
st.header("
|
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 |
-
frame = cv2.imdecode(image_array, cv2.IMREAD_COLOR)
|
120 |
-
if frame is None:
|
121 |
-
col_result.error("Failed to decode image from URL.")
|
122 |
break
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
|
132 |
# ===============================
|
133 |
# Tab 3: YouTube Live Stream Mode
|
134 |
with tabs[2]:
|
135 |
-
st.header("
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
youtube_url = st.text_input(
|
140 |
-
"Enter YouTube Live URL",
|
141 |
-
value="https://www.youtube.com/watch?v=<live_stream_id>"
|
142 |
-
)
|
143 |
yt_confidence = st.slider("Select Detection Confidence", 25, 100, 40, key="yt_conf") / 100
|
144 |
start_yt = st.button("Start Live Detection", key="start_yt")
|
145 |
-
|
146 |
if start_yt:
|
147 |
try:
|
148 |
streams = streamlink.streams(youtube_url)
|
@@ -158,17 +149,17 @@ with tabs[2]:
|
|
158 |
if not cap.isOpened():
|
159 |
st.error("Unable to open YouTube live stream.")
|
160 |
else:
|
161 |
-
|
162 |
-
while cap.isOpened() and not
|
163 |
ret, frame = cap.read()
|
164 |
if not ret:
|
165 |
-
|
166 |
break
|
167 |
results = model.predict(frame, conf=yt_confidence)
|
168 |
-
|
169 |
-
|
170 |
time.sleep(0.05)
|
171 |
-
|
172 |
cap.release()
|
173 |
except Exception as e:
|
174 |
st.error(f"Error processing YouTube stream: {e}")
|
|
|
3 |
import PIL.Image
|
4 |
from ultralytics import YOLO
|
5 |
import tempfile
|
6 |
+
import time
|
7 |
import requests
|
8 |
import numpy as np
|
|
|
9 |
import streamlink # pip install streamlink
|
10 |
|
11 |
# -------------------------------
|
|
|
17 |
initial_sidebar_state="expanded"
|
18 |
)
|
19 |
|
20 |
+
# IMPORTANT: Ensure the model URL returns the raw .pt file. Otherwise, use a local path.
|
21 |
+
model_path = 'https://huggingface.co/spaces/ankitkupadhyay/fire_and_smoke/resolve/main/best.pt'
|
|
|
22 |
try:
|
23 |
model = YOLO(model_path)
|
24 |
except Exception as ex:
|
25 |
st.error(f"Unable to load model from: {model_path}")
|
26 |
st.error(ex)
|
27 |
+
st.stop() # Stop the app if the model cannot load
|
28 |
|
29 |
+
st.title("WildfireWatch: Detecting Fire and Smoke using AI")
|
|
|
|
|
30 |
st.markdown("""
|
31 |
+
Wildfires and smoke are a major threat. This app uses a YOLOv8 model to detect fire/smoke in:
|
32 |
+
- Uploaded images or videos,
|
33 |
+
- Webcam snapshots or live streams,
|
34 |
+
- YouTube live streams.
|
35 |
""")
|
36 |
|
37 |
# -------------------------------
|
38 |
+
# Create three tabs for different modes
|
39 |
+
tabs = st.tabs(["File Upload", "Webcam / Image URL", "YouTube Live Stream"])
|
40 |
|
41 |
# ===============================
|
42 |
+
# Tab 1: File Upload Mode
|
43 |
with tabs[0]:
|
44 |
+
st.header("File Upload Mode")
|
45 |
+
col_left, col_right = st.columns(2)
|
46 |
+
with col_left:
|
47 |
+
uploaded_file = st.file_uploader("Choose an image or video...", type=["jpg", "jpeg", "png", "bmp", "webp", "mp4"])
|
|
|
|
|
|
|
|
|
48 |
file_confidence = st.slider("Select Detection Confidence", 25, 100, 40) / 100
|
49 |
+
display_mode = st.radio("Display Mode", options=["Detection", "Original"], index=0)
|
50 |
if uploaded_file:
|
51 |
file_type = uploaded_file.type.split('/')[0]
|
52 |
+
if file_type == 'image':
|
|
|
53 |
image = PIL.Image.open(uploaded_file)
|
54 |
+
col_left.image(image, caption="Uploaded Image", use_column_width=True)
|
55 |
+
results = model.predict(image, conf=file_confidence)
|
56 |
+
detected_image = results[0].plot()[:, :, ::-1]
|
57 |
+
if display_mode == "Detection":
|
58 |
+
col_right.image(detected_image, caption="Detection Result", use_column_width=True)
|
59 |
else:
|
60 |
+
col_right.image(image, caption="Original Image", use_column_width=True)
|
61 |
+
with col_right.expander("Detection Details"):
|
62 |
+
for box in results[0].boxes:
|
63 |
+
st.write("Box (xywh):", box.xywh)
|
64 |
+
elif file_type == 'video':
|
|
|
|
|
|
|
|
|
65 |
tfile = tempfile.NamedTemporaryFile(delete=False)
|
66 |
tfile.write(uploaded_file.read())
|
67 |
cap = cv2.VideoCapture(tfile.name)
|
68 |
+
if st.button("Start Video Detection"):
|
|
|
69 |
while cap.isOpened():
|
70 |
ret, frame = cap.read()
|
71 |
if not ret:
|
72 |
break
|
73 |
results = model.predict(frame, conf=file_confidence)
|
74 |
+
detected_frame = results[0].plot()[:, :, ::-1]
|
75 |
+
col_right.image(detected_frame, caption="Detection Frame", channels="BGR", use_column_width=True)
|
76 |
time.sleep(0.05)
|
77 |
cap.release()
|
78 |
|
79 |
# ===============================
|
80 |
+
# Tab 2: Webcam / Image URL Mode
|
81 |
with tabs[1]:
|
82 |
+
st.header("Webcam / Image URL Mode")
|
83 |
+
col_left, col_right = st.columns(2)
|
84 |
+
with col_left:
|
85 |
+
# Enter a webcam snapshot URL (e.g. an updating JPEG) or a live stream URL
|
86 |
+
webcam_url = st.text_input("Enter Webcam URL", value="http://<your_webcam_ip>/current.jpg")
|
87 |
+
webcam_confidence = st.slider("Select Detection Confidence", 25, 100, 40, key="webcam_conf") / 100
|
88 |
+
input_mode = st.radio("Input Mode", options=["Snapshot (Updating Image)", "Live Stream"], index=0)
|
89 |
+
start_webcam = st.button("Start Detection", key="start_webcam")
|
90 |
+
if start_webcam:
|
91 |
+
if input_mode == "Snapshot (Updating Image)":
|
92 |
+
placeholder = col_right.empty()
|
93 |
+
# Loop to periodically fetch the snapshot
|
94 |
+
while True:
|
95 |
+
try:
|
96 |
+
response = requests.get(webcam_url, timeout=5)
|
97 |
+
image_array = np.asarray(bytearray(response.content), dtype=np.uint8)
|
98 |
+
frame = cv2.imdecode(image_array, cv2.IMREAD_COLOR)
|
99 |
+
if frame is None:
|
100 |
+
col_right.error("Failed to decode image from URL.")
|
101 |
+
break
|
102 |
+
results = model.predict(frame, conf=webcam_confidence)
|
103 |
+
detected_frame = results[0].plot()[:, :, ::-1]
|
104 |
+
placeholder.image(detected_frame, channels="BGR", use_column_width=True)
|
105 |
+
time.sleep(1) # Adjust refresh rate as needed
|
106 |
+
st.experimental_rerun()
|
107 |
+
except Exception as e:
|
108 |
+
col_right.error(f"Error fetching image: {e}")
|
|
|
|
|
|
|
109 |
break
|
110 |
+
else:
|
111 |
+
cap = cv2.VideoCapture(webcam_url)
|
112 |
+
if not cap.isOpened():
|
113 |
+
col_right.error("Unable to open webcam stream. Check the URL and network connectivity.")
|
114 |
+
else:
|
115 |
+
stop_button = st.button("Stop Live Detection", key="stop_webcam")
|
116 |
+
while cap.isOpened() and not stop_button:
|
117 |
+
ret, frame = cap.read()
|
118 |
+
if not ret:
|
119 |
+
col_right.error("Failed to retrieve frame from stream.")
|
120 |
+
break
|
121 |
+
results = model.predict(frame, conf=webcam_confidence)
|
122 |
+
detected_frame = results[0].plot()[:, :, ::-1]
|
123 |
+
col_right.image(detected_frame, channels="BGR", use_column_width=True)
|
124 |
+
time.sleep(0.05)
|
125 |
+
stop_button = st.button("Stop Live Detection", key="stop_webcam_loop")
|
126 |
+
cap.release()
|
127 |
|
128 |
# ===============================
|
129 |
# Tab 3: YouTube Live Stream Mode
|
130 |
with tabs[2]:
|
131 |
+
st.header("YouTube Live Stream Mode")
|
132 |
+
col_left, col_right = st.columns(2)
|
133 |
+
with col_left:
|
134 |
+
youtube_url = st.text_input("Enter YouTube Live URL", value="https://www.youtube.com/watch?v=<live_stream_id>")
|
|
|
|
|
|
|
|
|
135 |
yt_confidence = st.slider("Select Detection Confidence", 25, 100, 40, key="yt_conf") / 100
|
136 |
start_yt = st.button("Start Live Detection", key="start_yt")
|
|
|
137 |
if start_yt:
|
138 |
try:
|
139 |
streams = streamlink.streams(youtube_url)
|
|
|
149 |
if not cap.isOpened():
|
150 |
st.error("Unable to open YouTube live stream.")
|
151 |
else:
|
152 |
+
stop_yt = st.button("Stop Live Detection", key="stop_yt")
|
153 |
+
while cap.isOpened() and not stop_yt:
|
154 |
ret, frame = cap.read()
|
155 |
if not ret:
|
156 |
+
col_right.error("Failed to retrieve frame from YouTube stream.")
|
157 |
break
|
158 |
results = model.predict(frame, conf=yt_confidence)
|
159 |
+
detected_frame = results[0].plot()[:, :, ::-1]
|
160 |
+
col_right.image(detected_frame, channels="BGR", use_column_width=True)
|
161 |
time.sleep(0.05)
|
162 |
+
stop_yt = st.button("Stop Live Detection", key="stop_yt_loop")
|
163 |
cap.release()
|
164 |
except Exception as e:
|
165 |
st.error(f"Error processing YouTube stream: {e}")
|