Exemple #1
0
        public static Tuple <BaseSonogram, double[, ], double[], List <AcousticEvent>, double[], TimeSpan> Execute_ODDetect(FileInfo wavPath,
                                                                                                                            bool doSegmentation, int minHz, int maxHz, double frameOverlap, double dctDuration, double dctThreshold, int minOscilFreq, int maxOscilFreq,
                                                                                                                            double eventThreshold, double minDuration, double maxDuration)
        {
            //i: GET RECORDING
            AudioRecording recording = new AudioRecording(wavPath.FullName);

            //if (recording.SampleRate != 22050) recording.ConvertSampleRate22kHz(); // THIS METHOD CALL IS OBSOLETE
            int sr = recording.SampleRate;

            //ii: MAKE SONOGRAM
            Log.WriteLine("Start sonogram.");
            SonogramConfig sonoConfig = new SonogramConfig(); //default values config

            sonoConfig.WindowOverlap = frameOverlap;
            sonoConfig.SourceFName   = recording.BaseName;
            BaseSonogram sonogram = new SpectrogramStandard(sonoConfig, recording.WavReader);

            Log.WriteLine("Signal: Duration={0}, Sample Rate={1}", sonogram.Duration, sr);
            Log.WriteLine("Frames: Size={0}, Count={1}, Duration={2:f1}ms, Overlap={5:f0}%, Offset={3:f1}ms, Frames/s={4:f1}",
                          sonogram.Configuration.WindowSize, sonogram.FrameCount, sonogram.FrameDuration * 1000,
                          sonogram.FrameStep * 1000, sonogram.FramesPerSecond, frameOverlap);
            int binCount = (int)(maxHz / sonogram.FBinWidth) - (int)(minHz / sonogram.FBinWidth) + 1;

            Log.WriteIfVerbose("Freq band: {0} Hz - {1} Hz. (Freq bin count = {2})", minHz, maxHz, binCount);

            Log.WriteIfVerbose("DctDuration=" + dctDuration + "sec.  (# frames=" + (int)Math.Round(dctDuration * sonogram.FramesPerSecond) + ")");
            Log.WriteIfVerbose("Score threshold for oscil events=" + eventThreshold);
            Log.WriteLine("Start OD event detection");

            //iii: DETECT OSCILLATIONS
            bool normaliseDCT = true;
            List <AcousticEvent> predictedEvents; //predefinition of results event list

            double[] scores;                      //predefinition of score array
            double[,] hits;                       //predefinition of hits matrix - to superimpose on sonogram image
            double[] segments;                    //predefinition of segmentation of recording
            TimeSpan analysisTime;                //predefinition of Time duration taken to do analysis on this file

            Oscillations2010.Execute((SpectrogramStandard)sonogram, doSegmentation, minHz, maxHz, dctDuration, dctThreshold, normaliseDCT,
                                     minOscilFreq, maxOscilFreq, eventThreshold, minDuration, maxDuration,
                                     out scores, out predictedEvents, out hits, out segments, out analysisTime);

            return(Tuple.Create(sonogram, hits, scores, predictedEvents, segments, analysisTime));
        }//end CaneToadRecogniser
