Spaces:
biodivx
/
Sleeping

amroa commited on
Commit
817fa65
1 Parent(s): 9bed9a7

bird gallery now live

Browse files
Files changed (6) hide show
  1. __pycache__/app.cpython-311.pyc +0 -0
  2. app.py +68 -115
  3. fetch_img.py +6 -3
  4. noimg.png +0 -0
  5. requirements.txt +1 -0
  6. styling.py +139 -0
__pycache__/app.cpython-311.pyc CHANGED
Binary files a/__pycache__/app.cpython-311.pyc and b/__pycache__/app.cpython-311.pyc differ
 
app.py CHANGED
@@ -5,15 +5,20 @@ import os
5
  import numpy as np
6
  import pandas as pd
7
  from typing import Iterable
 
8
 
9
  import gradio as gr
10
  from gradio.themes.base import Base
11
  from gradio.themes.utils import colors, fonts, sizes
12
  import requests
13
  import torch
 
14
  import librosa
15
  import torch.nn.functional as F
16
 
 
 
 
17
  # Import the necessary functions from the voj package
18
  from audio_class_predictor import predict_class
19
  from bird_ast_model import birdast_preprocess, birdast_inference
@@ -106,16 +111,6 @@ def run_inference_with_model(audio_clip, sr, model_name):
106
 
107
  return results
108
 
109
-
110
-
111
- def load_markdown_from_url(url):
112
- response = requests.get(url)
113
- response.raise_for_status()
114
- return response.text
115
-
116
- markdown_url = 'https://github.com/AmroAbdrabo/amroa/raw/main/img/desc.md'
117
- markdown_content = load_markdown_from_url(markdown_url)
118
-
119
  def predict(audio, start, end, model_name="BirdAST_Seq"):
120
 
121
  raw_sr, audio_array = audio
@@ -156,103 +151,13 @@ def predict(audio, start, end, model_name="BirdAST_Seq"):
156
  # run inference with model
157
  print(f"Running inference with model: {model_name}")
158
  species_class = run_inference_with_model(audio_array, DEFUALT_SR, model_name)
159
-
160
- return audio_class, species_class, fig_waveform, fig_spectrogram
161
-
162
-
163
-
164
-
165
- DESCRIPTION = markdown_content
166
-
167
- css = """
168
- #gradio-animation {
169
- font-size: 2em;
170
- font-weight: bold;
171
- text-align: center;
172
- margin-bottom: 20px;
173
- }
174
-
175
- .logo-container img {
176
- width: 14%; /* Adjust width as necessary */
177
- display: block;
178
- margin: auto;
179
- }
180
-
181
- .number-input {
182
- height: 100%;
183
- padding-bottom: 60px; /* Adust the value as needed for more or less space */
184
- }
185
- .full-height {
186
- height: 100%;
187
- }
188
- .column-container {
189
- height: 100%;
190
- }
191
- """
192
-
193
 
194
 
