Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion birdnet_analyzer/analyze/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ def main():
analyze_args.pop("use_perch") # handled via model param
analyze_args.pop("load_params") # already applied as defaults

analyze(**analyze_args)
analyze(**analyze_args, save_params=True)
128 changes: 81 additions & 47 deletions birdnet_analyzer/analyze/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,70 +49,96 @@ def analyze(
split_tables: bool = False,
strict_species_list: bool = False,
save_params: bool = False,
show_progress: bool = False,
_return_only=False,
):
"""
Analyzes audio files for bird species detection using the BirdNET-Analyzer.
Args:
audio_input (str): Path to the input directory or file containing audio data.
output (str | None, optional): Path to the output directory for results.
Defaults to None.
min_conf (float, optional): Minimum confidence threshold for detections.
audio_input (str): Path to an audio file, or to a folder that is searched
recursively for audio files.
output (str | None, optional): Folder for the result files. Defaults to None,
which is the folder of an input file or the input folder itself.
model (str, optional): "birdnet" or "perch". Defaults to "birdnet".
birdnet (Literal["2.4", "3.0"], optional): BirdNET version used when
``model`` is "birdnet". Defaults to "3.0".
min_conf (float, optional): Minimum confidence of a detection, in [0, 1).
Defaults to 0.25.
classifier (str | None, optional): Path to a custom classifier file.
Defaults to None.
lat (float | None, optional): Latitude for location-based filtering.
Defaults to None.
lon (float | None, optional): Longitude for location-based filtering.
Defaults to None.
week (int, optional): Week of the year for seasonal filtering. Defaults to -1.
slist (str | None, optional): Path to a species list file for filtering.
classifier (str | None, optional): Path to a custom classifier (.tflite),
loaded instead of the BirdNET model; its BirdNET version is read from the
file. Cannot be combined with ``model`` "perch". Defaults to None.
cc_species_list (str | None, optional): Labels file of ``classifier``.
Defaults to None, which is the classifier path with ".tflite" replaced
by "_Labels.txt".
lat (float | None, optional): Latitude of the recording location. Together
with ``lon``, the detections are limited to the species the geo model
predicts there. Defaults to None.
lon (float | None, optional): Longitude of the recording location.
Defaults to None.
week (int | None, optional): Week of the year (1-48) for the geo model.
Defaults to None, the year-round list.
slist (str | Path | Collection[str] | None, optional): Species to limit the
detections to: a species list file, a folder holding "species_list.txt",
or the labels themselves. Defaults to None.
sensitivity (float, optional): Sensitivity of the detection algorithm;
applies to every BirdNET model and custom classifier, ignored (with a
warning) for Perch. Defaults to 1.0.
overlap (float, optional): Overlap between analysis windows in seconds.
overlap (float, optional): Overlap of consecutive segments in seconds.
Defaults to 0.
fmin (int, optional): Minimum frequency for analysis in Hz. Defaults to 0.
fmax (int, optional): Maximum frequency for analysis in Hz. Defaults to 15000.
audio_speed (float, optional): Speed factor for audio playback during analysis.
Defaults to 1.0.
batch_size (int, optional): Batch size for processing. Defaults to 1.
rtype (Literal["table", "audacity", "kaleidoscope", "csv", "parquet"] |
List[Literal["table", "audacity", "kaleidoscope", "csv", "parquet"]], optional):
Output format(s) for results. Defaults to "table".
sf_thresh (float, optional): Threshold for species filtering. Defaults to 0.03.
top_n (int | None, optional): Limit the number of top detections per file.
Defaults to None.
merge_consecutive (int, optional): Merge consecutive detections within this time
window in seconds. Defaults to 1.
threads (int, optional): Number of CPU threads to use for analysis.
Defaults to 8.
locale (str, optional): Locale for species names and output. Defaults to "en".
additional_columns (list[str] | None, optional): Additional columns to include
in the output. Defaults to None.
use_perch (bool, optional): Whether to use the Perch model for analysis.
Defaults to False.
split_tables (bool, optional): Whether to split output tables by input files.
Defaults to False.
fmin (int, optional): Lower bandpass frequency in Hz. Defaults to 0.
fmax (int, optional): Upper bandpass frequency in Hz. Defaults to 15000.
audio_speed (float, optional): Speed factor applied to the audio before the
analysis. Defaults to 1.0.
batch_size (int, optional): Segments per inference batch; a classifier
trained on BirdNET 3.0 always takes 1. Defaults to 1.
n_workers (int | None, optional): Number of inference worker processes.
Defaults to None, one per physical CPU core.
n_producers (int, optional): Number of processes reading the audio files.
Defaults to 1.
rtype (str | list[str], optional): Result file format(s): "table" (Raven
selection table), "audacity", "kaleidoscope", "csv" or "parquet".
Defaults to "table".
sf_thresh (float, optional): Minimum occurrence frequency of a species in the
geo model's prediction. Defaults to 0.03.
top_n (int | None, optional): Keep at most this many detections per segment,
the highest-scoring ones; ``min_conf`` still applies. Defaults to None.
merge_consecutive (int, optional): Maximum number of consecutive detections
of a species merged into one; 0 or 1 disables merging. Defaults to 1.
locale (str, optional): Language of the species names of a BirdNET model;
one its version lacks falls back to "en_us" with a warning.
Defaults to "en_us".
additional_columns (list[str] | None, optional): Extra columns of the "csv"
and "parquet" results, any of "lat", "lon", "week", "overlap",
"sensitivity", "min_conf", "species_list" and "model". Defaults to None.
on_update (Callable[[AcousticProgressStats], None] | None, optional): Called
with the progress of the inference. Defaults to None.
split_tables (bool, optional): Write the results of each input file to files
of their own. Defaults to False.
strict_species_list (bool, optional): If True, raise when a species in ``slist``
is not in the model. If False (default), such species are matched to the
model by scientific/common name where possible and any that remain unknown
are skipped with a warning. Only affects a user-provided ``slist``.
are skipped with a warning. Only affects an ``slist`` file.
save_params (bool, optional): Write the parameters to
"birdnet.analyze-params.csv" in ``output``. Defaults to False.
_return_only (bool, optional): Only return the predictions, without writing
result files or a resume journal. Defaults to False.
Returns:
None
The predictions, a birdnet ``AcousticFilePredictionResult``. A resumed run
returns those of the files it analyzed, or None if none were left.
Raises:
ValueError: If input path is invalid or required parameters are missing.
ValueError: If only one of ``lat`` and ``lon`` is given, they are combined
with ``slist``, ``classifier`` is combined with ``model`` "perch",
``lat``, ``lon``, ``week`` or ``min_conf`` is out of range, ``model`` is
unknown, ``audio_input`` does not exist or holds no supported audio file,
or none of the species in an ``slist`` file (with
``strict_species_list``, not all of them) are in the model.
FileNotFoundError: If the ``slist`` file or ``classifier`` does not exist.
RuntimeError: If the resume state in ``output`` is incomplete, or the
analysis is cancelled or one of its processes dies.
Notes:
- The function ensures the BirdNET model is available before analysis.
- Analysis parameters are saved to a file in the output directory.
- Directory analyses are resumable: per-file results are journaled to
``<output>/.birdnet-resume/`` as they complete, an interrupted run
picks up where it left off (if the analysis parameters match), and
the journal is removed after outputs are written. When resuming a
run that had already completed every file, no new inference happens
and ``None`` is returned instead of a prediction result.
Directory analyses are resumable: per-file results are journaled to
``<output>/.birdnet-resume/`` as they complete, an interrupted run picks up
where it left off (if the analysis parameters match), and the journal is
removed after the outputs are written.
"""
import birdnet_analyzer.config as cfg
from birdnet_analyzer.analyze.resume import ResumeJournal, RunMetadata
Expand All @@ -124,6 +150,14 @@ def analyze(
)
from birdnet_analyzer.utils import save_params_file

