From 29af15136350b26d6a3782aeba9cfa6487f00217 Mon Sep 17 00:00:00 2001 From: Mahnoosh Kholghi Date: Thu, 18 Oct 2018 14:20:18 +1000 Subject: [PATCH] fixed bugs in new peak tracking method --- .../SpectralPeakTracking2018.cs | 67 ++++++++++++------- .../SpectralPeakTracking2018Tests.cs | 45 ++++++++++--- 2 files changed, 78 insertions(+), 34 deletions(-) diff --git a/src/AudioAnalysisTools/SpectralPeakTracking2018.cs b/src/AudioAnalysisTools/SpectralPeakTracking2018.cs index b47d5ba48..3b4204328 100644 --- a/src/AudioAnalysisTools/SpectralPeakTracking2018.cs +++ b/src/AudioAnalysisTools/SpectralPeakTracking2018.cs @@ -8,6 +8,7 @@ namespace AudioAnalysisTools using System.Collections.Generic; using System.Drawing; using System.IO; + using System.Linq; using Accord.Statistics.Kernels; using Acoustics.Shared.Csv; using StandardSpectrograms; @@ -24,7 +25,7 @@ public class Output public int[][] BandIndex { get; set; } - public object[][] peakTrackInfoList { get; set; } + public List peakTrackInfoList { get; set; } //public List SpecTracks { get; set; } } @@ -52,6 +53,7 @@ public static Output SpectralPeakTracking(double[,] spectrogram, SpectralPeakTra // make an array of the index of local peaks. Zero means there is no local peak identified. int[] SpectralPeakArray = MakeSpectralPeakArray(spectrogram, localPeaksAndBands.Item1); + // find a track of peaks in a pre-defined set of boundaries var peakTrackInfo = SpectralPeakTracking(spectrogram, SpectralPeakArray, timePerFrame, hertzPerFreqBin); /* @@ -168,18 +170,19 @@ public static Tuple FindLocalSpectralPeaks(double[,] matrix, i return Tuple.Create(targetPeakBinsIndex.ToArray(), bandIndex.ToArray()); } - public static object[][] SpectralPeakTracking(double[,] spectrogram, int[] SpectralPeakArray, double timePerFrame, double hertzPerFreqBin) + public static List SpectralPeakTracking(double[,] spectrogram, int[] SpectralPeakArray, double timePerFrame, double hertzPerFreqBin) { int startX; int endX; int startY; int endY; - int peakCount = 0; - var score = 0; + List peakTrackInfoList = new List(); for (int i = 0; i < SpectralPeakArray.Length; i++) { + int peakCount = 0; + var score = 0; if (SpectralPeakArray[i] != 0) { object[] peakTrackInfo = new object[6]; @@ -188,36 +191,52 @@ public static object[][] SpectralPeakTracking(double[,] spectrogram, int[] Spect endX = startX + 17; endY = startY + 4; //double[,] targetMatrix = GetArbitraryMatrix(spectrogram, startY, endY, startX, endX); - for (int j = startX; j < endX; j++) + + if (endX < spectrogram.GetLength(0) && endY < spectrogram.GetLength(1)) { - if (SpectralPeakArray[j] >= startY && SpectralPeakArray[j] <= endY) + for (int j = startX; j < endX; j++) { - peakCount++; + if (SpectralPeakArray[j] >= startY && SpectralPeakArray[j] <= endY) + { + peakCount++; + } } - } - score = peakCount / 18; + score = peakCount; //peakCount / 18; - peakTrackInfo[0] = i; // frame number - peakTrackInfo[1] = i * timePerFrame; - peakTrackInfo[2] = SpectralPeakArray[i]; // bin number - peakTrackInfo[3] = SpectralPeakArray[i] * hertzPerFreqBin; - peakTrackInfo[4] = score; + if (score >= 5) //4 / 18 + { + peakTrackInfo[0] = i; // frame number + peakTrackInfo[1] = i * timePerFrame; + peakTrackInfo[2] = SpectralPeakArray[i]; // bin number + peakTrackInfo[3] = SpectralPeakArray[i] * hertzPerFreqBin; + peakTrackInfo[4] = score; + peakTrackInfo[5] = "Yes"; + peakTrackInfoList.Add(peakTrackInfo); + } - if (score >= 4 / 18) - { - peakTrackInfo[5] = "Yes"; - } - else - { - peakTrackInfo[5] = "No"; - } + /* + peakTrackInfo[0] = i; // frame number + peakTrackInfo[1] = i * timePerFrame; + peakTrackInfo[2] = SpectralPeakArray[i]; // bin number + peakTrackInfo[3] = SpectralPeakArray[i] * hertzPerFreqBin; + peakTrackInfo[4] = score; - peakTrackInfoList.Add(peakTrackInfo); + if (score >= 4) //4 / 18 + { + peakTrackInfo[5] = "Yes"; + } + else + { + peakTrackInfo[5] = "No"; + } + peakTrackInfoList.Add(peakTrackInfo); + */ + } } } - return peakTrackInfoList.ToArray(); + return peakTrackInfoList; } diff --git a/tests/Acoustics.Test/AudioAnalysisTools/SpectralPeakTracking2018Tests.cs b/tests/Acoustics.Test/AudioAnalysisTools/SpectralPeakTracking2018Tests.cs index 019acfd31..6d98b4c83 100644 --- a/tests/Acoustics.Test/AudioAnalysisTools/SpectralPeakTracking2018Tests.cs +++ b/tests/Acoustics.Test/AudioAnalysisTools/SpectralPeakTracking2018Tests.cs @@ -5,8 +5,11 @@ namespace Acoustics.Test.AudioAnalysisTools { using System; + using System.Collections.Generic; using System.Drawing.Imaging; using System.IO; + using System.Linq; + using System.Text; using Acoustics.Shared; using Acoustics.Shared.ConfigFile; using Acoustics.Shared.Csv; @@ -56,7 +59,7 @@ public void FindLocalSpectralPeaksTest() int widthMidBand = 4; int topBufferSize = 2; int bottomBufferSize = 2; - double threshold = 4.0; + double threshold = 1.0; var actualLocalPeaks = SpectralPeakTracking2018.FindLocalSpectralPeaks(matrix, peakBinsIndex, widthMidBand, topBufferSize, bottomBufferSize, threshold).Item1; @@ -73,10 +76,10 @@ public void FindLocalSpectralPeaksTest() public void LocalSpectralPeakTest() { var configPath = @"C:\Users\kholghim\Mahnoosh\Night_parrot\SpectralPeakTrackingConfig.yml"; - var recordingPath = @"Y:\RichardSeaton\NP Monitoring\Kalamurina May18\Night Parrot calls Kala 2018\SM7 24 Sep 2018 5.30 am.wav";// "Y:\RichardSeaton\NP Monitoring\Kalamurina May18\Night Parrot calls Kala 2018\SM27 22 Sep 2018 3.30 am.wav"; //"Y:\RichardSeaton\NP Monitoring\Kalamurina May18\Night Parrot calls Kala 2018\SM16 24 Sep 2018 6.30 am.wav"; //"Y:\RichardSeaton\NP Monitoring\Kalamurina May18\Night Parrot calls Kala 2018\SM16 23 Sep 2018 6.30 am.wav"; //"Y:\RichardSeaton\NP Monitoring\Kalamurina May18\Night Parrot calls Kala 2018\SM7 24 Sep 2018 6.30 am.wav"; //"Y:\RichardSeaton\NP Monitoring\Kalamurina May18\Night Parrot calls Kala 2018\SM7 24 Sep 2018 5.30 am.wav";// "Y:\RichardSeaton\NP Monitoring\Kalamurina May18\Night Parrot calls Kala 2018\SM4 24 Sep 2018 6.30 am.wav"; //"C:\Users\kholghim\Mahnoosh\Night_parrot\Night Parrot call-WA-hollow whistle-didit.wav";//"Y:\RichardSeaton\NP Monitoring\Kalamurina May18\Night Parrot calls Kala 2018\SM3 24 Sep 2018 6.30 am.wav"; //"C:\Users\kholghim\Mahnoosh\Night_parrot\JY-(cleaned)-3-Night_Parrot-pair.Western_Qld_downsampled.wav"; //"C:\Users\kholghim\Mahnoosh\Night_parrot\SM16 24 Sep 2018 6.30 am.wav"; //"C:\Users\kholghim\Mahnoosh\Night_parrot\S4A07296_20180419_050023_11-12min.wav"; //"M:\Postdoc\Night_parrot\S4A07296_20180419_050023_Ch1.wav"; // - var imagePath = @"C:\Users\kholghim\Mahnoosh\Night_parrot\image_whistle_peaks_SM7 24 Sep 2018 5.30 am_1500_3500_100_250_3.bmp"; //image_NP_SM16 24 Sep 2018 6.30 am.bmp"; + var recordingPath = @"Y:\RichardSeaton\NP Monitoring\Kalamurina May18\Night Parrot calls Kala 2018\SM27 22 Sep 2018 3.30 am.wav"; + var imagePath = @"C:\Users\kholghim\Mahnoosh\Night_parrot\image_whistle_peaks_SM27 22 Sep 2018 3.30 am_1500_3500_100_250_6.bmp"; //var trackImagePath = @"C:\Users\kholghim\Mahnoosh\Night_parrot\trackImage.bmp"; - var pathToCsvFile = @"C:\Users\kholghim\Mahnoosh\Night_parrot\PeakTrackInfo.csv"; + var pathToCsvFile = @"C:\Users\kholghim\Mahnoosh\Night_parrot\PeakTrackInfo_SM27 22 Sep 2018 3.30 am.csv"; var configFile = configPath.ToFileInfo(); @@ -110,26 +113,48 @@ public void LocalSpectralPeakTest() NoiseReductionType = NoiseReductionType.None, }; - var frameStep = frameSize - (frameSize / frameOverlap); - var secondsPerFrame = frameSize / (nyquist * 2); - var timePerFrame = frameStep * secondsPerFrame; + var frameStep = frameSize * (1 - frameOverlap); + var secondsPerFrame = frameStep / (nyquist * 2); //var sonogram = new SpectrogramStandard(sonoConfig, recording.WavReader); var amplitudeSpectrogram = new AmplitudeSonogram(sonoConfig, recording.WavReader); var energySpectrogram = new EnergySpectrogram(amplitudeSpectrogram); var decibelSpectrogram = new SpectrogramStandard(sonoConfig, recording.WavReader); - // Noise Reduction to be added + // Noise Reduction //var noiseReducedSpectrogram = SNR.NoiseReduce_Standard(energySpectrogram.Data); - var output = SpectralPeakTracking2018.SpectralPeakTracking(energySpectrogram.Data, configuration.SptSettings, hertzPerFreqBin, timePerFrame); + var output = SpectralPeakTracking2018.SpectralPeakTracking(energySpectrogram.Data, configuration.SptSettings, hertzPerFreqBin, secondsPerFrame); // draw the local peaks double[,] hits = SpectralPeakTracking2018.MakeHitMatrix(energySpectrogram.Data, output.TargetPeakBinsIndex, output.BandIndex); var image = SpectralPeakTracking2018.DrawSonogram(decibelSpectrogram, hits); image.Save(imagePath, ImageFormat.Bmp); - Csv.WriteToCsv(pathToCsvFile.ToFileInfo(), output.peakTrackInfoList); + string[] header = new[] { "Frame No", "Start Time", "Bin No", "Freq", "Score", "Detection" }; + var csv = new StringBuilder(); + string content = string.Empty; + foreach (var entry in header.ToArray()) + { + content += entry.ToString() + ","; + } + + csv.AppendLine(content); + + foreach (var entry in output.peakTrackInfoList) + { + content = string.Empty; + foreach (var value in entry) + { + content += value.ToString() + ","; + } + + csv.AppendLine(content); + } + + File.WriteAllText(pathToCsvFile, csv.ToString()); + + //Csv.WriteMatrixToCsv(pathToCsvFile.ToFileInfo(), output.peakTrackInfoList); // draw spectral tracks //var trackImage = SpectralPeakTracking2018.DrawTracks(decibelSpectrogram, hits, output.SpecTracks);