195
- class Seafoam(Base):
196
- def __init__(
197
- self,
198
- *,
199
- primary_hue: colors.Color | str = colors.emerald,
200
- secondary_hue: colors.Color | str = colors.blue,
201
- neutral_hue: colors.Color | str = colors.gray,
202
- spacing_size: sizes.Size | str = sizes.spacing_md,
203
- radius_size: sizes.Size | str = sizes.radius_md,
204
- text_size: sizes.Size | str = sizes.text_lg,
205
- font: fonts.Font
206
- | str
207
- | Iterable[fonts.Font | str] = (
208
- fonts.GoogleFont("Quicksand"),
209
- "ui-sans-serif",
210
- "sans-serif",
211
- ),
212
- font_mono: fonts.Font
213
- | str
214
- | Iterable[fonts.Font | str] = (
215
- fonts.GoogleFont("IBM Plex Mono"),
216
- "ui-monospace",
217
- "monospace",
218
- ),
219
- ):
220
- super().__init__(
221
- primary_hue=primary_hue,
222
- secondary_hue=secondary_hue,
223
- neutral_hue=neutral_hue,
224
- spacing_size=spacing_size,
225
- radius_size=radius_size,
226
- text_size=text_size,
227
- font=font,
228
- font_mono=font_mono,
229
- )
230
-
231
-
232
- seafoam = Seafoam()
233
-
234
-
235
- js = """
236
- function createGradioAnimation() {
237
- var container = document.getElementById('gradio-animation');
238
- var text = 'Voice of Jungle';
239
- for (var i = 0; i < text.length; i++) {
240
- (function(i){
241
- setTimeout(function(){
242
- var letter = document.createElement('span');
243
- letter.style.opacity = '0';
244
- letter.style.transition = 'opacity 0.5s';
245
- letter.innerText = text[i];
246
- container.appendChild(letter);
247
- setTimeout(function() {
248
- letter.style.opacity = '1';
249
- }, 50);
250
- }, i * 250);
251
- })(i);
252
- }
253
- }
254
- """
255
-
256
  REFERENCES = """
257
  # Appendix
258
 
@@ -307,6 +212,49 @@ def handle_model_selection(model_name, download_status):
307
  return download_status
308
 
309
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
310
  with gr.Blocks(theme = seafoam, css = css, js = js) as demo:
311
 
312
  gr.Markdown('<div class="logo-container"><img src="https://i.ibb.co/vcG9kr0/vojlogo.jpg" width="50px" alt="vojlogo"></div>')
@@ -317,7 +265,6 @@ with gr.Blocks(theme = seafoam, css = css, js = js) as demo:
317
  model_names = ['BirdAST', 'BirdAST_Seq'] #, 'EfficientNet']
318
  model_dropdown = gr.Dropdown(label="Choose a model", choices=model_names)
319
  download_status = gr.Textbox(label="Model Status", lines=3, value='', interactive=False) # Non-interactive textbox for status
320
-
321
  model_dropdown.change(handle_model_selection, inputs=[model_dropdown, download_status], outputs=download_status)
322
 
323
 
@@ -328,14 +275,22 @@ with gr.Blocks(theme = seafoam, css = css, js = js) as demo:
328
  with gr.Column():
329
  audio_input = gr.Audio(label="Input Audio", elem_classes="full-height")
330
 
331
- with gr.Row():
332
- raw_class_output = gr.Dataframe(headers=["Class", "Score [%]"], row_count=10, label="Class Prediction")
333
- species_output = gr.Dataframe(headers=["Class", "Score [%]"], row_count=10, label="Species Prediction")
334
-
335
- with gr.Row():
336
- waveform_output = gr.Plot(label="Waveform")
337
- spectrogram_output = gr.Plot(label="Spectrogram")
 
 
 
 
 
 
338
 
 
 
339
  gr.Examples(
340
  examples=[
341
  ["XC226833-Chestnut-belted_20Chat-Tyrant_20A_2010989.mp3", 0, 10],
@@ -344,8 +299,6 @@ with gr.Blocks(theme = seafoam, css = css, js = js) as demo:
344
  ],
345
  inputs=[audio_input, start_time_input, end_time_input]
346
  )
347
-
348
- gr.Button("Predict").click(predict, [audio_input, start_time_input, end_time_input, model_dropdown], [raw_class_output, species_output, waveform_output, spectrogram_output])
349
 
350
  gr.Markdown(REFERENCES)
351
 
 
5
  import numpy as np
6
  import pandas as pd
7
  from typing import Iterable
8
+ from styling import js, seafoam, css, DESCRIPTION
9
 
10
  import gradio as gr
11
  from gradio.themes.base import Base
12
  from gradio.themes.utils import colors, fonts, sizes
13
  import requests
14
  import torch
15
+ import shutil
16
  import librosa
17
  import torch.nn.functional as F
18
 
19
+ # Image gallery
20
+ from fetch_img import download_images, scientific_to_species_code
21
+
22
  # Import the necessary functions from the voj package
23
  from audio_class_predictor import predict_class
24
  from bird_ast_model import birdast_preprocess, birdast_inference
 
111
 
112
  return results
113
 
 
 
 
 
 
 
 
 
 
 
114
  def predict(audio, start, end, model_name="BirdAST_Seq"):
115
 
116
  raw_sr, audio_array = audio
 
151
  # run inference with model
152
  print(f"Running inference with model: {model_name}")
153
  species_class = run_inference_with_model(audio_array, DEFUALT_SR, model_name)
154
+ print("Species is ", species_class[0][0].strip().replace("_", " "))
155
+ images = prepare_images(species_class[0][0].strip().replace("_", " "))
156
+ if len(images) == 0:
157
+ images.append(("noimg.png", "No image"))
158
+ return audio_class, species_class, fig_waveform, fig_spectrogram, images
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
 
160
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  REFERENCES = """
162
  # Appendix
