예제 #1
0
        /// <summary>
        /// Evaluate harmonic and percussive mag-phase spectrograms from given signal.
        /// Both spectrogram objects share the same phase array.
        /// </summary>
        /// <param name="signal"></param>
        /// <returns></returns>
        public (MagnitudePhaseList, MagnitudePhaseList) EvaluateSpectrograms(DiscreteSignal signal)
        {
            // spectrogram memory will be reused for harmonic magnitudes

            var harmonicSpectrogram = _stft.MagnitudePhaseSpectrogram(signal);
            var harmonicMagnitudes  = harmonicSpectrogram.Magnitudes;

            // median filtering along frequency axis:

            var percussiveMagnitudes = new List <float[]>(harmonicMagnitudes.Count);

            for (var i = 0; i < harmonicMagnitudes.Count; i++)
            {
                var mag = new DiscreteSignal(1, harmonicMagnitudes[i]);
                percussiveMagnitudes.Add(_medianPercussive.ApplyTo(mag).Samples);
                _medianPercussive.Reset();
            }

            // median filtering along time axis:

            for (var j = 0; j <= _stft.Size / 2; j++)
            {
                int i = 0, k = 0;

                for (; k < _medianHarmonic.Size / 2; k++)    // feed first Size/2 samples
                {
                    _medianHarmonic.Process(harmonicMagnitudes[k][j]);
                }

                for (; i < harmonicMagnitudes.Count - _medianHarmonic.Size / 2; i++, k++)
                {
                    var h = _medianHarmonic.Process(harmonicMagnitudes[k][j]);

                    harmonicMagnitudes[i][j]   *= _mask(h, percussiveMagnitudes[k][j]);
                    percussiveMagnitudes[i][j] *= _mask(percussiveMagnitudes[k][j], h);
                }

                for (k = 0; k < _medianHarmonic.Size / 2; i++, k++)     // don't forget last samples
                {
                    var h = _medianHarmonic.Process(0);

                    harmonicMagnitudes[i][j]   *= _mask(h, percussiveMagnitudes[i][j]);
                    percussiveMagnitudes[i][j] *= _mask(percussiveMagnitudes[i][j], h);
                }

                _medianHarmonic.Reset();
            }

            var percussiveSpectrogram = new MagnitudePhaseList
            {
                Magnitudes = percussiveMagnitudes,
                Phases     = harmonicSpectrogram.Phases
            };

            return(harmonicSpectrogram, percussiveSpectrogram);
        }
예제 #2
0
        public void TestMedianFilteringDefault()
        {
            var filter = new MedianFilter();    // 9-point median filter

            var input    = new[] { 1, 6, 5, 2, 8, 1, 9, 5, 4, 2, 3, 4, 6, 7, 4f };
            var expected = new[] { 1, 1, 2, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 3, 3f };

            var filtered = filter.ApplyTo(new DiscreteSignal(1, input));

            Assert.That(filtered.Samples, Is.EqualTo(expected).Within(1e-10));
        }
예제 #3
0
        public void TestMedianFiltering()
        {
            var filter = new MedianFilter(5);

            var input    = new[] { 2, 6, 5, 4, 0, 3, 5, 7, 9, 2, 0, 1f };
            var expected = new[] { 2, 4, 4, 4, 4, 4, 5, 5, 5, 2, 1, 0f };

            var filtered = filter.ApplyTo(new DiscreteSignal(1, input));

            Assert.That(filtered.Samples, Is.EqualTo(expected).Within(1e-10));
        }
예제 #4
0
        public void TestMedianFilteringDefault()
        {
            var filter1 = new MedianFilter();    // 9-point median filter (faster implementation for sizes > 10)
            var filter2 = new MedianFilter2();   // 9-point median filter

            var input    = new[] { 1, 6, 5, 2, 8, 1, 9, 5, 4, 2, 3, 4, 6, 7, 4f };
            var expected = new[] { 1, 1, 2, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 3, 3f };

            var filtered1 = filter1.ApplyTo(new DiscreteSignal(1, input));
            var filtered2 = filter2.ApplyTo(new DiscreteSignal(1, input));

            Assert.Multiple(() =>
            {
                Assert.That(filtered1.Samples, Is.EqualTo(expected).Within(1e-10));
                Assert.That(filtered2.Samples, Is.EqualTo(expected).Within(1e-10));
            });
        }
예제 #5
0
        static private int[] PPGremoveOutofRange(float[] signalData, List <int> Idx)
        {
            List <int> inlier = new List <int>();

            NWaves.Filters.MedianFilter mFilter = new MedianFilter();
            DiscreteSignal medianSig            = mFilter.ApplyTo(new DiscreteSignal(1, signalData));

            int i = 0;

            for (i = 0; i < Idx.Count(); i++)
            {
                if (signalData[Idx[i]] < (medianSig[Idx[i]] + SampleStandardDeviation(signalData, signalData[Idx[i]])))
                {
                    inlier.Add(Idx[i]);
                }
            }

            return(inlier.ToArray());
        }
