예제 #1
0
        /// <summary>
        /// Use this method when want to match defined shape in target using cross-correlation.
        /// This was the method used by Stewart Gage.
        /// First set target and source to same dynamic range.
        /// Then NormaliseMatrixValues target and source to unit-length.
        /// </summary>
        public static Tuple <double[]> Execute_StewartGage(double[,] target, double dynamicRange, SpectrogramStandard sonogram,
                                                           List <AcousticEvent> segments, int minHz, int maxHz, double minDuration)
        {
            Log.WriteLine("SEARCHING FOR EVENTS LIKE TARGET.");
            if (segments == null)
            {
                return(null);
            }

            int minBin       = (int)(minHz / sonogram.FBinWidth);
            int maxBin       = (int)(maxHz / sonogram.FBinWidth);
            int targetLength = target.GetLength(0);

            //adjust target's dynamic range to that set by user
            target = SNR.SetDynamicRange(target, 0.0, dynamicRange); //set event's dynamic range
            double[] v1 = DataTools.Matrix2Array(target);
            v1 = DataTools.normalise2UnitLength(v1);

            //var image = BaseSonogram.Data2ImageData(target);
            //ImageTools.DrawMatrix(image, 1, 1, @"C:\SensorNetworks\Output\FELT_Currawong\target.png");

            double[] scores = new double[sonogram.FrameCount];
            foreach (AcousticEvent av in segments)
            {
                Log.WriteLine("SEARCHING SEGMENT.");
                int startRow = (int)Math.Round(av.TimeStart * sonogram.FramesPerSecond);
                int endRow   = (int)Math.Round(av.TimeEnd * sonogram.FramesPerSecond);
                if (endRow >= sonogram.FrameCount)
                {
                    endRow = sonogram.FrameCount;
                }

                int stopRow = endRow - targetLength;
                if (stopRow <= startRow)
                {
                    stopRow = startRow + 1;  //want minimum of one row
                }

                int offset = targetLength / 2;

                for (int r = startRow; r < stopRow; r++)
                {
                    double[,] matrix = DataTools.Submatrix(sonogram.Data, r, minBin, r + targetLength - 1, maxBin);
                    matrix           = SNR.SetDynamicRange(matrix, 0.0, dynamicRange); //set event's dynamic range

                    //var image = BaseSonogram.Data2ImageData(matrix);
                    //ImageTools.DrawMatrix(image, 1, 1, @"C:\SensorNetworks\Output\FELT_CURLEW\compare.png");

                    double[] v2 = DataTools.Matrix2Array(matrix);
                    v2        = DataTools.normalise2UnitLength(v2);
                    scores[r] = DataTools.DotProduct(v1, v2);  //the Cross Correlation
                } // end of rows in segment
            } // foreach (AcousticEvent av in segments)

            var tuple = Tuple.Create(scores);

            return(tuple);
        }
        public static double[] AnalyseWaveformAtLocation(double[] signal, double amplitudeThreshold, double scoreThreshold)
        {
            double[] waveTemplate =
            {
                -0.000600653, -0.000451427, -0.000193289, -1.91083E-05,  0.000133366,  0.000256465,  0.000387591,  0.000533758,  0.000645976,  0.000670944,
                0.000622045,   0.000569337,  0.000553455,  0.000535552,  0.000448935,  0.000286928,  0.000120322,  2.26704E-05, -1.67728E-05, -9.42369E-05,
                -0.000289969, -0.000565902,  -0.00079103, -0.000883849, -0.000898074, -0.000932191, -0.000985956,  -0.00097387,     -0.00093,     -0.00088,
                -0.00088,         -0.00087, -0.000883903, -0.000831651, -0.000759236, -0.000668421,  -0.00052348, -0.000361632,  -0.00028245, -0.000292255,
                -0.00025,     -8.71854E-05,      0.00011,      0.00014,   0.00010031,      0.00013,      0.00016,  0.000240405,  0.000332283,  0.000357989,
                0.000312231,   0.000222307,  0.000138079,  9.49253E-05,  6.74344E-05, -7.81347E-07, -0.000103014,  -0.00014973,
            };
            int templateLength = waveTemplate.Length;

            double[] normalTemplate = DataTools.normalise2UnitLength(waveTemplate);

            double[] scores = new double[signal.Length];

            for (int i = 2; i < signal.Length - templateLength; i++)
            {
                // look for a local minimum
                if (signal[i] > signal[i - 1] || signal[i] > signal[i - 2] || signal[i] > signal[i + 1] || signal[i] > signal[i + 2])
                {
                    continue;
                }

                double[] subsampleWav = DataTools.Subarray(signal, i, templateLength);
                double   min, max;
                DataTools.MinMax(subsampleWav, out min, out max);
                if (max - min < amplitudeThreshold)
                {
                    continue;
                }

                double[] normalwav = DataTools.normalise2UnitLength(subsampleWav);

                // calculate cosine angle as similarity score
                double score = DataTools.DotProduct(normalTemplate, normalwav);
                if (score > scoreThreshold)
                {
                    for (int j = 0; j < templateLength; j++)
                    {
                        if (score > scores[i + j])
                        {
                            scores[i + j] = score;
                        }
                    }
                }
            }

            //scores = DataTools.NormaliseMatrixValues(scores);
            //scores = DataTools.filterMovingAverageOdd(scores, 3);
            return(scores);
        }
