tstone87 commited on
Commit
24fa59e
·
verified ·
1 Parent(s): debd205

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +93 -127
app.py CHANGED
@@ -6,160 +6,126 @@ import tempfile
6
  import time
7
  import requests
8
  import numpy as np
9
- import streamlink # pip install streamlink
10
 
11
- # -------------------------------
12
- # Page & Model Setup
13
- st.set_page_config(
14
- page_title="WildfireWatch",
15
- page_icon="🔥",
16
- layout="wide",
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)
140
- if not streams:
141
- st.error("No streams found. Please check the URL or ensure the stream is live.")
 
 
 
 
 
 
 
 
 
 
 
142
  else:
143
- best_stream = streams.get("best")
144
- if best_stream is None:
145
- st.error("No suitable stream found.")
146
- else:
147
- stream_url = best_stream.to_url()
148
- cap = cv2.VideoCapture(stream_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}")
 
6
  import time
7
  import requests
8
  import numpy as np
9
+ import streamlink
10
 
11
+ # Page Config
12
+ st.set_page_config(page_title="WildfireWatch", page_icon="🔥", layout="wide")
 
 
 
 
 
 
13
 
14
+ # Load Model
15
  model_path = 'https://huggingface.co/spaces/ankitkupadhyay/fire_and_smoke/resolve/main/best.pt'
16
  try:
17
  model = YOLO(model_path)
18
  except Exception as ex:
19
+ st.error(f"Model loading failed: {ex}")
20
+ st.stop()
 
21
 
22
+ # Minimalist Header
23
+ st.title("WildfireWatch")
24
+ st.markdown("AI-powered detection of fire and smoke.")
 
 
 
 
25
 
26
+ # Tabs
27
+ tabs = st.tabs(["Upload", "Webcam", "YouTube"])
 
28
 
29
+ # Tab 1: File Upload
 
30
  with tabs[0]:
31
+ col1, col2 = st.columns([1, 1])
32
+ with col1:
33
+ st.markdown("**Upload an image or video**")
34
+ uploaded_file = st.file_uploader("", type=["jpg", "jpeg", "png", "mp4"], label_visibility="collapsed")
35
+ confidence = st.slider("Confidence", 0.25, 1.0, 0.4, key="upload_conf")
36
+ with col2:
37
+ if uploaded_file:
38
+ file_type = uploaded_file.type.split('/')[0]
39
+ if file_type == 'image':
40
+ image = PIL.Image.open(uploaded_file)
41
+ results = model.predict(image, conf=confidence)
42
+ detected_image = results[0].plot()[:, :, ::-1]
43
+ st.image(detected_image, use_column_width=True)
44
+ st.write(f"Detections: {len(results[0].boxes)}")
45
+ elif file_type == 'video':
46
+ tfile = tempfile.NamedTemporaryFile(delete=False)
47
+ tfile.write(uploaded_file.read())
48
+ cap = cv2.VideoCapture(tfile.name)
49
+ frame_placeholder = st.empty()
 
 
 
 
 
 
50
  while cap.isOpened():
51
  ret, frame = cap.read()
52
  if not ret:
53
  break
54
+ results = model.predict(frame, conf=confidence)
55
  detected_frame = results[0].plot()[:, :, ::-1]
56
+ frame_placeholder.image(detected_frame, use_column_width=True)
57
  time.sleep(0.05)
58
  cap.release()
59
 
60
+ # Tab 2: Webcam / Image URL
 
61
  with tabs[1]:
62
+ col1, col2 = st.columns([1, 1])
63
+ with col1:
64
+ st.markdown("**Webcam snapshot or stream**")
65
+ webcam_url = st.text_input("URL", "http://<your_webcam_ip>/current.jpg", label_visibility="collapsed")
66
+ confidence = st.slider("Confidence", 0.25, 1.0, 0.4, key="webcam_conf")
67
+ mode = st.radio("", ["Snapshot", "Stream"], label_visibility="collapsed")
68
+ start = st.button("Start", key="webcam_start")
69
+ with col2:
70
+ if start:
71
+ if mode == "Snapshot":
72
+ placeholder = st.empty()
73
+ timer_placeholder = st.empty()
74
+ refresh_interval = 5 # seconds
75
+ while True:
76
+ start_time = time.time()
77
+ try:
78
+ response = requests.get(webcam_url, timeout=5)
79
+ image_array = np.asarray(bytearray(response.content), dtype=np.uint8)
80
+ frame = cv2.imdecode(image_array, cv2.IMREAD_COLOR)
81
+ results = model.predict(frame, conf=confidence)
82
+ detected_frame = results[0].plot()[:, :, ::-1]
83
+ placeholder.image(detected_frame, use_column_width=True)
84
+ elapsed = time.time() - start_time
85
+ remaining = max(0, refresh_interval - elapsed)
86
+ timer_placeholder.write(f"Next refresh in: {int(remaining)}s")
87
+ time.sleep(1)
88
+ if remaining <= 0:
89
+ st.experimental_rerun()
90
+ except Exception as e:
91
+ st.error(f"Error: {e}")
92
  break
 
 
 
 
 
 
 
 
 
 
 
 
93
  else:
94
+ cap = cv2.VideoCapture(webcam_url)
95
+ frame_placeholder = st.empty()
96
+ while cap.isOpened():
97
  ret, frame = cap.read()
98
  if not ret:
99
+ st.error("Stream failed.")
100
  break
101
+ results = model.predict(frame, conf=confidence)
102
  detected_frame = results[0].plot()[:, :, ::-1]
103
+ frame_placeholder.image(detected_frame, use_column_width=True)
104
  time.sleep(0.05)
 
 
105
 
106
+ # Tab 3: YouTube Live Stream
 
107
  with tabs[2]:
108
+ col1, col2 = st.columns([1, 1])
109
+ with col1:
110
+ st.markdown("**YouTube live stream**")
111
+ youtube_url = st.text_input("URL", "https://www.youtube.com/watch?v=<id>", label_visibility="collapsed")
112
+ confidence = st.slider("Confidence", 0.25, 1.0, 0.4, key="yt_conf")
113
+ start = st.button("Start", key="yt_start")
114
+ with col2:
115
+ if start:
116
  streams = streamlink.streams(youtube_url)
117
+ if streams:
118
+ stream_url = streams["best"].to_url()
119
+ cap = cv2.VideoCapture(stream_url)
120
+ frame_placeholder = st.empty()
121
+ while cap.isOpened():
122
+ ret, frame = cap.read()
123
+ if not ret:
124
+ st.error("Stream failed.")
125
+ break
126
+ results = model.predict(frame, conf=confidence)
127
+ detected_frame = results[0].plot()[:, :, ::-1]
128
+ frame_placeholder.image(detected_frame, use_column_width=True)
129
+ time.sleep(0.05)
130
  else:
131
+ st.error("No stream found.")