if classifier and model == "perch":
raise ValueError("Select either Perch or a custom classifier, not both.")

if (lat is None) != (lon is None):
raise ValueError(
"Set both lat and lon to limit the species to a location, or neither."
)

# Settled before the params file, result columns and resume fingerprint see it.
sensitivity = effective_sensitivity(sensitivity, model)
validate_min_conf(min_conf)
Expand Down
36 changes: 21 additions & 15 deletions birdnet_analyzer/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,15 @@
from birdnet_analyzer.config import (
ALL_MODEL_LANGUAGES,
AUTOTUNE_METRICS,
CROP_MODES,
DEFAULT_ACOUSTIC_MODEL_VERSION,
GEO_MODEL_LANGUAGES,
RESULT_TYPES,
SAMPLE_CROP_MODES,
SCORE_FUNCTIONS,
TRAINED_MODEL_OUTPUT_FORMATS,
TRAINED_MODEL_SAVE_MODES,
UPSAMPLING_MODES,
)
from birdnet_analyzer.logs import setup_logging

Expand Down Expand Up @@ -467,9 +473,9 @@ def __call__(self, parser, namespace, values, option_string=None):
parser.add_argument(
"--rtype",
default={"table"},
choices=["table", "audacity", "kaleidoscope", "csv", "parquet"],
choices=get_args(RESULT_TYPES),
nargs="+",
help="Specifies output format. Values in `['table', 'audacity', 'kaleidoscope', 'csv', 'parquet']`.",
help="Specifies output format.",
action=UniqueSetAction,
)
parser.add_argument(
Expand All @@ -482,7 +488,7 @@ def __call__(self, parser, namespace, values, option_string=None):
parser.add_argument(
"-c",
"--classifier",
help="Path to custom trained classifier. If set, --lat, --lon and --locale are ignored.",
help="Path to custom trained classifier. Its species names come from its labels file, so --locale is ignored. --lat and --lon keep only its species that the geo model predicts there, or, with a warning, all of them if it predicts none.",
)
parser.add_argument(
"--cc_species_list",
Expand All @@ -491,7 +497,7 @@ def __call__(self, parser, namespace, values, option_string=None):
parser.add_argument(
"--top_n",
type=lambda a: max(1, int(a)),
help="Saves only the top N predictions for each segment independent of their score. Threshold will be ignored.",
help="Saves at most the top N predictions for each segment. --min_conf still applies.",
)
parser.add_argument(
"--merge_consecutive",
Expand Down Expand Up @@ -579,14 +585,14 @@ def search_parser():
parser.add_argument(
"--score_function",
default="cosine",
choices=["cosine", "euclidean", "dot"],
help="Scoring function to use. Choose 'cosine', 'euclidean' or 'dot'.",
choices=get_args(SCORE_FUNCTIONS),
help="Scoring function to use.",
)
parser.add_argument(
"--crop_mode",
default="center",
choices=["center", "first", "segments"],
help="Crop mode for the query sample. Can be 'center', 'first' or 'segments'.",
choices=get_args(CROP_MODES),
help="Crop mode for the query sample.",
)

parser.add_argument(
Expand Down Expand Up @@ -659,12 +665,12 @@ def segments_parser():


def species_parser():
"""Build the argument parser for retrieving a species list for a location."""
"""Build the argument parser for retrieving a species list."""
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
parents=[
species_list_args(),
# The species list comes from the geo model, so only its languages apply.
# The geo model's languages, which the default acoustic model shares.
locale_args(languages=GEO_MODEL_LANGUAGES),
verbosity_args(),
],
Expand Down Expand Up @@ -711,8 +717,8 @@ def train_parser():
parser.add_argument(
"--crop_mode",
default="center",
choices=["center", "first", "segments", "smart"],
help="Crop mode for training data. Can be 'center', 'first', 'segments' or 'smart'.",
choices=get_args(SAMPLE_CROP_MODES),
help="Crop mode for training data.",
)
parser.add_argument(
"--birdnet",
Expand Down Expand Up @@ -793,20 +799,20 @@ def train_parser():
parser.add_argument(
"--upsampling_mode",
default="repeat",
choices=["repeat", "linear", "mean", "smote"],
choices=get_args(UPSAMPLING_MODES),
help="Upsampling mode.",
)
parser.add_argument(
"--model_formats",
nargs="+",
default=["tflite"],
choices=get_args(TRAINED_MODEL_OUTPUT_FORMATS),
help="Model output format(s). One or more of 'tflite', 'raven', 'detached'.",
help="Model output format(s).",
)
parser.add_argument(
"--model_save_mode",
default="replace",
choices=["replace", "append"],
choices=get_args(TRAINED_MODEL_SAVE_MODES),
help="Model save mode. 'replace' will overwrite the original classification layer and 'append' will combine the original classification layer with the new one.",
)
parser.add_argument(
Expand Down
16 changes: 9 additions & 7 deletions birdnet_analyzer/embeddings/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ def embeddings(
Args:
audio_input (str): Path to the input audio file or directory containing audio
files.
database (str): Path to the database where embeddings will be stored.
database (str): Path to the database where embeddings will be stored. It is
created if it does not exist.
overlap (float, optional): Overlap between consecutive audio segments in
seconds. Defaults to 0.0.
audio_speed (float, optional): Speed factor for audio processing.
Expand All @@ -53,15 +54,16 @@ def embeddings(
batch. Defaults to 1.
file_output (str | None, optional): Path to save the output embeddings. If None,
embeddings are not saved to a file. Defaults to None.
n_workers (int | None, optional): Number of worker threads to use for
processing. Defaults to None.
n_producers (int, optional): Number of producer threads to use for processing.
Defaults to 1.
n_workers (int | None, optional): Number of worker processes to use for
processing. Defaults to None, one per physical CPU core.
n_producers (int, optional): Number of producer processes to use for
processing. Defaults to 1.
on_update (Callable[[AcousticProgressStats], None] | None, optional): Callback
function to report progress updates. Defaults to None.
Raises:
FileNotFoundError: If the input path or database path does not exist.
ValueError: If any of the parameters are invalid.
ValueError: If ``audio_input`` does not exist or holds no supported audio
file, or if the database was created with a different ``fmin``, ``fmax``,
``audio_speed`` or parent folder of ``audio_input``.
Example:
embeddings(
"path/to/audio",
Expand Down
44 changes: 28 additions & 16 deletions birdnet_analyzer/gui/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@


def on_progress(update: AcousticProgressStats, progress: gr.Progress):
if progress is None:
return

if update.processed_segments and update.total_segments:
progress(
(update.processed_segments, update.total_segments),
Expand Down Expand Up @@ -65,35 +62,50 @@ def run_analysis(
"""Starts the analysis.

Args:
input_path: Either a file or directory.
output_path: The output path for the result, if None the input_path is used
input_path: The audio file of the single file tab. If set, the predictions
are only returned, no result files are written.
output_path: The output folder; if None, the folder of the input.
use_top_n: Whether to keep the ``top_n`` highest-scoring detections per
segment instead of those above ``confidence``.
top_n: The number of detections kept per segment with ``use_top_n``.
confidence: The selected minimum confidence.
sensitivity: The selected sensitivity.
overlap: The selected segment overlap.
merge_consecutive: The number of consecutive segments to merge into one.
audio_speed: The selected audio speed.
audio_speed: The value of the audio speed slider.
fmin: The selected minimum bandpass frequency.
fmax: The selected maximum bandpass frequency.
species_list_choice: The choice for the species list.
species_list_file: The selected custom species list file.
lat: The selected latitude.
lon: The selected longitude.
species_list_file: The species list file, used with the custom species list
choice.
lat: The latitude, used with the predicted species list choice.
lon: The longitude, used with the predicted species list choice.
week: The selected week of the year.
use_yearlong: Use yearlong instead of week.
sf_thresh: The threshold for the predicted species list.
custom_classifier_file: Custom classifier to be used.
output_type: The type of result to be generated.
selected_model: The model choice: a BirdNET version, Perch or the custom
classifier.
custom_classifier_file: The classifier file, used with the custom classifier
choice.
output_types: The result type(s) to write.
additional_columns: Additional columns to be added to the result.
output_filename: The filename for the combined output.
locale: The translation to be used.
batch_size: The number of samples in a batch.
n_producers: The number of producer threads to be used.
n_workers: The number of worker threads to be used.
input_dir: The input directory.
input_dir: The folder of the multi file tab, analyzed instead of
``input_path``.
save_params: Whether to write the parameters file next to the results.
n_producers: The number of producer processes.
n_workers: The number of worker processes.
progress: The gradio progress bar.
split_tables: Whether to split the output into separate tables per input file.
Defaults to False.

Returns:
The predictions returned by the analysis.

Raises:
gr.Error: If the custom species list or custom classifier choice has no file.
"""
import birdnet_analyzer.gui.localization as loc
from birdnet_analyzer.analyze import analyze

if species_list_choice == gu.CUSTOM_SPECIES:
Expand Down
Loading
Loading