예제 #3
0
        /// <summary>
        /// This done using Cosine similarity. Could also use Euclidian distance.
        /// </summary>
        /// <param name=""></param>
        /// <param name=""></param>
        public static void CalculateSimilarityScores(Arguments arguments, Output output)
        {
            int speciesCount  = arguments.SpeciesCount;
            int instanceCount = arguments.InstanceCount;

            output.SimilarityScores = new double[instanceCount, speciesCount];

            // loop through all instances
            for (int r = 0; r < instanceCount; r++)
            {
                double[] instance = MatrixTools.GetRow(output.InstanceFeatureMatrix, r);

                for (int s = 0; s < speciesCount; s++)
                {
                    double[] species    = MatrixTools.GetRow(output.SpeciesFeatureMatrix, s);
                    double   similarity = DataTools.DotProduct(instance, species);
                    output.SimilarityScores[r, s] = similarity;
                }
            } // end for loop r over all instances
        }
예제 #4
0
        public static Tuple <double[]> Execute_MFCC_XCOR(double[,] target, double dynamicRange, SpectrogramStandard sonogram,
                                                         List <AcousticEvent> segments, int minHz, int maxHz, double minDuration)
        {
            Log.WriteLine("SEARCHING FOR EVENTS LIKE TARGET.");
            if (segments == null)
            {
                return(null);
            }

            int minBin       = (int)(minHz / sonogram.FBinWidth);
            int maxBin       = (int)(maxHz / sonogram.FBinWidth);
            int targetLength = target.GetLength(0);

            //set up the matrix of cosine coefficients
            int coeffCount = 12;                                             //only use first 12 coefficients.
            int binCount   = target.GetLength(1);                            //number of filters in filter bank

            double[,] cosines = MFCCStuff.Cosines(binCount, coeffCount + 1); //set up the cosine coefficients

            //adjust target's dynamic range to that set by user
            target = SNR.SetDynamicRange(target, 3.0, dynamicRange); //set event's dynamic range
            target = MFCCStuff.Cepstra(target, coeffCount, cosines);
            double[] v1 = DataTools.Matrix2Array(target);
            v1 = DataTools.normalise2UnitLength(v1);

            string imagePath2 = @"C:\SensorNetworks\Output\FELT_Currawong\target.png";
            var    result1    = BaseSonogram.Data2ImageData(target);
            var    image      = result1.Item1;

            ImageTools.DrawMatrix(image, 1, 1, imagePath2);

            double[] scores = new double[sonogram.FrameCount];
            foreach (AcousticEvent av in segments)
            {
                Log.WriteLine("SEARCHING SEGMENT.");
                int startRow = (int)Math.Round(av.TimeStart * sonogram.FramesPerSecond);
                int endRow   = (int)Math.Round(av.TimeEnd * sonogram.FramesPerSecond);
                if (endRow >= sonogram.FrameCount)
                {
                    endRow = sonogram.FrameCount - 1;
                }

                endRow -= targetLength;
                if (endRow <= startRow)
                {
                    endRow = startRow + 1;  //want minimum of one row
                }

                for (int r = startRow; r < endRow; r++)
                {
                    double[,] matrix = DataTools.Submatrix(sonogram.Data, r, minBin, r + targetLength - 1, maxBin);
                    matrix           = SNR.SetDynamicRange(matrix, 3.0, dynamicRange); //set event's dynamic range

                    //string imagePath2 = @"C:\SensorNetworks\Output\FELT_Gecko\compare.png";
                    //var image = BaseSonogram.Data2ImageData(matrix);
                    //ImageTools.DrawMatrix(image, 1, 1, imagePath2);
                    matrix = MFCCStuff.Cepstra(matrix, coeffCount, cosines);

                    double[] v2 = DataTools.Matrix2Array(matrix);
                    v2 = DataTools.normalise2UnitLength(v2);
                    double crossCor = DataTools.DotProduct(v1, v2);
                    scores[r] = crossCor;
                } //end of rows in segment
            }     //foreach (AcousticEvent av in segments)

            var tuple = Tuple.Create(scores);

            return(tuple);
        }