Exemple #2
0
        public static void Execute(Arguments arguments)
        {
            MainEntry.WarnIfDeveloperEntryUsed();

            string title = "# EVENT PATTERN RECOGNITION.";
            string date  = "# DATE AND TIME: " + DateTime.Now;

            Log.WriteLine(title);
            Log.WriteLine(date);

            Log.Verbosity = 1;

            string targetName = arguments.Target; // prefix of name of created files

            var input = arguments.Source;

            string        recordingFileName  = input.Name;
            string        recordingDirectory = input.DirectoryName;
            DirectoryInfo outputDir          = arguments.Config.ToFileInfo().Directory;
            FileInfo      targetPath         = outputDir.CombineFile(targetName + "_target.txt");
            FileInfo      targetNoNoisePath  = outputDir.CombineFile(targetName + "_targetNoNoise.txt");
            FileInfo      noisePath          = outputDir.CombineFile(targetName + "_noise.txt");
            FileInfo      targetImagePath    = outputDir.CombineFile(targetName + "_target.png");
            FileInfo      paramsPath         = outputDir.CombineFile(targetName + "_params.txt");

            Log.WriteIfVerbose("# Output folder =" + outputDir);

            //i: GET RECORDING
            AudioRecording recording = new AudioRecording(input.FullName);

            //if (recording.SampleRate != 22050) recording.ConvertSampleRate22kHz(); THIS METHOD CALL IS OBSOLETE
            int sr = recording.SampleRate;

            //ii: READ PARAMETER VALUES FROM INI FILE
            var config = new ConfigDictionary(arguments.Config);
            Dictionary <string, string> dict = config.GetTable();

            // framing parameters
            //double frameOverlap      = FeltTemplates_Use.FeltFrameOverlap;   // default = 0.5
            double frameOverlap = double.Parse(dict["FRAME_OVERLAP"]);

            //frequency band
            int minHz = int.Parse(dict["MIN_HZ"]);
            int maxHz = int.Parse(dict["MAX_HZ"]);

            // oscillation OD parameters
            double dctDuration  = double.Parse(dict[OscillationRecogniser.key_DCT_DURATION]);  // 2.0; // seconds
            double dctThreshold = double.Parse(dict[OscillationRecogniser.key_DCT_THRESHOLD]); // 0.5;
            int    minOscilFreq = int.Parse(dict[OscillationRecogniser.key_MIN_OSCIL_FREQ]);   // 4;
            int    maxOscilFreq = int.Parse(dict[OscillationRecogniser.key_MAX_OSCIL_FREQ]);   // 5;
            bool   normaliseDCT = false;

            // iii initialize the sonogram config class.
            SonogramConfig sonoConfig = new SonogramConfig(); //default values config

            sonoConfig.SourceFName = recording.BaseName;

            //sonoConfig.WindowSize = windowSize;
            sonoConfig.WindowOverlap = frameOverlap;

            // iv: generate the sonogram
            BaseSonogram sonogram = new SpectrogramStandard(sonoConfig, recording.WavReader);

            Log.WriteLine("Frames: Size={0}, Count={1}, Duration={2:f1}ms, Overlap={5:f2}%, Offset={3:f1}ms, Frames/s={4:f1}",
                          sonogram.Configuration.WindowSize, sonogram.FrameCount, sonogram.FrameDuration * 1000,
                          sonogram.FrameStep * 1000, sonogram.FramesPerSecond, frameOverlap);
            int binCount = (int)(maxHz / sonogram.FBinWidth) - (int)(minHz / sonogram.FBinWidth) + 1;

            Log.WriteIfVerbose("Freq band: {0} Hz - {1} Hz. (Freq bin count = {2})", minHz, maxHz, binCount);

            // v: extract the subband energy array
            Log.WriteLine("# Start extracting target event.");
            double[] dBArray = SNR.DecibelsInSubband(sonogram.Data, minHz, maxHz, sonogram.FBinWidth);
            for (int i = 0; i < sonogram.FrameCount; i++)
            {
                dBArray[i] /= binCount; // get average dB energy
            }

            double Q  = 0.0;
            double SD = 0.0;

            throw new NotImplementedException("Mike changed the API here, I don't know how to fix it.");
            dBArray = new[] { 0.0 };             // SNR.NoiseSubtractMode(dBArray, out Q, out SD);
            double maxDB       = 6.0;
            double dBThreshold = 2 * SD / maxDB; //set dB threshold to 2xSD above background noise

            dBArray = SNR.NormaliseDecibelArray_ZeroOne(dBArray, maxDB);
            dBArray = DataTools.filterMovingAverage(dBArray, 7);

            //Log.WriteLine("Q ={0}", Q);
            //Log.WriteLine("SD={0}", SD);
            //Log.WriteLine("Th={0}", dBThreshold); //normalised threshhold

            // #############################################################################################################################################
            // vi: look for oscillation at required OR for ground parrots.
            double[] odScores = Oscillations2010.DetectOscillationsInScoreArray(dBArray, dctDuration, sonogram.FramesPerSecond, dctThreshold,
                                                                                normaliseDCT, minOscilFreq, maxOscilFreq);

            //odScores = SNR.NoiseSubtractMode(odScores, out Q, out SD);
            double maxOD = 1.0;

            odScores = SNR.NormaliseDecibelArray_ZeroOne(odScores, maxOD);
            odScores = DataTools.filterMovingAverage(odScores, 5);

            //odScores = DataTools.NormaliseMatrixValues(odScores); //NormaliseMatrixValues 0 - 1
            //double odThreshold = (10 * SD) / maxOD;   //set od threshold to 2xSD above background noise
            //double odThreshold = dctThreshold;
            double odThreshold = 0.4;

            Log.WriteLine("Max={0}", odScores.Max());

            //Log.WriteLine("Q  ={0}", Q);
            //Log.WriteLine("SD ={0}", SD);
            Log.WriteLine("Th ={0}", dctThreshold); //normalised threshhold

            // #############################################################################################################################################
            // vii: LOOK FOR GROUND PARROTS USING TEMPLATE
            var template = GroundParrotRecogniser.ReadGroundParrotTemplateAsList(sonogram);

            double[] gpScores = DetectEPR(template, sonogram, odScores, odThreshold);
            gpScores = DataTools.normalise(gpScores); //NormaliseMatrixValues 0 - 1

            // #############################################################################################################################################

            // iv: SAVE extracted event as matrix of dB intensity values
            //FileTools.WriteMatrix2File(template, targetPath);                  // write template values to file PRIOR to noise removal.
            //FileTools.WriteMatrix2File(templateMinusNoise, targetNoNoisePath); // write template values to file AFTER to noise removal.
            //FileTools.WriteArray2File(noiseSubband, noisePath);

            // v: SAVE image of extracted event in the original sonogram
            string sonogramImagePath = outputDir + Path.GetFileNameWithoutExtension(recordingFileName) + ".png";

            //DrawSonogram(sonogram, sonogramImagePath, dBArray, dBThreshold / maxDB, odScores, dctThreshold, gpScores, template);
        }