예제 #6
0
        static private List <int> PPGfiltering(int[] ppgData)
        {
            float lowcut  = (float)ppg_min_bpm / 60.0f / ppg_frame_rate / 2.0f;
            float highcut = (float)ppg_max_bpm / 60.0f / ppg_frame_rate / 2.0f;

            var LPfilter = new NWaves.Filters.OnePole.LowPassFilter(highcut);
            var HPfilter = new NWaves.Filters.OnePole.HighPassFilter(lowcut);

            var filteredPPG = LPfilter.ApplyTo(new DiscreteSignal(1, ppgData));

            filteredPPG = HPfilter.ApplyTo(filteredPPG);

            /******************** Median Filtering ********************/
            NWaves.Filters.MedianFilter mFilter = new MedianFilter(167);
            DiscreteSignal mfilteredPPG         = mFilter.ApplyTo(filteredPPG);

            float[] arrayPPG = SigToArr(mfilteredPPG);

            var peakIdx = PPGfindPeaks(arrayPPG);

            var inlier = PPGremoveOutofRange(arrayPPG, peakIdx);

            List <float> bpm = new List <float>();

            for (int i = 0; i < inlier.Count() - 1; i++)
            {
                float curBPM = ((float)ppg_frame_rate / ((float)inlier[i + 1] - (float)inlier[i])) * 60.0f;

                if (curBPM > ppg_max_bpm)
                {
                    bpm.Add(0);
                }
                else if (curBPM < ppg_min_bpm)
                {
                    bpm.Add(0);
                }
                else
                {
                    bpm.Add(curBPM);
                }
            }

            List <float> output = new List <float>();

            /*output.Add(90);
             * for (int i = 1; i < bpm.Count() - 1; i++)
             * {
             *  if (bpm[i] == 0)
             *      output.Add(output[output.Count() - 1]);
             *  else if (30 < (bpm[i] - bpm[i - 1]))
             *      output.Add(output[output.Count() - 1]);
             *  else
             *      output.Add(bpm[i]);
             * }*/
            for (int i = 0; i < bpm.Count() - 1; i++)
            {
                if (bpm[i] != 0)
                {
                    output.Add(bpm[i]);
                }
            }
            if (output.Count() == 0)
            {
                output.Add(90);
            }

            //var outputG = GaussianFiltering(7, output.ToArray());

            List <int> toList = new List <int>();

            for (int i = 0; i < output.Count(); i++)
            {
                toList.Add((int)output[i]);
            }

            return(toList);
        }
예제 #7
0
        static public List <GsrPpgPacket> GSRfiltering(List <GsrPpgPacket> GSRdata)
        {
            var gsrData_int = GSRdata.Select(e => gsr_max - e.Value).ToArray();
            var gsrData     = Array.ConvertAll(gsrData_int, item => (float)item);

            /******************** Gaussian Filtering ********************/
            var filtered = GaussianFiltering(gsr_gaussian_kernel, gsrData);

            /******************** Median Filtering ********************/
            MedianFilter   mFilter   = new MedianFilter(gsr_subtract_sample);
            DiscreteSignal tonic_GSR = mFilter.ApplyTo(filtered);

            var phasic_GSR = filtered.Subtract(tonic_GSR);

            /******************* 앞/뒤 데이터 자르는 과정인듯 ********************/
            if (phasic_GSR.Length > gsr_subtract_sample * 2)
            {
                for (int i = 0; i < gsr_subtract_sample; i++)
                {
                    phasic_GSR[i] = 0;
                }
                for (int i = phasic_GSR.Length - 1; i > phasic_GSR.Length - gsr_subtract_sample; i--)
                {
                    phasic_GSR[i] = 0;
                }
            }
            else
            {
                for (int i = 0; i < phasic_GSR.Length; i++)
                {
                    phasic_GSR[i] = 0;
                }
            }

            /******************** Find peak ********************/
            bool  checkFlag = false;
            float max       = 0;

            int idx1 = 0;

            var findPeak = GSRdata.Select(e => new GsrPpgPacket(0, e.Timestamp)).ToList();

            findPeak[0].Value = 0;

            for (int i = 1; i < filtered.Length; i++)
            {
                if (checkFlag)
                {
                    if (phasic_GSR[i] > 0 && phasic_GSR[i - 1] <= 0)
                    {
                        for (int j = idx1; j < i; j++)
                        {
                            findPeak[j].Value = (int)max;
                        }
                        checkFlag = false;
                    }
                    if (phasic_GSR[i] > max)
                    {
                        max = phasic_GSR[i];
                    }
                }
                else
                {
                    if (phasic_GSR[i] > 0 && phasic_GSR[i - 1] > 0)
                    {
                        idx1      = i;
                        max       = 0;
                        checkFlag = true;
                    }
                }
            }

            /******************** Gaussian Filtering ********************/

            //var filteredData = GaussianFiltering(gsr_gaussian_kernel * 10, findPeak.ToArray());
            return(findPeak);
        }