163
 
 
212
  return download_status
213
 
214
 
215
+ # Image generation
216
+ def prepare_images(scientific_name: str):
217
+ # Get species code
218
+ scode = scientific_to_species_code(scientific_name)
219
+ if not scode:
220
+ return []
221
+
222
+ # Clear folder assets' images
223
+ for filename in os.listdir(ASSET_DIR):
224
+ # Construct full file path
225
+ file_path = os.path.join(ASSET_DIR, filename)
226
+ # Check if the file is a .jpg, .jpeg, or .png
227
+ if file_path.lower().endswith(('.jpg', '.jpeg', '.png')):
228
+ # If yes, delete the file
229
+ os.remove(file_path)
230
+ print(f"Deleted: {file_path}")
231
+
232
+ # Save images to assets
233
+ download_images(f"https://ebird.org/species/{scode}")
234
+
235
+ # Return array of local image paths
236
+ nsplit = scientific_name.split(" ")
237
+ abbreviate_name = nsplit[0][0] + "." + " " + nsplit[1]
238
+ images = []
239
+ for img_file in os.listdir("./assets"):
240
+ if img_file.lower().endswith(('.png', '.jpg', '.jpeg')):
241
+ images.append((os.path.join("./assets", img_file), abbreviate_name))
242
+
243
+ return images
244
+
245
+
246
+ sp_and_cl = """<div align="center">
247
+ <b> <h2> Class and Species Prediction </h2> </b>
248
+ </div>"""
249
+
250
+ sig_prop = """<div align="center">
251
+ <b> <h2> Signal Visualization </h2> </b>
252
+ </div>"""
253
+
254
+ imgs = """<div align="center">
255
+ <b> <h2> Bird Gallery </h2> </b>
256
+ </div>"""
257
+
258
  with gr.Blocks(theme = seafoam, css = css, js = js) as demo:
259
 
260
  gr.Markdown('<div class="logo-container"><img src="https://i.ibb.co/vcG9kr0/vojlogo.jpg" width="50px" alt="vojlogo"></div>')
 
265
  model_names = ['BirdAST', 'BirdAST_Seq'] #, 'EfficientNet']
266
  model_dropdown = gr.Dropdown(label="Choose a model", choices=model_names)
267
  download_status = gr.Textbox(label="Model Status", lines=3, value='', interactive=False) # Non-interactive textbox for status
 
268
  model_dropdown.change(handle_model_selection, inputs=[model_dropdown, download_status], outputs=download_status)
269
 
270
 
 
275
  with gr.Column():
276
  audio_input = gr.Audio(label="Input Audio", elem_classes="full-height")
277
 