Exemple #3
0
        /// <summary>
        /// Wraps up the resources into a template.ZIP file
        /// and then runs a test on the source recording.
        /// </summary>
        public static void Execute(Arguments arguments)
        {
            if (arguments == null)
            {
                arguments = Dev();
            }

            string title = "# EDIT TEMPLATE.";
            string date  = "# DATE AND TIME: " + DateTime.Now;

            Log.WriteLine(title);
            Log.WriteLine(date);

            //ZIP THE OUTPUT FILES
            const bool ZipOutput = true;

            FileInfo iniPath = arguments.Config;

            string[] nameComponents = (Path.GetFileNameWithoutExtension(iniPath.Name)).Split('_');
            string   targetName     = nameComponents[0] + "_" + nameComponents[1];

            //i: Set up the file names
            DirectoryInfo outputDir       = iniPath.Directory;
            FileInfo      targetImagePath = outputDir.CombineFile(targetName + "_target.png"); // input image file
            FileInfo      binaryOpPath    = outputDir.CombineFile(targetName + "_binary.bmp");
            FileInfo      trinaryOpPath   = outputDir.CombineFile(targetName + "_trinary.bmp");
            FileInfo      sprOpPath       = outputDir.CombineFile(targetName + "_spr.txt");    // syntactic pattern recognition file
            //additional files to be zipped up with template
            FileInfo targetPath        = outputDir.CombineFile(targetName + "_target.txt");
            FileInfo targetNoNoisePath = outputDir.CombineFile(targetName + "_targetNoNoise.txt");
            FileInfo noisePath         = outputDir.CombineFile(targetName + "_noise.txt");

            //ii: READ PARAMETER VALUES FROM INI FILE
            var config = new ConfigDictionary(iniPath);
            Dictionary <string, string> dict = config.GetTable();
            string sourceFile           = dict[FeltTemplate_Create.key_SOURCE_RECORDING];
            string sourceDir            = dict[FeltTemplate_Create.key_SOURCE_DIRECTORY];
            double dB_Threshold         = double.Parse(dict[FeltTemplate_Create.key_DECIBEL_THRESHOLD]);
            double maxTemplateIntensity = double.Parse(dict[FeltTemplate_Create.key_TEMPLATE_MAX_INTENSITY]);
            int    neighbourhood        = int.Parse(dict[FeltTemplate_Create.key_DONT_CARE_NH]);   //the do not care neighbourhood
            int    lineLength           = int.Parse(dict[FeltTemplate_Create.key_LINE_LENGTH]);
            double templateThreshold    = dB_Threshold / maxTemplateIntensity;
            int    bitmapThreshold      = (int)(255 - (templateThreshold * 255));

            Log.WriteLine("#################################### WRITE THE BINARY TEMPLATE ##################################");
            Bitmap bitmap    = ImageTools.ReadImage2Bitmap(targetImagePath.FullName);
            var    binaryBmp = Image2BinaryBitmap(bitmap, bitmapThreshold);

            binaryBmp.Save(binaryOpPath.FullName);

            Log.WriteLine("#################################### WRITE THE TRINARY TEMPLATE ##################################");
            var trinaryBmp = Image2TrinaryBitmap(binaryBmp, neighbourhood);

            trinaryBmp.Save(trinaryOpPath.FullName);

            Log.WriteLine("#################################### WRITE THE SPR TEMPLATE ##################################");
            double[,] matrix = ImageTools.GreyScaleImage2Matrix(bitmap);
            matrix           = DataTools.MatrixRotate90Clockwise(matrix); //rows=time  cols=freq.
            //ImageTools.DrawMatrix(matrix, @"C:\SensorNetworks\Output\FELT_LewinsRail1\SPR_output1.bmp");
            //int smallLengthThreshold = 10;
            //var tuple = SPT.doSPT(matrix, templateThreshold, smallLengthThreshold);
            //matrix = tuple.Item1;
            //ImageTools.DrawMatrix(matrix, @"C:\SensorNetworks\Output\FELT_LewinsRail1\SPR_output2.bmp");
            char[,] spr = SprTools.Target2SymbolicTracks(matrix, templateThreshold, lineLength);
            FileTools.WriteMatrix2File(spr, sprOpPath.FullName);
            var    tuple1   = FindMatchingEvents.Execute_One_Spr_Match(spr, matrix, templateThreshold);
            double sprScore = tuple1.Item1;
            double dBScore  = sprScore * maxTemplateIntensity;

            Log.WriteLine("#################################### WRITE THE OSCILATION TEMPLATE ##################################");
            double[,] target = FileTools.ReadDoubles2Matrix(targetPath.FullName);
            // oscillations in time
            double[,] rotatedtarget = DataTools.MatrixRotate90Clockwise(target);
            var colSums = DataTools.GetColumnsAverages(rotatedtarget);

            double[] periods = Oscillations2010.PeriodicityAnalysis(colSums); // frame periodicity
            LoggedConsole.WriteLine("Periodicity (sec) = {0:f3},  {1:f3},  {2:f3}",
                                    periods[0] * FeltTemplates_Use.FeltFrameOffset, periods[1] * FeltTemplates_Use.FeltFrameOffset, periods[2] * FeltTemplates_Use.FeltFrameOffset);
            //double oscilFreq = indexOfMaxValue / dctDuration * 0.5; //Times 0.5 because index = Pi and not 2Pi

            // oscillations in freq i.e. harmonics
            colSums = DataTools.GetColumnsAverages(target);
            periods = Oscillations2010.PeriodicityAnalysis(colSums);
            LoggedConsole.WriteLine("Periodicity (Hz) = {0:f0},  {1:f0},  {2:f0}.",
                                    periods[0] * FeltTemplates_Use.FeltFreqBinWidth, periods[1] * FeltTemplates_Use.FeltFreqBinWidth, periods[2] * FeltTemplates_Use.FeltFreqBinWidth);
            //double oscilFreq = indexOfMaxValue / dctDuration * 0.5; //Times 0.5 because index = Pi and not 2Pi

            //FileTools.WriteMatrix2File(spr, sprOpPath);

            // ZIP THE OUTPUT
            Log.WriteLine("#################################### ZIP THE TEMPLATES ##################################");
            if (ZipOutput == true)
            {
                var filenames = new[]
                { iniPath, targetImagePath, binaryOpPath, targetPath, targetNoNoisePath, noisePath };
                string biOutZipFile = outputDir + targetName + "_binaryTemplate.zip";
                //FileTools.ZipFiles(filenames, biOutZipFile);

                filenames = new[]
                { iniPath, targetImagePath, trinaryOpPath, targetPath, targetNoNoisePath, noisePath };

                string triOutZipFile = outputDir + targetName + "_trinaryTemplate.zip";
                //FileTools.ZipFiles(filenames, triOutZipFile);

                filenames = new[]
                { iniPath, targetImagePath, sprOpPath, targetPath, targetNoNoisePath, noisePath };

                string sprOutZipFile = outputDir + targetName + "_syntacticTemplate.zip";
                //FileTools.ZipFiles(filenames, sprOutZipFile);

                // Zipping files can be done by using standard .NET 4.6 System.IO.Compression
                // however, this code hasn't been used in years and I've opted to just comment out the lines above
                throw new NotImplementedException("Zipping template files intentionally broken");
            }

            Log.WriteLine("\n\n#################################### TEST THE EXTRACTED EVENT ON SOURCE FILE ##################################");
            //vi: TEST THE EVENT ON ANOTHER FILE
            //felt  "C:\SensorNetworks\WavFiles\Canetoad\DM420010_128m_00s__130m_00s - Toads.mp3" C:\SensorNetworks\Output\FELT_CaneToad\FELT_CaneToad_Params.txt events.txt
            //string testRecording = @"C:\SensorNetworks\WavFiles\Gecko\Suburban_March2010\geckos_suburban_104.mp3";
            //string testRecording = @"C:\SensorNetworks\WavFiles\Gecko\Suburban_March2010\geckos_suburban_18.mp3";
            //string testRecording = @"C:\SensorNetworks\WavFiles\Currawongs\Currawong_JasonTagged\West_Knoll_Bees_20091102-170000.mp3";
            //string testRecording = @"C:\SensorNetworks\WavFiles\Curlew\Curlew2\Top_Knoll_-_St_Bees_20090517-210000.wav";

            string listOpDir        = "C:\\SensorNetworks\\Output\\FELT_templateList\\";
            string templateListPath = listOpDir + "templateTestList.txt";
            var    list             = new List <string>();

            list.Add("#" + outputDir + targetName + "_binaryTemplate.zip");
            list.Add("#" + outputDir + targetName + "_trinaryTemplate.zip");
            list.Add("#" + outputDir + targetName + "_syntacticTemplate.zip");
            FileTools.Append2TextFile(templateListPath, list);      //write the template.ZIP file

            //TEST THE TEMPLATE ON SOURCE FILE
            //string[] arguments = new string[3];

            /*
             * var args = new FeltTemplates_Use.Arguments()
             *         {
             *             Source = "",
             * arguments[0] = sourceDir + "\\" + sourceFile;
             * arguments[1] = templateListPath;
             * arguments[2] = listOpDir;
             *
             *         }*/
            //FeltTemplates_Use.Dev(arguments);

            Log.WriteLine("# Finished everything!");
        }
        FrogRibbitRecognizer(AudioRecording recording, string filterName, int midBandFreq, double windowDuration = 5.0, double windowOverlap = 0.5,
                             double dctDuration = 0.5, double dctThreshold = 0.4, bool normaliseDCT = false, int minOscilRate = 11, int maxOscilRate = 17, double maxOscilScore = 20.0)
        {
            int    sr              = recording.SampleRate;
            int    windowSize      = (int)(windowDuration * sr / 1000.0);
            double frameStep       = windowDuration * (1 - windowOverlap);
            double framesPerSecond = 1000 / frameStep;

            //i: Apply filter
            Log.WriteLine("#   Filter: " + filterName);
            var filteredRecording = AudioRecording.Filter_IIR(recording, filterName); //return new filtered audio recording.
            int signalLength      = filteredRecording.WavReader.Samples.Length;

            //ii: FRAMING
            int[,] frameIDs = DSP_Frames.FrameStartEnds(signalLength, windowSize, windowOverlap);
            int frameCount = frameIDs.GetLength(0);

            //iii: EXTRACT ENVELOPE and ZERO-CROSSINGS
            Log.WriteLine("#   Extract Envelope and Zero-crossings.");
            var results2 = DSP_Frames.ExtractEnvelopeAndZeroCrossings(filteredRecording.WavReader.Samples, sr, windowSize, windowOverlap);

            //double[] average       = results2.Item1;
            double[] envelope      = results2.Item2;
            double[] zeroCrossings = results2.Item3;
            //double[] sampleZCs     = results2.Item4;
            double[] sampleStd = results2.Item5;

            Log.WriteLine("#   Normalize values.");
            //iv: FRAME ENERGIES
            double StandardDeviationCount = 0.1; // number of noise SDs to calculate noise threshold - determines severity of noise reduction
            var    results3 = SNR.SubtractBackgroundNoiseFromWaveform_dB(SNR.Signal2Decibels(envelope), StandardDeviationCount);
            var    dBarray  = SNR.TruncateNegativeValues2Zero(results3.NoiseReducedSignal);

            //v: CONVERSIONS: ZERO CROSSINGS to herz - then NORMALIZE to Fuzzy freq
            int[] freq      = DSP_Frames.ConvertZeroCrossings2Hz(zeroCrossings, windowSize, sr);
            int   sideBand  = (int)(midBandFreq * 0.1);
            var   fuzzyFreq = FuzzyFrequency(freq, midBandFreq, sideBand);

            //vi: CONVERSIONS: convert sample std deviations to milliseconds - then NORMALIZE to PROBs
            double[] tsd = DSP_Frames.ConvertSamples2Milliseconds(sampleStd, sr); //time standard deviation
            //for (int i = 0; i < tsd.Length; i++) if (tsd[i]) LoggedConsole.WriteLine(i + " = " + tsd[i]);
            //filter the freq array to remove values derived from frames with high standard deviation
            double[] tsdScores = NormalDist.Values2Probabilities(tsd);

            //vii: GET OSCILLATION SCORE AND NORMALIZE
            double[] rawOscillations = Oscillations2010.DetectOscillationsInScoreArray(dBarray, dctDuration, framesPerSecond, dctThreshold, normaliseDCT, minOscilRate, maxOscilRate);
            //NormaliseMatrixValues oscillation scores wrt scores obtained on a training.
            //double maxOscillationScore = rawOscillations[DataTools.GetMaxIndex(rawOscillations)];
            //LoggedConsole.WriteLine("maxOscillationScore=" + maxOscillationScore);
            var oscillations = new double[dBarray.Length];

            for (int i = 0; i < dBarray.Length; i++)
            {
                oscillations[i] = rawOscillations[i] / maxOscilScore;
                if (oscillations[i] > 1.0)
                {
                    oscillations[i] = 1.0;
                }
            }

            //viii: COMBINE the SCORES
            Log.WriteLine("#   Combine Scores.");
            var combinedScores = new double[dBarray.Length];

            for (int i = 0; i < dBarray.Length; i++)
            {
                combinedScores[i] = fuzzyFreq[i] * tsdScores[i] * oscillations[i];
            }

            //ix: fill in the oscillation scores
            combinedScores = Oscillations2010.FillScoreArray(combinedScores, dctDuration, framesPerSecond);
            return(Tuple.Create(combinedScores, filteredRecording, dBarray, tsd));
        }