tstone87 commited on
Commit
0ba77f1
·
verified ·
1 Parent(s): f98a043

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +135 -80
app.py CHANGED
@@ -1,21 +1,15 @@
1
  import streamlit as st
2
  import cv2
3
- import PIL
4
  from ultralytics import YOLO
5
  import tempfile
 
 
6
  import time
 
7
 
8
- # ----------------------------------------------------------------
9
- # Load the model (using a URL to your weight file)
10
- model_path = 'https://huggingface.co/spaces/tstone87/ccr-colorado/blob/main/best.pt'
11
- try:
12
- model = YOLO(model_path)
13
- except Exception as ex:
14
- st.error(f"Unable to load model. Check the specified path: {model_path}")
15
- st.error(ex)
16
-
17
- # ----------------------------------------------------------------
18
- # Set page configuration
19
  st.set_page_config(
20
  page_title="WildfireWatch",
21
  page_icon="🔥",
@@ -23,90 +17,151 @@ st.set_page_config(
23
  initial_sidebar_state="expanded"
24
  )
25
 
26
- # ----------------------------------------------------------------
 
 
 
 
 
 
 
27
  # App Title and Description
28
  st.title("WildfireWatch: Detecting Wildfire using AI")
29
- st.markdown(
30
- """
31
- **Wildfires are a critical threat to ecosystems and communities.**
32
- Early detection can save lives and reduce environmental damage.
33
- Use this app to analyze images, videos, or live webcam streams for signs of fire.
34
- """
35
- )
36
 
37
- # ----------------------------------------------------------------
38
- # Create two tabs: one for file uploads and one for live webcam stream detection
39
- tab_upload, tab_live = st.tabs(["Upload Image/Video", "Live Webcam Stream"])
40
 
41
- # =========================
42
- # Tab 1: File Upload for Image/Video Detection
43
- with tab_upload:
44
- st.header("Upload an Image or Video")
45
- uploaded_file = st.file_uploader(
46
- "Choose an image or video...",
47
- type=["jpg", "jpeg", "png", "bmp", "webp", "mp4"]
48
- )
49
- confidence = st.slider("Select Model Confidence", 25, 100, 40) / 100
 
 
 
50
 
51
- if uploaded_file is not None:
52
- if uploaded_file.type.split('/')[0] == 'image':
53
- # Process uploaded image
54
  image = PIL.Image.open(uploaded_file)
55
- st.image(image, caption="Uploaded Image", use_column_width=True)
56
- if st.button("Detect Wildfire in Image"):
57
- results = model.predict(image, conf=confidence)
58
- annotated_image = results[0].plot()[:, :, ::-1]
59
- st.image(annotated_image, caption="Detection Result", use_column_width=True)
60
- with st.expander("Detection Details"):
61
  for box in results[0].boxes:
62
- st.write("Box coordinates (xywh):", box.xywh)
63
- elif uploaded_file.type.split('/')[0] == 'video':
64
- # Process uploaded video
65
  tfile = tempfile.NamedTemporaryFile(delete=False)
66
  tfile.write(uploaded_file.read())
67
  cap = cv2.VideoCapture(tfile.name)
68
- if st.button("Detect Wildfire in Video"):
69
- frame_placeholder = st.empty()
70
  while cap.isOpened():
71
  ret, frame = cap.read()
72
  if not ret:
73
  break
74
- results = model.predict(frame, conf=confidence)
75
- annotated_frame = results[0].plot()[:, :, ::-1]
76
- frame_placeholder.image(annotated_frame, channels="BGR", use_column_width=True)
77
- time.sleep(0.05) # Adjust delay for processing speed
78
  cap.release()
79
 
80
- # =========================
81
- # Tab 2: Live Webcam Stream Detection
82
- with tab_live:
83
- st.header("Live Webcam Stream Detection")
84
- st.markdown("Enter the URL for your online hosted webcam stream (e.g., an IP camera stream).")
85
- webcam_url = st.text_input("Webcam Stream URL", value="http://<your_webcam_stream_url>")
86
- live_confidence = st.slider("Select Live Detection Confidence", 25, 100, 40) / 100
87
-
88
- # Initialize a session state flag for stopping the live loop
89
- if "stop_live" not in st.session_state:
90
- st.session_state.stop_live = False
 
 
 
 
 
 
 
91
 
92
- def stop_live_detection():
93
- st.session_state.stop_live = True
 
94
 
95
- if st.button("Start Live Detection"):
96
- cap = cv2.VideoCapture(webcam_url)
97
- if not cap.isOpened():
98
- st.error("Unable to open webcam stream. Please check the URL.")
99
- else:
100
- live_frame_placeholder = st.empty()
101
- st.button("Stop Live Detection", on_click=stop_live_detection)
102
- while cap.isOpened() and not st.session_state.stop_live:
103
- ret, frame = cap.read()
104
- if not ret:
105
- st.error("Failed to retrieve frame from stream.")
106
  break
107
- results = model.predict(frame, conf=live_confidence)
108
- annotated_frame = results[0].plot()[:, :, ::-1]
109
- live_frame_placeholder.image(annotated_frame, channels="BGR", use_column_width=True)
110
- time.sleep(0.05)
111
- cap.release()
112
- st.session_state.stop_live = False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
  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
+ # -------------------------------
12
+ # Page & Model Setup
 
 
 
 
 
 
 
 
 
13
  st.set_page_config(
14
  page_title="WildfireWatch",
15
  page_icon="🔥",
 
17
  initial_sidebar_state="expanded"
18
  )
19
 
20
+ model_path = 'https://huggingface.co/spaces/tstone87/ccr-colorado/blob/main/best.pt'
21
+ try:
22
+ model = YOLO(model_path)
23
+ except Exception as ex:
24
+ st.error(f"Unable to load model from: {model_path}")
25
+ st.error(ex)
26
+
27
+ # -------------------------------
28
  # App Title and Description
29
  st.title("WildfireWatch: Detecting Wildfire using AI")
30
+ st.markdown("""
31
+ Wildfires are a major environmental issue that cause substantial losses.
32
+ Use this app to detect wildfires in images, videos, updating image URLs, or live YouTube streams.
33
+ """)
 
 
 
34
 
35
+ # -------------------------------
36
+ # Tabs for Detection Modes
37
+ tabs = st.tabs(["File Upload", "Image URL", "YouTube Live Stream"])
38
 
39
+ # ===============================
40
+ # Tab 1: File Upload Mode
41
+ with tabs[0]:
42
+ st.header("Detect Wildfire from Uploaded File")
43
+ col_input, col_result = st.columns(2)
44
+
45
+ with col_input:
46
+ uploaded_file = st.file_uploader(
47
+ "Choose an image or video...",
48
+ type=["jpg", "jpeg", "png", "bmp", "webp", "mp4"]
49
+ )
50
+ file_confidence = st.slider("Select Detection Confidence", 25, 100, 40) / 100
51
 
52
+ if uploaded_file:
53
+ file_type = uploaded_file.type.split('/')[0]
54
+ if file_type == "image":
55
  image = PIL.Image.open(uploaded_file)
56
+ col_input.image(image, caption="Uploaded Image", use_column_width=True)
57
+ if st.button("Detect Wildfire", key="detect_file_image"):
58
+ results = model.predict(image, conf=file_confidence)
59
+ annotated = results[0].plot()[:, :, ::-1]
60
+ col_result.image(annotated, caption="Detection Result", use_column_width=True)
61
+ with col_result.expander("Detection Details"):
62
  for box in results[0].boxes:
63
+ col_result.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("Detect Wildfire in Video", key="detect_file_video"):
 
69
  while cap.isOpened():
70
  ret, frame = cap.read()
71
  if not ret:
72
  break
73
+ results = model.predict(frame, conf=file_confidence)
74
+ annotated = results[0].plot()[:, :, ::-1]
75
+ col_result.image(annotated, caption="Detection Result", channels="BGR", use_column_width=True)
76
+ time.sleep(0.05)
77
  cap.release()
78
 
79
+ # ===============================
80
+ # Tab 2: Updating Image URL Mode
81
+ with tabs[1]:
82
+ st.header("Detect Wildfire from Updating Image URL")
83
+ col_input, col_result = st.columns(2)
84
+
85
+ with col_input:
86
+ image_url = st.text_input(
87
+ "Enter the URL of the updating image",
88
+ value="http://<your_updating_image_url>/current.jpg"
89
+ )
90
+ url_confidence = st.slider("Select Detection Confidence", 25, 100, 40, key="url_conf") / 100
91
+ start_detection = st.button("Start Detection", key="start_url")
92
+
93
+ if start_detection:
94
+ placeholder = col_result.empty()
95
+ if "stop_url" not in st.session_state:
96
+ st.session_state.stop_url = False
97
 
98
+ # Provide a stop button (the button will update session_state.stop_url on click)
99
+ def stop_detection():
100
+ st.session_state.stop_url = True
101
 
102
+ st.button("Stop Detection", on_click=stop_detection, key="url_stop")
103
+
104
+ # Loop until stop button is clicked
105
+ while not st.session_state.stop_url:
106
+ try:
107
+ response = requests.get(image_url, timeout=5)
108
+ image_array = np.asarray(bytearray(response.content), dtype=np.uint8)
109
+ frame = cv2.imdecode(image_array, cv2.IMREAD_COLOR)
110
+ if frame is None:
111
+ col_result.error("Failed to decode image from URL.")
 
112
  break
113
+ results = model.predict(frame, conf=url_confidence)
114
+ annotated = results[0].plot()[:, :, ::-1]
115
+ placeholder.image(annotated, channels="BGR", use_column_width=True)
116
+ time.sleep(1) # update interval in seconds
117
+ # Rerun the loop by breaking out of script execution cycle.
118
+ st.experimental_rerun()
119
+ except Exception as e:
120
+ col_result.error(f"Error fetching image: {e}")
121
+ break
122
+
123
+ # ===============================
124
+ # Tab 3: YouTube Live Stream Mode
125
+ with tabs[2]:
126
+ st.header("Detect Wildfire from YouTube Live Stream")
127
+ col_input, col_result = st.columns(2)
128
+
129
+ with col_input:
130
+ youtube_url = st.text_input(
131
+ "Enter YouTube Live URL",
132
+ value="https://www.youtube.com/watch?v=<live_stream_id>"
133
+ )
134
+ yt_confidence = st.slider("Select Detection Confidence", 25, 100, 40, key="yt_conf") / 100
135
+ start_yt = st.button("Start Live Detection", key="start_yt")
136
+
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
+ # Provide a stop button for live stream detection
153
+ stop_live = st.button("Stop Live Detection", key="yt_stop")
154
+ while cap.isOpened() and not stop_live:
155
+ ret, frame = cap.read()
156
+ if not ret:
157
+ col_result.error("Failed to retrieve frame from YouTube stream.")
158
+ break
159
+ results = model.predict(frame, conf=yt_confidence)
160
+ annotated = results[0].plot()[:, :, ::-1]
161
+ col_result.image(annotated, channels="BGR", use_column_width=True)
162
+ time.sleep(0.05)
163
+ # Check for stop command during loop
164
+ stop_live = st.button("Stop Live Detection", key="yt_stop_loop")
165
+ cap.release()
166
+ except Exception as e:
167
+ st.error(f"Error processing YouTube stream: {e}")