278
+ gr.Markdown(sp_and_cl)
279
+ with gr.Column():
280
+ with gr.Row():
281
+ raw_class_output = gr.Dataframe(headers=["Class", "Score [%]"], row_count=10, label="Class Prediction")
282
+ species_output = gr.Dataframe(headers=["Class", "Score [%]"], row_count=10, label="Species Prediction")
283
+
284
+ gr.Markdown(sig_prop)
285
+ with gr.Column():
286
+ with gr.Row():
287
+ waveform_output = gr.Plot(label="Waveform")
288
+ spectrogram_output = gr.Plot(label="Spectrogram")
289
+ gr.Markdown(imgs)
290
+ gallery = gallery = gr.Gallery(label="Species Images", show_label=False, elem_id="gallery",columns=[3], rows=[1], object_fit="contain", height="auto")
291
 
292
+ gr.Button("Predict").click(predict, [audio_input, start_time_input, end_time_input, model_dropdown], [raw_class_output, species_output, waveform_output, spectrogram_output, gallery])
293
+
294
  gr.Examples(
295
  examples=[
296
  ["XC226833-Chestnut-belted_20Chat-Tyrant_20A_2010989.mp3", 0, 10],
 
299
  ],
300
  inputs=[audio_input, start_time_input, end_time_input]
301
  )
 
 
302
 
303
  gr.Markdown(REFERENCES)
304
 
fetch_img.py CHANGED
@@ -22,8 +22,11 @@ bird_df = pd.read_csv("ebird_taxonomy_v2023.csv")
22
 
23
 
24
  def scientific_to_species_code(scientific_name: str):
25
- scode = bird_df.loc[bird_df['SCI_NAME'] == scientific_name]['SPECIES_CODE']
26
- return scode.array[0]
 
 
 
27
 
28
  # Gets taxonomical info on bird. (Is not actually used)
29
  def get_bird_info(species_code : str):
@@ -33,7 +36,7 @@ def get_bird_info(species_code : str):
33
  data = response.content
34
  return data
35
 
36
- def download_images(url, folder_path='assets'):
37
  # Create a folder to save images if it doesn't exist
38
  if not os.path.exists(folder_path):
39
  os.makedirs(folder_path)
 
22
 
23
 
24
  def scientific_to_species_code(scientific_name: str):
25
+ scode = bird_df[bird_df['SCI_NAME'].str.contains(scientific_name, na=False)]['SPECIES_CODE']
26
+ if not scode.array:
27
+ return []
28
+ else:
29
+ return scode.array[0]
30
 
31
  # Gets taxonomical info on bird. (Is not actually used)
32
  def get_bird_info(species_code : str):
 
36
  data = response.content
37
  return data
38
 
39
+ def download_images(url, folder_path='./assets'):
40
  # Create a folder to save images if it doesn't exist
41
  if not os.path.exists(folder_path):
42
  os.makedirs(folder_path)
noimg.png ADDED
requirements.txt CHANGED
@@ -6,6 +6,7 @@ requests
6
  timm
7
  pandas
8
  torch
 
9
  librosa
10
  noisereduce
11
  torchaudio
 
6
  timm
7
  pandas
8
  torch
9
+ shutil
10
  librosa
11
  noisereduce
12
  torchaudio
