Skip to content

Commit

Permalink
Merge branch 'main' into embeddings-with-hoplite
Browse files Browse the repository at this point in the history
  • Loading branch information
max-mauermann committed Feb 19, 2025
2 parents 581e3a6 + 3d19684 commit e7680cf
Show file tree
Hide file tree
Showing 20 changed files with 90 additions and 104 deletions.
13 changes: 6 additions & 7 deletions birdnet_analyzer/analyze/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def save_analysis_params(path):
"Minimum Segment length",
"Bandpass filter minimum",
"Bandpass filter maximum",
"Merge consecutive detections",
"Audio speed",
"Custom classifier path",
),
Expand All @@ -44,6 +45,7 @@ def save_analysis_params(path):
cfg.SIG_MINLEN,
cfg.BANDPASS_FMIN,
cfg.BANDPASS_FMAX,
cfg.MERGE_CONSECUTIVE,
cfg.AUDIO_SPEED,
cfg.CUSTOM_CLASSIFIER,
),
Expand Down Expand Up @@ -447,7 +449,7 @@ def merge_consecutive_detections(results: dict[str, list], max_consecutive: int
# Merge consecutive detections
merged_results = {}
for label in species:
timestamps = species[label]
timestamps = species[label]

# Check if end time of current detection is within the start time of the next detection
i = 0
Expand All @@ -459,24 +461,21 @@ def merge_consecutive_detections(results: dict[str, list], max_consecutive: int
# Merge detections
merged_scores = [timestamps[i][1], timestamps[i + 1][1]]
timestamps.pop(i)
consecutive_count = 1

while i < len(timestamps) - 1 and float(timestamps[i][0].split("-", 1)[1]) >= float(timestamps[i + 1][0].split("-", 1)[0]):
if max_consecutive and consecutive_count >= max_consecutive:
while i < len(timestamps) - 1 and float(next_end) >= float(timestamps[i + 1][0].split("-", 1)[0]):
if max_consecutive and len(merged_scores) >= max_consecutive - 1:
break
merged_scores.append(timestamps[i + 1][1])
next_end = timestamps[i + 1][0].split("-", 1)[1]
timestamps.pop(i + 1)
consecutive_count += 1

# Calculate mean of top 3 scores
top_3_scores = sorted(merged_scores, reverse=True)[:3]
merged_score = sum(top_3_scores) / len(top_3_scores)

timestamps[i] = (f"{start}-{next_end}", merged_score)

else:
i += 1
i += 1

merged_results[label] = timestamps

Expand Down
25 changes: 0 additions & 25 deletions birdnet_analyzer/gui/assets/gui.css
Original file line number Diff line number Diff line change
@@ -1,22 +1,3 @@
.d-block .wrap {
display: block !important;
}

.matrix-mh-200,
.matrix-mh-200 table {
max-height: 300px;
overflow-y: auto !important;
}

.matrix-mh-200 .table-wrap {
max-height: 300px;
}

.mh-200 {
max-height: 300px;
overflow-y: auto !important;
}

footer {
display: none !important;
}
Expand All @@ -40,12 +21,6 @@ footer {
text-align: center;
}

.table-container>.header-row {
display: none;
}



#embeddings-search-results {
overflow-y: scroll;
height: 700px;
Expand Down
3 changes: 3 additions & 0 deletions birdnet_analyzer/gui/assets/gui.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ function init() {
console.log("Binding review key shortcuts...");

document.addEventListener("keydown", function (event) {
if (event.target.style && event.target.style.display === "none") {
return;
}
if (event.key === "ArrowUp") {
posBtn.click();
} else if (event.key === "ArrowDown") {
Expand Down
5 changes: 2 additions & 3 deletions birdnet_analyzer/gui/multi_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def run_batch_analysis(
confidence,
sensitivity,
overlap,
merge_consecutive,
audio_speed,
fmin,
fmax,
Expand Down Expand Up @@ -94,7 +95,6 @@ def build_multi_analysis_tab():
directory_input = gr.Matrix(
interactive=False,
elem_classes="matrix-mh-200",
show_fullscreen_button=False,
headers=[
loc.localize("multi-tab-samples-dataframe-column-subpath-header"),
loc.localize("multi-tab-samples-dataframe-column-duration-header"),
Expand Down Expand Up @@ -138,9 +138,9 @@ def select_directory_wrapper(): # Nishant - Function modified for For Folder se
use_top_n,
top_n_input,
confidence_slider,
merge_consecutive_slider,
sensitivity_slider,
overlap_slider,
merge_consecutive_slider,
audio_speed_slider,
fmin_number,
fmax_number,
Expand Down Expand Up @@ -208,7 +208,6 @@ def select_directory_wrapper(): # Nishant - Function modified for For Folder se
loc.localize("multi-tab-result-dataframe-column-execution-header"),
],
elem_classes="matrix-mh-200",
show_fullscreen_button=False,
)

inputs = [
Expand Down
43 changes: 23 additions & 20 deletions birdnet_analyzer/gui/review.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,32 +144,20 @@ def create_log_plot(positives, negatives, fig_num=None):
],
interactive=False,
elem_id="segments-results-grid",
show_fullscreen_button=False,
)

with gr.Column() as review_item_col:
with gr.Row():
with gr.Column():
spectrogram_image = gr.Plot(
label=loc.localize("review-tab-spectrogram-plot-label"), show_label=False
)
with gr.Row():
spectrogram_dl_btn = gr.Button("Download spectrogram", size="sm")
regression_dl_btn = gr.Button("Download regression", size="sm")

with gr.Column():
with gr.Row():
skip_btn = gr.Button(
loc.localize("review-tab-skip-button-label"),
elem_id="skip-button",
icon=os.path.join(SCRIPT_DIR, "assets/arrow_right.svg"),
)
undo_btn = gr.Button(
loc.localize("review-tab-undo-button-label"),
elem_id="undo-button",
icon=os.path.join(SCRIPT_DIR, "assets/arrow_left.svg"),
with gr.Group():
spectrogram_image = gr.Plot(
label=loc.localize("review-tab-spectrogram-plot-label"), show_label=False
)
with gr.Row():
spectrogram_dl_btn = gr.Button("Download spectrogram", size="sm")
regression_dl_btn = gr.Button("Download regression", size="sm")

with gr.Column():
positive_btn = gr.Button(
loc.localize("review-tab-pos-button-label"),
elem_id="positive-button",
Expand All @@ -183,6 +171,18 @@ def create_log_plot(positives, negatives, fig_num=None):
icon=os.path.join(SCRIPT_DIR, "assets/arrow_down.svg"),
)

with gr.Row():
undo_btn = gr.Button(
loc.localize("review-tab-undo-button-label"),
elem_id="undo-button",
icon=os.path.join(SCRIPT_DIR, "assets/arrow_left.svg"),
)
skip_btn = gr.Button(
loc.localize("review-tab-skip-button-label"),
elem_id="skip-button",
icon=os.path.join(SCRIPT_DIR, "assets/arrow_right.svg"),
)

with gr.Group():
review_audio = gr.Audio(
type="filepath", sources=[], show_download_button=False, autoplay=True
Expand Down Expand Up @@ -230,7 +230,10 @@ def update_values(next_review_state, skip_plot=False):
return update_dict

def next_review(next_review_state: dict, target_dir: str = None):
current_file = next_review_state["files"][0]
try:
current_file = next_review_state["files"][0]
except IndexError:
raise gr.Error("No more files to review.")

if target_dir:
selected_dir = os.path.join(
Expand Down
1 change: 0 additions & 1 deletion birdnet_analyzer/gui/segments.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ def select_directory_to_state_and_tb(state_key):
loc.localize("segments-tab-result-dataframe-column-execution-header"),
],
elem_classes="matrix-mh-200",
show_fullscreen_button=False,
)

extract_segments_btn.click(
Expand Down
4 changes: 2 additions & 2 deletions birdnet_analyzer/gui/single_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def get_audio_path(i, generate_spectrogram):
return (
i["path"],
gr.Audio(label=os.path.basename(i["path"])),
gr.Plot(visible=True, value=utils.spectrogram_from_file(i["path"], fig_size="auto"))
gr.Plot(visible=True, value=utils.spectrogram_from_file(i["path"], fig_size=(20,4)))
if generate_spectrogram
else gr.Plot(visible=False),
)
Expand All @@ -142,7 +142,7 @@ def get_audio_path(i, generate_spectrogram):

def try_generate_spectrogram(audio_path, generate_spectrogram):
if audio_path and generate_spectrogram:
return gr.Plot(visible=True, value=utils.spectrogram_from_file(audio_path["path"], fig_size="auto"))
return gr.Plot(visible=True, value=utils.spectrogram_from_file(audio_path["path"], fig_size=(20,4)))
else:
return gr.Plot()

Expand Down
10 changes: 7 additions & 3 deletions birdnet_analyzer/gui/species.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ def select_directory_and_update_tb(name_tb):
show_progress=False,
)

lat_number, lon_number, week_number, sf_thresh_number, yearlong_checkbox, map_plot = gu.species_list_coordinates(show_map=True)
lat_number, lon_number, week_number, sf_thresh_number, yearlong_checkbox, map_plot = (
gu.species_list_coordinates(show_map=True)
)

sortby = gr.Radio(
[
Expand All @@ -80,8 +82,10 @@ def select_directory_and_update_tb(name_tb):
],
)

species_tab.select(gu.resize)

species_tab.select(
lambda lat, lon: gu.plot_map_scatter_mapbox(lat, lon, zoom=3), inputs=[lat_number, lon_number], outputs=map_plot
)

return lat_number, lon_number, map_plot


Expand Down
2 changes: 1 addition & 1 deletion birdnet_analyzer/gui/train.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ def build_train_tab():
directory_input = gr.List(
headers=[loc.localize("training-tab-classes-dataframe-column-classes-header")],
interactive=False,
show_fullscreen_button=False,
elem_classes="matrix-mh-200",
)
select_directory_btn.click(
Expand Down Expand Up @@ -290,6 +289,7 @@ def select_directory_and_update_tb():
[
(loc.localize("training-tab-upsampling-radio-option-repeat"), "repeat"),
(loc.localize("training-tab-upsampling-radio-option-mean"), "mean"),
(loc.localize("training-tab-upsampling-radio-option-linear"), "linear"),
("SMOTE", "smote"),
],
value=cfg.UPSAMPLING_MODE,
Expand Down
53 changes: 23 additions & 30 deletions birdnet_analyzer/gui/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,10 +274,10 @@ def sample_sliders(opened=True):
info=loc.localize("inference-settings-top-n-number-info"),
)
confidence_slider = gr.Slider(
minimum=0.001,
maximum=0.99,
minimum=0.05,
maximum=0.95,
value=cfg.MIN_CONFIDENCE,
step=0.001,
step=0.05,
label=loc.localize("inference-settings-confidence-slider-label"),
info=loc.localize("inference-settings-confidence-slider-info"),
)
Expand All @@ -300,9 +300,9 @@ def sample_sliders(opened=True):
)
overlap_slider = gr.Slider(
minimum=0,
maximum=2.99,
maximum=2.9,
value=cfg.SIG_OVERLAP,
step=0.01,
step=0.1,
label=loc.localize("inference-settings-overlap-slider-label"),
info=loc.localize("inference-settings-overlap-slider-info"),
)
Expand Down Expand Up @@ -372,12 +372,13 @@ def locale():
)


def plot_map_scatter_mapbox(lat, lon):
def plot_map_scatter_mapbox(lat, lon, zoom=4):
fig = px.scatter_mapbox(
lat=[lat],
lon=[lon],
zoom=4,
zoom=zoom,
mapbox_style="open-street-map",
size=[10]
)
# fig.update_traces(marker=dict(size=10, color="red")) # Explicitly set color and size
fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0})
Expand Down Expand Up @@ -405,7 +406,7 @@ def species_list_coordinates(show_map=False):
info=loc.localize("species-list-coordinates-lon-number-info"),
)

map_plot = gr.Plot(show_label=False, scale=2, visible=show_map)
map_plot = gr.Plot(plot_map_scatter_mapbox(0, 0), show_label=False, scale=2, visible=show_map)

lat_number.change(
plot_map_scatter_mapbox, inputs=[lat_number, lon_number], outputs=map_plot, show_progress=False
Expand All @@ -414,21 +415,20 @@ def species_list_coordinates(show_map=False):
plot_map_scatter_mapbox, inputs=[lat_number, lon_number], outputs=map_plot, show_progress=False
)

with gr.Row():
yearlong_checkbox = gr.Checkbox(
True, label=loc.localize("species-list-coordinates-yearlong-checkbox-label")
)
week_number = gr.Slider(
minimum=1,
maximum=48,
value=1,
step=1,
interactive=False,
label=loc.localize("species-list-coordinates-week-slider-label"),
info=loc.localize("species-list-coordinates-week-slider-info"),
)
with gr.Group():
with gr.Row():
yearlong_checkbox = gr.Checkbox(True, label=loc.localize("species-list-coordinates-yearlong-checkbox-label"))
week_number = gr.Slider(
minimum=1,
maximum=48,
value=1,
step=1,
interactive=False,
label=loc.localize("species-list-coordinates-week-slider-label"),
info=loc.localize("species-list-coordinates-week-slider-info"),
)

sf_thresh_number = gr.Slider(
sf_thresh_number = gr.Slider(
minimum=0.01,
maximum=0.99,
value=cfg.LOCATION_FILTER_THRESHOLD,
Expand Down Expand Up @@ -591,13 +591,6 @@ def _get_win_drives():

return [f"{drive}:\\" for drive in UPPER_CASE]

def resize():
# Used to trigger resize
# Otherwise the map will not be displayed correctly
old_height, old_width = _WINDOW.height, _WINDOW.width
_WINDOW.resize(old_width + 1, old_height)
_WINDOW.resize(old_width, old_height)

def open_window(builder: list[Callable] | Callable):
"""
Opens a GUI window using the Gradio library and the webview module.
Expand Down Expand Up @@ -646,7 +639,7 @@ def update_plots(*args):
enable_monitoring=False,
allowed_paths=_get_win_drives() if sys.platform == "win32" else ["/"],
)[1]
_WINDOW = webview.create_window("BirdNET-Analyzer", url.rstrip("/") + "?__theme=light", width=1024, height=769) #min_size=(1024, 768))
_WINDOW = webview.create_window("BirdNET-Analyzer", url.rstrip("/") + "?__theme=light", width=1300, height=900)
set_window(_WINDOW)

with suppress(ModuleNotFoundError):
Expand Down
Loading

0 comments on commit e7680cf

Please sign in to comment.