diff --git a/src/AnalysisConfigFiles/RecognizerConfigFiles/Towsey.PteropusSpecies.yml b/src/AnalysisConfigFiles/RecognizerConfigFiles/Towsey.PteropusSpecies.yml index 8463c0a29..b3c55de57 100644 --- a/src/AnalysisConfigFiles/RecognizerConfigFiles/Towsey.PteropusSpecies.yml +++ b/src/AnalysisConfigFiles/RecognizerConfigFiles/Towsey.PteropusSpecies.yml @@ -1,8 +1,6 @@ --- -# Should be in proper casing. The full real name of the species SpeciesName: Pteropus species CommonName: Flying Fox -# Abbreviation of species name, format how you like AbbreviatedSpeciesName: PteropusSp #Proposed Approach: @@ -26,8 +24,8 @@ Profiles: # The below settings are a template Standard: &STANDARD # min and max of the freq band to search - MinHz: 3000 - MaxHz: 5000 + MinHz: 100 + MaxHz: 7000 # duration of DCT in seconds DctDuration: 0.15 # minimum acceptable value of a DCT coefficient @@ -38,7 +36,7 @@ Profiles: MaxOcilFreq: 140 # Minimum and maximum duration for the length of a true call. MinDuration: 0.1 - MaxDuration: 0.8 + MaxDuration: 0.5 # Event threshold - use this to determine FP / FN trade-off for events. EventThreshold: 0.30 # This notation means the Groote profile has all of the settings that the Standard profile has, diff --git a/src/AnalysisPrograms/Recognizers/LitoriaFallax.cs b/src/AnalysisPrograms/Recognizers/LitoriaFallax.cs index ebdaf7570..cd9962f8b 100644 --- a/src/AnalysisPrograms/Recognizers/LitoriaFallax.cs +++ b/src/AnalysisPrograms/Recognizers/LitoriaFallax.cs @@ -1,4 +1,4 @@ -// -------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // // All code in this file and all associated files are the copyright and property of the QUT Ecoacoustics Research Group (formerly MQUTeR, and formerly QUT Bioacoustics Research Group). // @@ -201,7 +201,7 @@ private void WriteDebugImage( bool displayDebugImage = MainEntry.InDEBUG; if (displayDebugImage) { - Image debugImage1 = LitoriaRothii.DisplayDebugImage(sonogram, acousticEvents, plots, hits); + Image debugImage1 = SpectrogramTools.GetSonogramPlusCharts(sonogram, acousticEvents, plots, hits); var debugPath1 = outputDirectory.Combine( FilenameHelpers.AnalysisResultName( @@ -231,7 +231,7 @@ private void WriteDebugImage( this.Identifier, "png", "DebugSpectrogram2")); - Image debugImage2 = LitoriaRothii.DisplayDebugImage(sonogram2, acousticEvents, plots, null); + Image debugImage2 = SpectrogramTools.GetSonogramPlusCharts(sonogram2, acousticEvents, plots, null); debugImage2.Save(debugPath2.FullName); } } diff --git a/src/AnalysisPrograms/Recognizers/LitoriaFreycineti.cs b/src/AnalysisPrograms/Recognizers/LitoriaFreycineti.cs index aec2abc29..41c9f4ba8 100644 --- a/src/AnalysisPrograms/Recognizers/LitoriaFreycineti.cs +++ b/src/AnalysisPrograms/Recognizers/LitoriaFreycineti.cs @@ -1,4 +1,4 @@ -// -------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // // All code in this file and all associated files are the copyright and property of the QUT Ecoacoustics Research Group (formerly MQUTeR, and formerly QUT Bioacoustics Research Group). // @@ -195,7 +195,7 @@ private void WriteDebugImage( bool displayDebugImage = MainEntry.InDEBUG; if (displayDebugImage) { - Image debugImage1 = LitoriaRothii.DisplayDebugImage(sonogram, acousticEvents, plots, hits); + Image debugImage1 = SpectrogramTools.GetSonogramPlusCharts(sonogram, acousticEvents, plots, hits); var debugPath1 = outputDirectory.Combine( FilenameHelpers.AnalysisResultName( @@ -225,7 +225,7 @@ private void WriteDebugImage( this.Identifier, "png", "DebugSpectrogram2")); - Image debugImage2 = LitoriaRothii.DisplayDebugImage(sonogram2, acousticEvents, plots, null); + Image debugImage2 = SpectrogramTools.GetSonogramPlusCharts(sonogram2, acousticEvents, plots, null); debugImage2.Save(debugPath2.FullName); } } diff --git a/src/AnalysisPrograms/Recognizers/LitoriaRothii.cs b/src/AnalysisPrograms/Recognizers/LitoriaRothii.cs index aec60e851..447799a01 100644 --- a/src/AnalysisPrograms/Recognizers/LitoriaRothii.cs +++ b/src/AnalysisPrograms/Recognizers/LitoriaRothii.cs @@ -1,4 +1,4 @@ -// -------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // // All code in this file and all associated files are the copyright and property of the QUT Ecoacoustics Research Group (formerly MQUTeR, and formerly QUT Bioacoustics Research Group). // @@ -223,7 +223,7 @@ public override RecognizerResults Recognize(AudioRecording recording, Config con var lowPassPlot = new Plot("Low Pass", normalisedScores, normalisedThreshold); var debugPlots = new List { ampltdPlot, lowPassPlot, demeanedPlot, plot }; - Image debugImage = DisplayDebugImage(sonogram, acousticEvents, debugPlots, null); + Image debugImage = SpectrogramTools.GetSonogramPlusCharts(sonogram, acousticEvents, debugPlots, null); var debugPath = outputDirectory.Combine(FilenameHelpers.AnalysisResultName(Path.GetFileNameWithoutExtension(recording.BaseName), this.Identifier, "png", "DebugSpectrogram")); debugImage.Save(debugPath.FullName); } @@ -236,37 +236,5 @@ public override RecognizerResults Recognize(AudioRecording recording, Config con Events = acousticEvents, }; } - - public static Image DisplayDebugImage(BaseSonogram sonogram, List events, List scores, double[,] hits) - { - var image = new Image_MultiTrack(sonogram.GetImage(doHighlightSubband: false, add1KHzLines: true, doMelScale: false)); - image.AddTrack(ImageTrack.GetTimeTrack(sonogram.Duration, sonogram.FramesPerSecond)); - if (scores != null) - { - foreach (var plot in scores) - { - image.AddTrack(ImageTrack.GetNamedScoreTrack(plot.data, 0.0, 1.0, plot.threshold, plot.title)); //assumes data normalised in 0,1 - } - } - - if (hits != null) - { - image.OverlayRainbowTransparency(hits); - } - - if (events.Count > 0) - { - // set colour for the events - foreach (AcousticEvent ev in events) - { - ev.BorderColour = AcousticEvent.DefaultBorderColor; - ev.ScoreColour = AcousticEvent.DefaultScoreColor; - } - - image.AddEvents(events, sonogram.NyquistFrequency, sonogram.Configuration.FreqBinCount, sonogram.FramesPerSecond); - } - - return image.GetImage(); - } } } diff --git a/src/AnalysisPrograms/Recognizers/PteropusSpecies.cs b/src/AnalysisPrograms/Recognizers/PteropusSpecies.cs index 6d8003a47..b8471a843 100644 --- a/src/AnalysisPrograms/Recognizers/PteropusSpecies.cs +++ b/src/AnalysisPrograms/Recognizers/PteropusSpecies.cs @@ -28,6 +28,7 @@ namespace AnalysisPrograms.Recognizers using System.Linq; using System.Reflection; using System.Text; + using Acoustics.Shared; using Acoustics.Shared.ConfigFile; using Acoustics.Tools.Wav; using AnalysisBase; @@ -81,10 +82,6 @@ public override void SummariseResults( /// recogniser results. public override RecognizerResults Recognize(AudioRecording audioRecording, Config configuration, TimeSpan segmentStartOffset, Lazy getSpectralIndexes, DirectoryInfo outputDirectory, int? imageWidth) { - // get the common properties - string speciesName = configuration[AnalysisKeys.SpeciesName] ?? ""; - string abbreviatedSpeciesName = configuration[AnalysisKeys.AbbreviatedSpeciesName] ?? ""; - RecognizerResults results = Gruntwork(audioRecording, configuration, outputDirectory, segmentStartOffset); return results; @@ -100,12 +97,19 @@ public override RecognizerResults Recognize(AudioRecording audioRecording, Confi /// a list of events. internal static RecognizerResults Gruntwork(AudioRecording audioRecording, Config configuration, DirectoryInfo outputDirectory, TimeSpan segmentStartOffset) { + // get the common properties + string speciesName = configuration[AnalysisKeys.SpeciesName] ?? ""; + string abbreviatedSpeciesName = configuration[AnalysisKeys.AbbreviatedSpeciesName] ?? ""; + int minHz = configuration.GetIntOrNull(AnalysisKeys.MinHz) ?? 500; + int maxHz = configuration.GetIntOrNull(AnalysisKeys.MaxHz) ?? 8000; + double minDuration = configuration.GetIntOrNull(AnalysisKeys.MinDuration) ?? 0.1; + double maxDuration = configuration.GetIntOrNull(AnalysisKeys.MaxDuration) ?? 0.5; + // Get a value from the config file - without a string accessor, as a double - double someExampleSettingA = configuration.GetDoubleOrNull("SomeExampleSettingA") ?? 0.0; + //double someExampleSettingA = configuration.GetDoubleOrNull("SomeExampleSettingA") ?? 0.0; /* * Examples of using profiles - */ // Examples of the APIs available. You don't need all of these commands! Pick and choose. bool hasProfiles = ConfigFile.HasProfiles(configuration); @@ -121,6 +125,7 @@ internal static RecognizerResults Gruntwork(AudioRecording audioRecording, Confi // object currentProfile = profile.Profile; // Log.Info(profile.Name + ": " + ((int)currentProfile.MinHz).ToString()); // } + */ //###################### //2.Convert each segment to a spectrogram. @@ -139,7 +144,44 @@ internal static RecognizerResults Gruntwork(AudioRecording audioRecording, Confi // get frame parameters for the analysis var sonogram = (BaseSonogram)new SpectrogramStandard(sonoConfig, audioRecording.WavReader); - var sonoImage = sonogram.GetImageFullyAnnotated("Test"); + var data = sonogram.Data; + var score = MatrixTools.GetRowAverages(data); + score = DataTools.NormaliseInZeroOne(score, 0, 12); + //var eventThreshold = 0.25; // equivalent to 3dB + var eventThreshold = 0.5; // equivalent to 6dB + var plot = new Plot(speciesName, score, eventThreshold); + var plots = new List { plot }; + + //iii: CONVERT decibel SCORES TO ACOUSTIC EVENTS + var acousticEvents = AcousticEvent.ConvertScoreArray2Events( + score, + minHz, + maxHz, + sonogram.FramesPerSecond, + sonogram.FBinWidth, + eventThreshold, + minDuration, + maxDuration, + segmentStartOffset); + + // ###################################################################### + acousticEvents.ForEach(ae => + { + ae.SpeciesName = speciesName; + ae.SegmentDurationSeconds = audioRecording.Duration.TotalSeconds; + ae.SegmentStartSeconds = segmentStartOffset.TotalSeconds; + ae.Name = abbreviatedSpeciesName; + }); + + var sonoImage = SpectrogramTools.GetSonogramPlusCharts(sonogram, acousticEvents, plots, null); + //var sonoImage = sonogram.GetImageFullyAnnotated("Test"); + + //var opPath = + // outputDirectory.Combine( + // FilenameHelpers.AnalysisResultName( + // Path.GetFileNameWithoutExtension(recording.BaseName), speciesName, "png", "DebugSpectrogram")); + //sonoImage.Save(opPath.FullName); + string imageFilename = "Test.png"; sonoImage.Save(Path.Combine(outputDirectory.FullName, imageFilename)); diff --git a/src/AnalysisPrograms/Recognizers/UperoleiaInundata.cs b/src/AnalysisPrograms/Recognizers/UperoleiaInundata.cs index 235dbad01..ab0dea431 100644 --- a/src/AnalysisPrograms/Recognizers/UperoleiaInundata.cs +++ b/src/AnalysisPrograms/Recognizers/UperoleiaInundata.cs @@ -1,4 +1,4 @@ -// -------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // // All code in this file and all associated files are the copyright and property of the QUT Ecoacoustics Research Group (formerly MQUTeR, and formerly QUT Bioacoustics Research Group). // @@ -201,7 +201,7 @@ private void WriteDebugImage( bool displayDebugImage = MainEntry.InDEBUG; if (displayDebugImage) { - Image debugImage1 = LitoriaRothii.DisplayDebugImage(sonogram, acousticEvents, plots, hits); + Image debugImage1 = SpectrogramTools.GetSonogramPlusCharts(sonogram, acousticEvents, plots, hits); var debugPath1 = outputDirectory.Combine( FilenameHelpers.AnalysisResultName( @@ -231,7 +231,7 @@ private void WriteDebugImage( this.Identifier, "png", "DebugSpectrogram2")); - Image debugImage2 = LitoriaRothii.DisplayDebugImage(sonogram2, acousticEvents, plots, null); + Image debugImage2 = SpectrogramTools.GetSonogramPlusCharts(sonogram2, acousticEvents, plots, null); debugImage2.Save(debugPath2.FullName); } } diff --git a/src/AnalysisPrograms/Recognizers/UperoleiaMimula.cs b/src/AnalysisPrograms/Recognizers/UperoleiaMimula.cs index f9faa5d71..c6546e6f5 100644 --- a/src/AnalysisPrograms/Recognizers/UperoleiaMimula.cs +++ b/src/AnalysisPrograms/Recognizers/UperoleiaMimula.cs @@ -1,4 +1,4 @@ -// -------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // // All code in this file and all associated files are the copyright and property of the QUT Ecoacoustics Research Group (formerly MQUTeR, and formerly QUT Bioacoustics Research Group). // @@ -206,7 +206,7 @@ private void WriteDebugImage( bool displayDebugImage = MainEntry.InDEBUG; if (displayDebugImage) { - Image debugImage1 = LitoriaRothii.DisplayDebugImage(sonogram, acousticEvents, plots, hits); + Image debugImage1 = SpectrogramTools.GetSonogramPlusCharts(sonogram, acousticEvents, plots, hits); var debugPath1 = outputDirectory.Combine(FilenameHelpers.AnalysisResultName(Path.GetFileNameWithoutExtension(recording.BaseName), this.Identifier, "png", "DebugSpectrogram1")); debugImage1.Save(debugPath1.FullName); @@ -224,7 +224,7 @@ private void WriteDebugImage( BaseSonogram sonogram2 = new SpectrogramStandard(sonoConfig2, recording.WavReader); var debugPath2 = outputDirectory.Combine(FilenameHelpers.AnalysisResultName(Path.GetFileNameWithoutExtension(recording.BaseName), this.Identifier, "png", "DebugSpectrogram2")); - Image debugImage2 = LitoriaRothii.DisplayDebugImage(sonogram2, acousticEvents, plots, null); + Image debugImage2 = SpectrogramTools.GetSonogramPlusCharts(sonogram2, acousticEvents, plots, null); debugImage2.Save(debugPath2.FullName); } } diff --git a/src/AudioAnalysisTools/StandardSpectrograms/SpectrogramTools.cs b/src/AudioAnalysisTools/StandardSpectrograms/SpectrogramTools.cs index 9e6125fa5..6d82b7a4a 100644 --- a/src/AudioAnalysisTools/StandardSpectrograms/SpectrogramTools.cs +++ b/src/AudioAnalysisTools/StandardSpectrograms/SpectrogramTools.cs @@ -14,6 +14,7 @@ namespace AudioAnalysisTools.StandardSpectrograms using System.Drawing; using System.IO; using Acoustics.Shared; + using AudioAnalysisTools.WavTools; using ColorMine.ColorSpaces; using DSP; using LongDurationSpectrograms; @@ -178,6 +179,45 @@ public static BaseSonogram Audio2DecibelSonogram(FileInfo fiAudio, Dictionary + /// THis method draws a sonogram with other useful information attached. + /// + /// of BaseSonogram class. + /// a list of acoustic events. + /// a list of plots relevant to the spectrogram scores. + /// not often used - can be null. + public static Image GetSonogramPlusCharts(BaseSonogram sonogram, List events, List plots, double[,] hits) + { + var image = new Image_MultiTrack(sonogram.GetImage(doHighlightSubband: false, add1KHzLines: true, doMelScale: false)); + image.AddTrack(ImageTrack.GetTimeTrack(sonogram.Duration, sonogram.FramesPerSecond)); + if (plots != null) + { + foreach (var plot in plots) + { + image.AddTrack(ImageTrack.GetNamedScoreTrack(plot.data, 0.0, 1.0, plot.threshold, plot.title)); //assumes data normalised in 0,1 + } + } + + if (hits != null) + { + image.OverlayRainbowTransparency(hits); + } + + if (events != null && events.Count > 0) + { + // set colour for the events + foreach (AcousticEvent ev in events) + { + ev.BorderColour = AcousticEvent.DefaultBorderColor; + ev.ScoreColour = AcousticEvent.DefaultScoreColor; + } + + image.AddEvents(events, sonogram.NyquistFrequency, sonogram.Configuration.FreqBinCount, sonogram.FramesPerSecond); + } + + return image.GetImage(); + } + /* /// ///