Skip to content

Commit

Permalink
1.2.0 (#364)
Browse files Browse the repository at this point in the history
* release 1.2.0

* updated local paths to be pyinstaller compliant

* error log in settings

* check for missong error log

* small fixes

* added language contribution to README

---------

Co-authored-by: Josef Haupt <[email protected]>
  • Loading branch information
Josef-Haupt and Josef Haupt authored Jun 25, 2024
1 parent b1dc845 commit 839297c
Show file tree
Hide file tree
Showing 13 changed files with 156 additions and 117 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ foo*
# Installers
installers/
desktop.ini
*.iss

# Custom classifier
checkpoints/custom/
Expand Down
52 changes: 0 additions & 52 deletions BirdNET-Anaylzer-setup.iss

This file was deleted.

5 changes: 5 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,11 @@ Due to these custom labels, the location filter and locale will be disabled.
+
. To train with multi-label data separate the class labels with commas in the folder names (e.g., `Poecile atricapillus_Black-capped Chickadee, Cardinalis cardinalis_Northern Cardinal`). This can also be combined with negative samples as described above. The validation split will be performed combination of classes, so you might want to ensure sufficient data for each combination of classes. When using multi-label data the upsampling mode will be limited to 'repeat'.

== GUI Language

The default language of the GUI is English, but you can change it to German in the *Settings* tab of the GUI. If you want to contribute a translation to another language you, use the files inside the `lang` folder as a template. You can then send us the translated files or create a pull request.
To check your translation, place your file inside the `lang` folder and start the GUI, your language should now be available in the *Settings* tab. After selecting your language, you should restart the GUI to apply the changes.

== Funding

This project is supported by Jake Holshuh (Cornell class of `'69) and The Arthur Vining Davis Foundations.
Expand Down
16 changes: 8 additions & 8 deletions analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

# 0 1 2 3 4 5 6 7 8 9 10 11
RTABLE_HEADER = "Selection\tView\tChannel\tBegin Time (s)\tEnd Time (s)\tLow Freq (Hz)\tHigh Freq (Hz)\tCommon Name\tSpecies Code\tConfidence\tBegin Path\tFile Offset (s)\n"
SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))


def loadCodes():
Expand All @@ -28,7 +29,7 @@ def loadCodes():
Returns:
A dictionary containing the eBird codes.
"""
with open(cfg.CODES_FILE, "r") as cfile:
with open(os.path.join(SCRIPT_DIR, cfg.CODES_FILE), "r") as cfile:
codes = json.load(cfile)

return codes
Expand Down Expand Up @@ -530,13 +531,12 @@ def analyzeFile(item):
args = parser.parse_args()

# Set paths relative to script path (requested in #3)
script_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
cfg.MODEL_PATH = os.path.join(script_dir, cfg.MODEL_PATH)
cfg.LABELS_FILE = os.path.join(script_dir, cfg.LABELS_FILE)
cfg.TRANSLATED_LABELS_PATH = os.path.join(script_dir, cfg.TRANSLATED_LABELS_PATH)
cfg.MDATA_MODEL_PATH = os.path.join(script_dir, cfg.MDATA_MODEL_PATH)
cfg.CODES_FILE = os.path.join(script_dir, cfg.CODES_FILE)
cfg.ERROR_LOG_FILE = os.path.join(script_dir, cfg.ERROR_LOG_FILE)
cfg.MODEL_PATH = os.path.join(SCRIPT_DIR, cfg.MODEL_PATH)
cfg.LABELS_FILE = os.path.join(SCRIPT_DIR, cfg.LABELS_FILE)
cfg.TRANSLATED_LABELS_PATH = os.path.join(SCRIPT_DIR, cfg.TRANSLATED_LABELS_PATH)
cfg.MDATA_MODEL_PATH = os.path.join(SCRIPT_DIR, cfg.MDATA_MODEL_PATH)
cfg.CODES_FILE = os.path.join(SCRIPT_DIR, cfg.CODES_FILE)
cfg.ERROR_LOG_FILE = os.path.join(SCRIPT_DIR, cfg.ERROR_LOG_FILE)

# Load eBird codes, labels
cfg.CODES = loadCodes()
Expand Down
2 changes: 1 addition & 1 deletion config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#################

# GUI version
GUI_VERSION: str = "1.1.0"
GUI_VERSION: str = "1.2.0"

# Random seed for gaussian noise
RANDOM_SEED: int = 42
Expand Down
36 changes: 22 additions & 14 deletions embeddings.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Module used to extract embeddings for samples.
"""

import argparse
import datetime
import os
Expand All @@ -14,6 +15,8 @@
import model
import utils

SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))


def writeErrorLog(msg):
with open(cfg.ERROR_LOG_FILE, "a") as elog:
Expand All @@ -22,7 +25,7 @@ def writeErrorLog(msg):

def saveAsEmbeddingsFile(results: dict[str], fpath: str):
"""Write embeddings to file
Args:
results: A dictionary containing the embeddings at timestamp.
fpath: The path for the embeddings file.
Expand Down Expand Up @@ -92,7 +95,7 @@ def analyzeFile(item):
# Reset batch
samples = []
timestamps = []

offset = offset + duration

except Exception as ex:
Expand All @@ -113,7 +116,9 @@ def analyzeFile(item):
fdir = os.path.join(cfg.OUTPUT_PATH, os.path.dirname(fpath))
os.makedirs(fdir, exist_ok=True)

saveAsEmbeddingsFile(results, os.path.join(cfg.OUTPUT_PATH, fpath.rsplit(".", 1)[0] + ".birdnet.embeddings.txt"))
saveAsEmbeddingsFile(
results, os.path.join(cfg.OUTPUT_PATH, fpath.rsplit(".", 1)[0] + ".birdnet.embeddings.txt")
)
else:
saveAsEmbeddingsFile(results, cfg.OUTPUT_PATH)

Expand All @@ -138,30 +143,33 @@ def analyzeFile(item):
"--o", default="example/", help="Path to output file or folder. If this is a file, --i needs to be a file too."
)
parser.add_argument(
"--overlap", type=float, default=0.0, help="Overlap of prediction segments. Values in [0.0, 2.9]. Defaults to 0.0."
"--overlap",
type=float,
default=0.0,
help="Overlap of prediction segments. Values in [0.0, 2.9]. Defaults to 0.0.",
)
parser.add_argument("--threads", type=int, default=4, help="Number of CPU threads.")
parser.add_argument(
"--batchsize", type=int, default=1, help="Number of samples to process at the same time. Defaults to 1."
)
parser.add_argument(
"--fmin",
type=int,
default=cfg.SIG_FMIN,
help="Minimum frequency for bandpass filter in Hz. Defaults to {} Hz.".format(cfg.SIG_FMIN)
"--fmin",
type=int,
default=cfg.SIG_FMIN,
help="Minimum frequency for bandpass filter in Hz. Defaults to {} Hz.".format(cfg.SIG_FMIN),
)
parser.add_argument(
"--fmax",
type=int,
default=cfg.SIG_FMAX,
help="Maximum frequency for bandpass filter in Hz. Defaults to {} Hz.".format(cfg.SIG_FMAX)
"--fmax",
type=int,
default=cfg.SIG_FMAX,
help="Maximum frequency for bandpass filter in Hz. Defaults to {} Hz.".format(cfg.SIG_FMAX),
)

args = parser.parse_args()

# Set paths relative to script path (requested in #3)
cfg.MODEL_PATH = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), cfg.MODEL_PATH)
cfg.ERROR_LOG_FILE = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), cfg.ERROR_LOG_FILE)
cfg.MODEL_PATH = os.path.join(SCRIPT_DIR, cfg.MODEL_PATH)
cfg.ERROR_LOG_FILE = os.path.join(SCRIPT_DIR, cfg.ERROR_LOG_FILE)

### Make sure to comment out appropriately if you are not using args. ###

Expand Down
Loading

0 comments on commit 839297c

Please sign in to comment.