tstone87 commited on
Commit
72e648a
·
verified ·
1 Parent(s): bd8cb28

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +49 -34
app.py CHANGED
@@ -48,55 +48,79 @@ with st.sidebar:
48
 
49
  # Main page
50
  st.title("Fire Watch: AI-Powered Fire and Smoke Detection")
 
 
51
  col1, col2 = st.columns(2)
52
  with col1:
53
- st.image("https://huggingface.co/spaces/tstone87/ccr-colorado/resolve/main/Fire_1.jpeg", use_column_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  with col2:
55
- st.image("https://huggingface.co/spaces/tstone87/ccr-colorado/resolve/main/Fire_3.png", use_column_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
  st.markdown("""
58
- Early wildfire detection using YOLOv8 AI vision model. See examples below or upload your own content!
59
- Hover over example videos to see detection results!
60
  """)
61
 
62
- # Function to create synchronized video pair HTML with hover images
63
- def create_synced_video_pair(orig_url, proc_url, pair_id, hover_image_url):
64
  try:
65
  orig_bytes = requests.get(orig_url).content
66
  proc_bytes = requests.get(proc_url).content
67
- hover_bytes = requests.get(hover_image_url).content
68
  orig_b64 = base64.b64encode(orig_bytes).decode('utf-8')
69
  proc_b64 = base64.b64encode(proc_bytes).decode('utf-8')
70
- hover_b64 = base64.b64encode(hover_bytes).decode('utf-8')
71
 
72
  html = f"""
73
- <div style="display: flex; gap: 10px; margin-bottom: 20px; position: relative;">
74
- <div style="flex: 1; position: relative;">
75
  <h4>Original</h4>
76
  <video id="orig_{pair_id}" width="100%" controls preload="metadata">
77
  <source src="data:video/mp4;base64,{orig_b64}" type="video/mp4">
78
  Your browser does not support the video tag.
79
  </video>
80
  </div>
81
- <div style="flex: 1; position: relative;">
82
  <h4>Processed</h4>
83
  <video id="proc_{pair_id}" width="100%" controls preload="metadata">
84
  <source src="data:video/mp4;base64,{proc_b64}" type="video/mp4">
85
  Your browser does not support the video tag.
86
  </video>
87
  </div>
88
- <img id="hover_{pair_id}" src="data:image/jpeg;base64,{hover_b64}"
89
- style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
90
- max-width: 80%; max-height: 80%; display: none; z-index: 10;">
91
  </div>
92
  <script>
93
  document.addEventListener('DOMContentLoaded', function() {{
94
  const origVideo = document.getElementById('orig_{pair_id}');
95
  const procVideo = document.getElementById('proc_{pair_id}');
96
- const hoverImg = document.getElementById('hover_{pair_id}');
97
- const container = origVideo.parentElement.parentElement;
98
 
99
- if (origVideo && procVideo && hoverImg) {{
100
  origVideo.addEventListener('play', function() {{
101
  procVideo.currentTime = origVideo.currentTime;
102
  procVideo.play().catch(e => console.log('Play error:', e));
@@ -119,23 +143,15 @@ def create_synced_video_pair(orig_url, proc_url, pair_id, hover_image_url):
119
  procVideo.addEventListener('seeked', function() {{
120
  origVideo.currentTime = procVideo.currentTime;
121
  }});
122
-
123
- // Hover events
124
- container.addEventListener('mouseover', function() {{
125
- hoverImg.style.display = 'block';
126
- }});
127
- container.addEventListener('mouseout', function() {{
128
- hoverImg.style.display = 'none';
129
- }});
130
  }} else {{
131
- console.log('Elements not found for {pair_id}');
132
  }}
133
  }});
134
  </script>
135
  """
136
  return html
137
  except Exception as e:
138
- return f"<p>Error loading videos or hover image: {str(e)}</p>"
139
 
140
  if not source_file:
141
  st.info("Please upload a file to begin.")
@@ -144,19 +160,18 @@ st.header("Your Results")
144
  result_cols = st.columns(2)
145
  viewer_slot = st.empty()
146
 
147
- # Example videos with synchronization and hover images
148
  st.header("Example Results")
149
  examples = [
150
- ("T Example", "T1.mp4", "T2.mp4", "File_3a.jpg"),
151
- ("LA Example", "LA1.mp4", "LA2.mp4", "File_4a.jpg")
152
  ]
153
- for title, orig_file, proc_file, hover_file in examples:
154
  st.subheader(title)
155
  orig_url = f"https://huggingface.co/spaces/tstone87/ccr-colorado/resolve/main/{orig_file}"
156
  proc_url = f"https://huggingface.co/spaces/tstone87/ccr-colorado/resolve/main/{proc_file}"
157
- hover_url = f"https://huggingface.co/spaces/tstone87/ccr-colorado/resolve/main/{hover_file}"
158
  pair_id = title.replace(" ", "").lower()
159
- video_html = create_synced_video_pair(orig_url, proc_url, pair_id, hover_url)
160
  st.markdown(video_html, unsafe_allow_html=True)
161
 
162
  # Load model
@@ -254,7 +269,7 @@ if process_button and source_file and model:
254
  download_slot.download_button(
255
  label="Download Processed Video",
256
  data=st.session_state.processed_video,
257
- file_name="processed_fire_analysis.mp4",
258
  mime="video/mp4"
259
  )
260
 
 
48
 
49
  # Main page
50
  st.title("Fire Watch: AI-Powered Fire and Smoke Detection")
51
+
52
+ # Custom HTML for images with hover effect
53
  col1, col2 = st.columns(2)
54
  with col1:
55
+ fire_1_url = "https://huggingface.co/spaces/tstone87/ccr-colorado/resolve/main/Fire_4.jpeg"
56
+ fire_3a_url = "https://huggingface.co/spaces/tstone87/ccr-colorado/resolve/main/Fire_4a.jpg"
57
+ fire_1_bytes = requests.get(fire_1_url).content
58
+ fire_3a_bytes = requests.get(fire_3a_url).content
59
+ fire_1_b64 = base64.b64encode(fire_1_bytes).decode('utf-8')
60
+ fire_3a_b64 = base64.b64encode(fire_3a_bytes).decode('utf-8')
61
+ html1 = f"""
62
+ <div style="position: relative; width: 100%;">
63
+ <img src="data:image/jpeg;base64,{fire_1_b64}" style="width: 100%; height: auto;">
64
+ <img src="data:image/jpeg;base64,{fire_3a_b64}"
65
+ style="position: absolute; top: 0; left: 0; width: 100%; height: auto; opacity: 0; transition: opacity 0.3s;"
66
+ onmouseover="this.style.opacity='1';" onmouseout="this.style.opacity='0';">
67
+ </div>
68
+ """
69
+ st.markdown(html1, unsafe_allow_html=True)
70
+
71
  with col2:
72
+ fire_3_url = "https://huggingface.co/spaces/tstone87/ccr-colorado/resolve/main/Fire_3.png"
73
+ fire_4a_url = "https://huggingface.co/spaces/tstone87/ccr-colorado/resolve/main/Fire_3a.jpg"
74
+ fire_3_bytes = requests.get(fire_3_url).content
75
+ fire_4a_bytes = requests.get(fire_4a_url).content
76
+ fire_3_b64 = base64.b64encode(fire_3_bytes).decode('utf-8')
77
+ fire_4a_b64 = base64.b64encode(fire_4a_bytes).decode('utf-8')
78
+ html2 = f"""
79
+ <div style="position: relative; width: 100%;">
80
+ <img src="data:image/png;base64,{fire_3_b64}" style="width: 100%; height: auto;">
81
+ <img src="data:image/jpeg;base64,{fire_4a_b64}"
82
+ style="position: absolute; top: 0; left: 0; width: 100%; height: auto; opacity: 0; transition: opacity 0.3s;"
83
+ onmouseover="this.style.opacity='1';" onmouseout="this.style.opacity='0';">
84
+ </div>
85
+ """
86
+ st.markdown(html2, unsafe_allow_html=True)
87
 
88
  st.markdown("""
89
+ Early wildfire detection using YOLOv8 AI vision model. Hover over the images above to see detection results!
90
+ See video examples below or upload your own to try it out!
91
  """)
92
 
93
+ # Function to create synchronized video pair HTML (no hover changes here)
94
+ def create_synced_video_pair(orig_url, proc_url, pair_id):
95
  try:
96
  orig_bytes = requests.get(orig_url).content
97
  proc_bytes = requests.get(proc_url).content
 
98
  orig_b64 = base64.b64encode(orig_bytes).decode('utf-8')
99
  proc_b64 = base64.b64encode(proc_bytes).decode('utf-8')
 
100
 
101
  html = f"""
102
+ <div style="display: flex; gap: 10px; margin-bottom: 20px;">
103
+ <div style="flex: 1;">
104
  <h4>Original</h4>
105
  <video id="orig_{pair_id}" width="100%" controls preload="metadata">
106
  <source src="data:video/mp4;base64,{orig_b64}" type="video/mp4">
107
  Your browser does not support the video tag.
108
  </video>
109
  </div>
110
+ <div style="flex: 1;">
111
  <h4>Processed</h4>
112
  <video id="proc_{pair_id}" width="100%" controls preload="metadata">
113
  <source src="data:video/mp4;base64,{proc_b64}" type="video/mp4">
114
  Your browser does not support the video tag.
115
  </video>
116
  </div>
 
 
 
117
  </div>
118
  <script>
119
  document.addEventListener('DOMContentLoaded', function() {{
120
  const origVideo = document.getElementById('orig_{pair_id}');
121
  const procVideo = document.getElementById('proc_{pair_id}');
 
 
122
 
123
+ if (origVideo && procVideo) {{
124
  origVideo.addEventListener('play', function() {{
125
  procVideo.currentTime = origVideo.currentTime;
126
  procVideo.play().catch(e => console.log('Play error:', e));
 
143
  procVideo.addEventListener('seeked', function() {{
144
  origVideo.currentTime = procVideo.currentTime;
145
  }});
 
 
 
 
 
 
 
 
146
  }} else {{
147
+ console.log('Video elements not found for {pair_id}');
148
  }}
149
  }});
150
  </script>
151
  """
152
  return html
153
  except Exception as e:
154
+ return f"<p>Error loading videos: {str(e)}</p>"
155
 
156
  if not source_file:
157
  st.info("Please upload a file to begin.")
 
160
  result_cols = st.columns(2)
161
  viewer_slot = st.empty()
162
 
163
+ # Example videos with synchronization
164
  st.header("Example Results")
165
  examples = [
166
+ ("T Example", "T1.mp4", "T2.mp4"),
167
+ ("LA Example", "LA1.mp4", "LA2.mp4")
168
  ]
169
+ for title, orig_file, proc_file in examples:
170
  st.subheader(title)
171
  orig_url = f"https://huggingface.co/spaces/tstone87/ccr-colorado/resolve/main/{orig_file}"
172
  proc_url = f"https://huggingface.co/spaces/tstone87/ccr-colorado/resolve/main/{proc_file}"
 
173
  pair_id = title.replace(" ", "").lower()
174
+ video_html = create_synced_video_pair(orig_url, proc_url, pair_id)
175
  st.markdown(video_html, unsafe_allow_html=True)
176
 
177
  # Load model
 
269
  download_slot.download_button(
270
  label="Download Processed Video",
271
  data=st.session_state.processed_video,
272
+ file_name="results_fire_analysis.mp4",
273
  mime="video/mp4"
274
  )
275