Skip to content

Commit

Permalink
Adjusted lists for BirdNET so birds & migrants returns just birds, an…
Browse files Browse the repository at this point in the history
…d not non-bird detections.
  • Loading branch information
Mattk70 committed Jan 25, 2024
1 parent 137a336 commit 74e4e40
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 57 deletions.
27 changes: 17 additions & 10 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,22 +67,29 @@ <h5>Welcome to Chirpity Nocmig</h5>
</div>
</div>
<div class="carousel-item" data-element-selector="#navbarSettings">
<img src="img/logo/chirpity_logo2.png" class="w-100 rounded pb-4" alt="Image 1">
<img src="img/logo/chirpity_logo2.png" class="w-100 rounded pb-4" alt="Chiprity Nocmig">
<div class="text-center pb-4">
<h5>Settings</h5>
<p>Here is where you set a number of defaults, including your recording location,
system preferences, audio preferences and spectrogram options.
<p>When getting started, here is where you should set a number of default settings, especially your recording location.
You may also want to tune system parameters, audio preferences and spectrogram options.
</p>
</div>
</div>
<div class="carousel-item" data-element-selector="#filter-panel">
<img src="img/logo/chirpity_logo2.png" class="w-100 rounded pb-4" alt="Chiprity Nocmig">
<div class="text-center pb-4">
<h5>Filter panel</h5>
<p>The icons here toggle the filters available. These enable Nocmig mode, Audio
filters, Context-aware mode,
the detection list to use and confidence threshold. Note, the confidence
threshold can be adjusted at any time,
<h5>Quick access settings panel</h5>
<p>The icons here allow you to qucikly toggle some frequently used settings.
These include:
<ul>
<li>Nocmig mode
<li>Audio filters
<li>Context-aware mode
<li>Which detection list to use
<li>Fullscreen mode for the spectrogram
<li>And the confidence threshold.
</ul>
Note, the confidence threshold can be adjusted at any time,
even after a file analysis has taken place.
</p>
</div>
Expand All @@ -99,7 +106,7 @@ <h5>Context Menus</h5>
</div>
</div>
<div class="carousel-item" data-element-selector="#navbarRecords">
<img src="img/logo/chirpity_logo2.png" class="w-100 rounded pb-4" alt="Image 1">
<img src="img/logo/chirpity_logo2.png" class="w-100 rounded pb-4" alt="Chiprity Nocmig">
<div class="text-center pb-4">
<h5>Saved Records</h5>
<p>You can save records for future reference from the Records menu. Here you will
Expand Down Expand Up @@ -272,7 +279,7 @@ <h5>Saved Records</h5>
<div class="input-group col">
<span class="input-group-text pe-2">Threshold:</span>
<input id="species-frequency-threshold" type="number"
class="form-control ps-2 rounded-3 w-25" value="0.005" step="0.001" min="0.001" max="1"
class="form-control ps-2 rounded-3 w-25" value="0.005" step="0.001" min="0.001" max="1" value="0.03"
aria-label="species frequency threshold" aria-describedby="species-frequency-threshold">
<span class="circle"
title="Set the minimum eBird checklist frequency for a bird to be included">?</span>
Expand Down
73 changes: 28 additions & 45 deletions js/BirdNet2.4.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ let BACKEND;
//GLOBALS
let myModel;
// const MIGRANTS = new Set(["Pluvialis dominica_American Golden Plover", "Acanthis hornemanni_Arctic Redpoll", "Sterna paradisaea_Arctic Tern", "Recurvirostra avosetta_Avocet", "Porzana pusilla_Baillon's Crake", "Limosa lapponica_Bar-tailed Godwit", "Tyto alba_Barn Owl", "Branta leucopsis_Barnacle Goose", "Cygnus columbianus_Bewick's Swan", "Botaurus stellaris_Bittern", "Chroicocephalus ridibundus_Black-headed Gull", "Podiceps nigricollis_Black-necked Grebe", "Limosa limosa_Black-tailed Godwit", "Turdus merula_Blackbird", "Sylvia atricapilla_Blackcap", "Fringilla montifringilla_Brambling", "Branta bernicla_Brent Goose", "Branta canadensis_Canada Goose", "Larus cachinnans_Caspian Gull", "Phylloscopus collybita_Chiffchaff", "Loxia curvirostra_Common Crossbill", "Larus canus_Common Gull", "Acanthis flammea_Common Redpoll", "Actitis hypoleucos_Common Sandpiper", "Melanitta nigra_Common Scoter", "Sterna hirundo_Common Tern", "Fulica atra_Coot", "Crex crex_Corncrake", "Cuculus canorus_Cuckoo", "Calidris ferruginea_Curlew Sandpiper", "Numenius arquata_Curlew", "Charadrius morinellus_Dotterel", "Calidris alpina_Dunlin", "Prunella modularis_Dunnock", "Alopochen aegyptiaca_Egyptian Goose", "Turdus pilaris_Fieldfare", "Mareca strepera_Gadwall", "Sylvia borin_Garden Warbler", "Spatula querquedula_Garganey", "Regulus regulus_Goldcrest", "Pluvialis apricaria_Golden Plover", "Bucephala clangula_Goldeneye", "Mergus merganser_Goosander", "Locustella naevia_Grasshopper Warbler", "Larus marinus_Great Black-backed Gull", "Podiceps cristatus_Great Crested Grebe", "Tringa ochropus_Green Sandpiper", "Tringa nebularia_Greenshank", "Ardea cinerea_Grey Heron", "Perdix perdix_Grey Partridge", "Phalaropus fulicarius_Grey", "Pluvialis squatarola_Grey Plover", "Motacilla cinerea_Grey Wagtail ", "Anser anser_Greylag Goose", "Delichon urbicum_House Martin", "Coccothraustes coccothraustes_Hawfinch", "Larus argentatus_Herring Gull", "Lymnocryptes minimus_Jack Snipe", "Alcedo atthis_Kingfisher", "Calidris canutus_Knot", "Calcarius lapponicus_Lapland Bunting", "Larus fuscus_Lesser Black-backed Gull", "Acanthis cabaret_Lesser Redpoll ", "Sylvia curruca_Lesser Whitethroat", "Linaria cannabina_Linnet", "Egretta garzetta_Little Egret", "Tachybaptus ruficollis_Little Grebe", "Hydrocoloeus minutus_Little Gull", "Athene noctua_Little Owl", "Charadrius dubius_Little Ringed Plover", "Calidris minuta_Little Stint ", "Sternula albifrons_Little Tern", "Asio otus_Long-eared Owl", "Clangula hyemalis_Long-tailed Duck", "Anas platyrhynchos_Mallard", "Aix galericulata_Mandarin Duck", "Anthus pratensis_Meadow Pipit", "Ichthyaetus melanocephalus_Mediterranean Gull", "Turdus viscivorus_Mistle Thrush", "Gallinula chloropus_Moorhen", "Nycticorax nycticorax_Night Heron", "Luscinia megarhynchos_Nightingale", "Luscinia megarhynchos_Nightingale (song)", "Caprimulgus europaeus_Nightjar", "Anthus hodgsoni_Olive-backed Pipit", "Emberiza hortulana_Ortolan Bunting", "Emberiza pusilla_Little Bunting", "Haematopus ostralegus_Oystercatcher", "Ficedula hypoleuca_Pied Flycatcher", "Motacilla alba_Pied Wagtail", "Anser brachyrhynchus_Pink-footed Goose", "Anas acuta_Pintail", "Aythya ferina_Pochard", "Calidris maritima_Purple Sandpiper", "Coturnix coturnix_Quail", "Mergus serrator_Red-breasted Merganser", "Netta rufina_Red-crested Pochard", "Alectoris rufa_Red-legged Partridge", "Tringa totanus_Redshank", "Phoenicurus phoenicurus_Redstart", "Turdus iliacus_Redwing", "Emberiza schoeniclus_Reed Bunting", "Acrocephalus scirpaceus_Reed Warbler", "Turdus torquatus_Ring Ouzel", "Charadrius hiaticula_Ringed Plover", "Erithacus rubecula_Robin (flight call)", "Anthus petrosus_Rock Pipit", "Sterna dougallii_Roseate Tern", "Calidris pugnax_Ruff", "Riparia riparia_Sand Martin", "Calidris alba_Sanderling", "Thalasseus sandvicensis_Sandwich Tern", "Aythya marila_Scaup", "Loxia scotica_Scottish Crossbill", "Acrocephalus schoenobaenus_Sedge Warbler", "Tadorna tadorna_Shelduck", "Asio flammeus_Short-eared Owl", "Spatula clypeata_Shoveler", "Spinus spinus_Siskin", "Alauda arvensis_Skylark", "Gallinago gallinago_Snipe", "Plectrophenax nivalis_Snow Bunting", "Turdus philomelos_Song Thrush", "Porzana porzana_Spotted Crake", "Muscicapa striata_Spotted Flycatcher", "Tringa erythropus_Spotted Redshank", "Burhinus oedicnemus_Stone-curlew", "Saxicola rubicola_Stonechat", "Hirundo rustica_Swallow", "Apus apus_Swift", "Anser fabalis_Taiga Bean Goose", "Strix aluco_Tawny Owl", "Anas crecca_Teal", "Anthus trivialis_Tree Pipit", "Aythya fuligula_Tufted Duck", "Anser serrirostris_Tundra Bean Goose", "Arenaria interpres_Turnstone", "Anthus spinoletta_Water Pipit", "Rallus aquaticus_Water Rail", "Numenius phaeopus_Whimbrel", "Anser albifrons_White-fronted Goose", "Sylvia communis_Whitethroat", "Cygnus cygnus_Whooper Swan", "Mareca penelope_Wigeon", "Phylloscopus trochilus_Willow Warbler", "Tringa glareola_Wood Sandpiper", "Scolopax rusticola_Woodcock", "Lullula arborea_Woodlark", "Larus michahellis_Yellow-legged Gull", "Motacilla flava_Yellow Wagtail", "Emberiza citrinella_Yellowhammer"]);
// const NOT_BIRDS = ['Ambient Noise_Ambient Noise', 'Animal_Animal', 'Cat_Cat', 'Church Bells_Church Bells', 'Cough_Cough', 'Dog_Dog', 'Human_Human', 'Laugh_Laugh', 'Rain_Rain', 'Red Fox_Red Fox', 'Sneeze_Sneeze', 'Snoring_Snoring', 'Thunder_Thunder', 'Vehicle_Vehicle', 'Water Drops_Water Drops', 'Waves_Waves', 'Wind_Wind'];
const NOT_BIRDS = ['Dog_Dog', 'Environmental_Environmental', 'Engine_Engine', 'Fireworks_Fireworks',
'Gryllus assimilis_Gryllus assimilis', 'Gun_Gun', 'Human non-vocal_Human non-vocal', 'Human vocal_Human vocal',
'Human whistle_Human whistle', 'Miogryllus saussurei_Miogryllus saussurei', 'Noise_Noise',
'Power tools_Power tools', 'Siren_Siren'];
const MYSTERIES = ['Unknown Sp._Unknown Sp.'];
const GRAYLIST = [];
const GOLDEN_LIST = []
Expand Down Expand Up @@ -209,52 +212,32 @@ class Model {
async setList() {
BLOCKED_IDS = [];
if (this.list === "everything") return
// Dummy location and week
const lat = this.lat;
const lon = this.lon;
const week = this.week;
console.log('lat', lat, 'lon', lon, 'week', week)
this.mdata_input = tf.tensor([lat, lon, week]).expandDims(0);
const mdata_prediction = this.metadata_model.predict(this.mdata_input);
const mdata_probs = await mdata_prediction.data();
const mdata_probs_sorted = mdata_probs.slice().sort().reverse();
let count = 0
for (let i = 0; i < mdata_probs.length; i++) {
if (mdata_probs[i] > this.speciesThreshold) {
count++;
DEBUG && console.log("including:", this.labels[i] + ': ' + mdata_probs[i]);
} else {
DEBUG && console.log("Excluding:", this.labels[i] + ': ' + mdata_probs[i]);
// Hack to add Dotterel??
//if (! this.labels[i].includes('Dotterel'))
BLOCKED_IDS.push(i)
else if (this.list === 'location'){
const lat = this.lat;
const lon = this.lon;
const week = this.week;
DEBUG && console.log('lat', lat, 'lon', lon, 'week', week)
this.mdata_input = tf.tensor([lat, lon, week]).expandDims(0);
const mdata_prediction = this.metadata_model.predict(this.mdata_input);
const mdata_probs = await mdata_prediction.data();
const mdata_probs_sorted = mdata_probs.slice().sort().reverse();
let count = 0
for (let i = 0; i < mdata_probs.length; i++) {
if (mdata_probs[i] > this.speciesThreshold) {
count++;
DEBUG && console.log("including:", this.labels[i] + ': ' + mdata_probs[i]);
} else {
DEBUG && console.log("Excluding:", this.labels[i] + ': ' + mdata_probs[i]);
// Hack to add Dotterel??
//if (! this.labels[i].includes('Dotterel'))
BLOCKED_IDS.push(i)
}
}
}
//console.log('Total species considered at this location: ', count)
// get the indices of any items in the blacklist, GRAYLIST
// if (this.list === 'birds') {
// // find the position of the blocked items in the label list
// NOT_BIRDS.forEach(notBird => BLOCKED_IDS.push(this.labels.indexOf(notBird)))
// } else if (this.list === 'migrants') {
// let v1_migrants;
// if (this.version === 'v1') {
// // strip (call) from migrants set
// v1_migrants = new Set();
// MIGRANTS.forEach((element) => {
// const newElement = element.replace(' (call)', '');
// v1_migrants.add(newElement);
// })

// }
// const listToCheck = v1_migrants || MIGRANTS;
// for (let i = 0; i < this.labels.length; i++) {
// const item = this.labels[i];
// if (!listToCheck.has(item) && !MYSTERIES.includes(item)) BLOCKED_IDS.push(i);
// }

// }
// GRAYLIST.forEach(species => SUPPRESSED_IDS.push(this.labels.indexOf(species)))
// GOLDEN_LIST.forEach(species => ENHANCED_IDS.push(this.labels.indexOf(species)))
else {
// find the position of the blocked items in the label list
NOT_BIRDS.forEach(notBird => BLOCKED_IDS.push(this.labels.indexOf(notBird)))
}
}

normalize(spec) {
Expand Down
13 changes: 11 additions & 2 deletions js/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -628,13 +628,14 @@ const displayLocationAddress = async (where) => {
lonEl = document.getElementById('customLon');
placeEl = document.getElementById('customPlace');
address = await fetchLocationAddress(latEl.value, lonEl.value, false);
if (address === false) return
placeEl.value = address || 'Location not available';
} else {

latEl = document.getElementById('latitude');
lonEl = document.getElementById('longitude');
placeEl = document.getElementById('place');
address = await fetchLocationAddress(latEl.value, lonEl.value, false);
if (address === false) return
const content = '<span class="material-symbols-outlined">fmd_good</span> ' + address;
placeEl.innerHTML = content;
config.latitude = parseFloat(latEl.value).toFixed(2);
Expand Down Expand Up @@ -876,6 +877,10 @@ function postAnalyseMessage(args) {


function fetchLocationAddress(lat, lon) {
if (isNaN(lat) || isNaN(lon || lat === '' || lon === '')){
alert('Both lat and lon values need to be numbers between 180 and -180')
return false
}
return new Promise((resolve, reject) => {
if (!LOCATIONS) {
worker.postMessage({ action: 'get-locations', file: currentFile });
Expand Down Expand Up @@ -1347,7 +1352,7 @@ window.onload = async () => {
colormap: 'inferno',
timeOfDay: false,
list: 'migrants',
speciesThreshold: 0.004,
speciesThreshold: 0.03,
model: 'v2',
latitude: 52.87,
longitude: 0.89, // Great Snoring :)
Expand Down Expand Up @@ -2176,6 +2181,10 @@ listToUse.addEventListener('change', function (e) {
})

speciesThreshold.addEventListener('change', () =>{
if (isNaN(speciesThreshold.value) || speciesThreshold.value === '') {
alert('The threshold must be a number between 0.001 and 1');
return false
}
config.speciesThreshold = speciesThreshold.value;
updatePrefs();
worker.postMessage({ action: 'update-state', speciesThreshold: speciesThreshold.value });
Expand Down

0 comments on commit 74e4e40

Please sign in to comment.