styling.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import warnings
2
+ warnings.filterwarnings("ignore")
3
+
4
+ import os
5
+ import numpy as np
6
+ import pandas as pd
7
+ from typing import Iterable
8
+
9
+ import gradio as gr
10
+ from gradio.themes.base import Base
11
+ from gradio.themes.utils import colors, fonts, sizes
12
+ import requests
13
+ import torch
14
+ import shutil
15
+ import librosa
16
+ import torch.nn.functional as F
17
+
18
+ # Image gallery
19
+ from fetch_img import download_images, scientific_to_species_code
20
+
21
+ # Import the necessary functions from the voj package
22
+ from audio_class_predictor import predict_class
23
+ from bird_ast_model import birdast_preprocess, birdast_inference
24
+ from bird_ast_seq_model import birdast_seq_preprocess, birdast_seq_inference
25
+
26
+ from utils import plot_wave, plot_mel, download_model, bandpass_filter
27
+
28
+
29
+ def load_markdown_from_url(url):
30
+ response = requests.get(url)
31
+ response.raise_for_status()
32
+ return response.text
33
+
34
+
35
+ markdown_url = 'https://github.com/AmroAbdrabo/amroa/raw/main/img/desc.md'
36
+ markdown_content = load_markdown_from_url(markdown_url)
37
+
38
+ DESCRIPTION = markdown_content
39
+
40
+ # CSS properties for the logo and inputs
41
+ css = """
42
+ #gradio-animation {
43
+ font-size: 2em;
44
+ font-weight: bold;
45
+ text-align: center;
46
+ margin-bottom: 20px;
47
+ }
48
+ #gallery {
49
+ align: center;
50
+ margin: auto;
51
+ }
52
+ .gr-gallery-item img {
53
+ display: block;
54
+ margin-left: auto;
55
+ margin-right: auto;
56
+ }
57
+ .logo-container img {
58
+ width: 14%; /* Adjust width as necessary */
59
+ display: block;
60
+ margin: auto;
61
+ }
62
+ .number-input {
63
+ height: 100%;
64
+ padding-bottom: 60px; /* Adust the value as needed for more or less space */
65
+ }
66
+ .full-height {
67
+ height: 100%;
68
+ }
69
+ .column-container {
70
+ height: 100%;
71
+ }
72
+ .section-divider {
73
+ align: center;
74
+ font-size: 100% !important;
75
+ color: blue !important;
76
+ }
77
+ """
78
+
79
+ # Seafoam is the theme
80
+ class Seafoam(Base):
81
+ def __init__(
82
+ self,
83
+ *,
84
+ primary_hue: colors.Color | str = colors.emerald,
85
+ secondary_hue: colors.Color | str = colors.blue,
86
+ neutral_hue: colors.Color | str = colors.gray,
87
+ spacing_size: sizes.Size | str = sizes.spacing_md,
88
+ radius_size: sizes.Size | str = sizes.radius_md,
89
+ text_size: sizes.Size | str = sizes.text_lg,
90
+ font: fonts.Font
91
+ | str
92
+ | Iterable[fonts.Font | str] = (
93
+ fonts.GoogleFont("Poppins"),
94
+ "ui-sans-serif",
95
+ "sans-serif",
96
+ ),
97
+ font_mono: fonts.Font
98
+ | str
99
+ | Iterable[fonts.Font | str] = (
100
+ fonts.GoogleFont("IBM Plex Mono"),
101
+ "ui-monospace",
102
+ "monospace",
103
+ ),
104
+ ):
105
+ super().__init__(
106
+ primary_hue=primary_hue,
107
+ secondary_hue=secondary_hue,
108
+ neutral_hue=neutral_hue,
109
+ spacing_size=spacing_size,
110
+ radius_size=radius_size,
111
+ text_size=text_size,
112
+ font=font,
113
+ font_mono=font_mono,
114
+ )
115
+
116
+
117
+ seafoam = Seafoam()
118
+
119
+ # Typeletter animation
120
+ js = """
121
+ function createGradioAnimation() {
122
+ var container = document.getElementById('gradio-animation');
123
+ var text = 'Voice of Jungle';
124
+ for (var i = 0; i < text.length; i++) {
125
+ (function(i){
126
+ setTimeout(function(){
127
+ var letter = document.createElement('span');
128
+ letter.style.opacity = '0';
129
+ letter.style.transition = 'opacity 0.5s';
130
+ letter.innerText = text[i];
131
+ container.appendChild(letter);
132
+ setTimeout(function() {
133
+ letter.style.opacity = '1';
134
+ }, 50);
135
+ }, i * 250);
136
+ })(i);
137
+ }
138
+ }
139
+ """