예제 #8
0
 public void MedianFilter()
 {
     var output = _filter.ApplyTo(_signal);
 }
예제 #9
0
        public void Run()
        {
            var output2  = new float[_signal.Length];
            var output4  = new float[_signal.Length];
            var output5  = new float[_signal.Length];
            var outputZi = new float[_signal.Length];

            var samples = _signal.Samples;

            for (var i = 0; i < samples.Length; i++)
            {
                output4[i]  = _filterV4BiQuad.Process(samples[i]);
                output5[i]  = _filterV5BiQuad.Process(samples[i]);
                outputZi[i] = _filterZiBiQuad.Process(samples[i]);
            }

            var diffAverageV4 = output5.Zip(output4, (o5, o4) => Math.Abs(o5 - o4)).Average();
            var diffAverageZi = output5.Zip(outputZi, (o5, zi) => Math.Abs(o5 - zi)).Average();

            Console.WriteLine($"Average difference Ver.0.9.5 vs. Ver.0.9.4 : {diffAverageV4}");
            Console.WriteLine($"Average difference IirFilter vs. ZiFilter : {diffAverageZi}");

            for (var i = 0; i < samples.Length; i++)
            {
                output4[i]  = _filterV4Butterworth6.Process(samples[i]);
                output5[i]  = _filterV5Butterworth6.Process(samples[i]);
                outputZi[i] = _filterZiButterworth6.Process(samples[i]);
            }

            diffAverageV4 = output5.Zip(output4, (o5, o4) => Math.Abs(o5 - o4)).Average();
            diffAverageZi = output5.Zip(outputZi, (o5, zi) => Math.Abs(o5 - zi)).Average();

            Console.WriteLine($"Average difference Ver.0.9.5 vs. Ver.0.9.4 : {diffAverageV4}");
            Console.WriteLine($"Average difference IirFilter vs. ZiFilter : {diffAverageZi}");


            // === MISC ====

            var med  = new MedianFilter();
            var med2 = new MedianFilter2();

            var medOut  = med.ApplyTo(_signal).Samples;
            var medOut2 = med2.ApplyTo(_signal).Samples;

            var diffAverageMed = medOut.Zip(medOut, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference MedianFilter vs. MedianFilter2 : {diffAverageMed}");


            var ma    = new MovingAverageFilter();
            var maRec = new MovingAverageRecursiveFilter();

            var maOut    = ma.ApplyTo(_signal).Samples;
            var maRecOut = maRec.ApplyTo(_signal).Samples;

            var diffAverageMa = maOut.Zip(maRecOut, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference MovingAverageFilter vs. MovingAverageRecursiveFilter : {diffAverageMa}");


            // 32bit vs. 64bit

            var fir32 = new FirFilter(DesignFilter.FirWinLp(7, 0.1));
            var fir64 = new FirFilter64(DesignFilter.FirWinLp(7, 0.1));

            var fir32Out = fir32.ApplyTo(_signal).Samples;
            var fir64Out = fir64.ApplyTo(_signal.Samples.ToDoubles());

            var diffAverageFir = fir64Out.Zip(fir32Out, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference FirFilter vs. FirFilter64 : {diffAverageFir}");


            var iir32 = new IirFilter(_filterV5Butterworth6.Tf);
            var iir64 = new IirFilter64(_filterV5Butterworth6.Tf);

            var iir32Out = iir32.ApplyTo(_signal).Samples;
            var iir64Out = iir64.ApplyTo(_signal.Samples.ToDoubles());

            var diffAverageIir = iir64Out.Zip(iir32Out, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference IirFilter vs. IirFilter64 : {diffAverageIir}");


            var zi32 = new ZiFilter(_filterV5Butterworth6.Tf);
            var zi64 = new ZiFilter64(_filterV5Butterworth6.Tf);

            var zi32Out = zi32.ApplyTo(_signal).Samples;
            var zi64Out = zi64.ApplyTo(_signal.Samples.ToDoubles());

            var diffAverageZis = zi64Out.Zip(zi32Out, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference ZiFilter vs. ZiFilter64 : {diffAverageZis}");

            zi32Out = zi32.ZeroPhase(_signal).Samples;
            zi64Out = zi64.ZeroPhase(_signal.Samples.ToDoubles());

            var diffAverageZiZeroPhase = zi64Out.Zip(zi32Out, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference ZiFilter vs. ZiFilter64 (zero-phase): {diffAverageZiZeroPhase}");
        }