page contents

c# mathnet 低通滤波

本文讲述了c# mathnet 低通滤波!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

attachments-2022-11-4O3SRkZI638417e05fc46.jpg本文讲述了c# mathnet 低通滤波!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

我正在尝试使用带有F#的低通滤波器使用MathNet.Filter,当我绘制时,结果不起作用。 我在C#中发现了一些类似的问题,但是当我在F#中重现代码时,结果是错误的。

这是我使用MathNet.Filter的方式:

let fs ,fcut, order = 5000., 2.5, 5  // set the filter parameters
let lowPass2 = MathNet.Filtering.OnlineFilter.CreateLowpass(MathNet.Filtering.ImpulseResponse.Finite,fs,fcut,order)
let disp_beam_f = disp_beam |> lowPass2.ProcessSamples // apply the filter

// I print max/min to do a quick check
(disp_beam_f |> Array.min, disp_beam |> Array.min )

然后,当我绘制一些数据时,我的结果是: 当我只绘制过滤后的数据时,绘图看起来像原始数据,但具有不同的比例: 我已经尝试更改过滤器的顺序,而不是使用过滤器的顺序,结果更好,但它不是过滤后的数据。

  • 我做错了什么? 我知道fs是频率采样(以Hz为单位), fcut切割高频的频率(以Hz为单位), 顺序表示fcut以上频率的信号衰减多少(或快)。

有关更多信息,请参阅以下脚本: https : //gist.github.com/josesoyo/f45b59a035c3e2ec2cdf0fe1f95cc84b
数据样本位于: https : //drive.google.com/open?id = 1rA4B21i-S5g2wrB4eK7xk3_A6Rs0tLHf
结果应该是这个文件: https : //drive.google.com/open?id = 1ukmWtzFm_I4ou3zuQcLWCrFIOJs2eV41

编辑基于Gene Belitski的答案我相信澄清案例:

运行下一个脚本会更好地显示我遇到的问题:

#I __SOURCE_DIRECTORY__
#r @"..\packages\MathNet.Numerics.3.8.0\lib\net40\MathNet.Numerics.dll"
#r @"..\packages\MathNet.Filtering.0.4.0\lib\net40\MathNet.Filtering.dll"
#load @"..\packages\FSharp.Charting.0.91.1\lib\net45\FSharp.Charting.fsx"

let length, samplingRate,  amplitude = 750, 44100.,20.
let flow, fhigh = 200., 15000.
let lo = Generate.Sinusoidal(length,samplingRate,flow,amplitude)
let hi = Generate.Sinusoidal(length,samplingRate,fhigh,amplitude/4.)
let sumLoHi = lo |> Array.map2 (+) hi
let fs ,fcut, order = float(samplingRate), 5000., 10 

// first low pass filter
let lowPass2 = MathNet.Filtering.OnlineFilter.CreateLowpass(MathNet.Filtering.ImpulseResponse.Finite,fs,fcut,order)
let filtered = sumLoHi |> lowPass2.ProcessSamples

// second low pass filter
let lowPass3 = MathNet.Filtering.OnlineFilter.CreateLowpass(MathNet.Filtering.ImpulseResponse.Finite,fs,fcut/5.,order)
let filtered_2 = sumLoHi |> lowPass3.ProcessSamples

// plot
Chart.Combine([Chart.Line(lo, Name="lo", Color=Color.DarkBlue);
               Chart.Line(sumLoHi, Name="sumLoHi", Color=Color.LightSkyBlue);
               Chart.Line(filtered, Name="filtered ratio fcut/SamplingRatio = 0.1", Color=Color.Purple);
               Chart.Line(filtered_2, Name="filtered ratio fcut/SamplingRatio = 0.02", Color=Color.Fuchsia)])
|> Chart.WithLegend(Title="Combined",Docking=ChartTypes.Docking.Bottom)
|> Chart.WithTitle("OnlineFilter")

结果是:

我已经指定了samplingRate和过滤频率之间的比率,因为我认为问题问题与此参数有关。 是不是我不应该以这种方式使用OnlineFilter,还是其他的东西?

我也试过使用IIR和FIR滤波器,结果是一样的。 相反,python / scipy的类似情况效果很好。


I am trying to use a low-pass filter with F# using MathNet.Filter and when I plot the results is not working. I have found some similar questions in C#, but when I reproduce the code in F# The result is wrong.

Here it is the way I am using MathNet.Filter:

let fs ,fcut, order = 5000., 2.5, 5  // set the filter parameters
let lowPass2 = MathNet.Filtering.OnlineFilter.CreateLowpass(MathNet.Filtering.ImpulseResponse.Finite,fs,fcut,order)
let disp_beam_f = disp_beam |> lowPass2.ProcessSamples // apply the filter

// I print max/min to do a quick check
(disp_beam_f |> Array.min, disp_beam |> Array.min )

Then, when I plot some data my result is: When I plot just the filtered data, the plot looks like the original data, but with a different scale: I have already tried changing the order of the filter, and not using the order of the filter, the result is better, but it is not the filtered data.

  • What I am doing wrong? I understand that fs is the frequency sampling (in Hz), fcut the frequency at which high frequencies are cut (in Hz) and order represents how much (or fast) the signal for frequencies above fcut are attenuated.

For more information, here there is a script: https://gist.github.com/josesoyo/f45b59a035c3e2ec2cdf0fe1f95cc84b
and a sample of data is in : https://drive.google.com/open?id=1rA4B21i-S5g2wrB4eK7xk3_A6Rs0tLHf
The result should be this file: https://drive.google.com/open?id=1ukmWtzFm_I4ou3zuQcLWCrFIOJs2eV41

Edit Based on Gene Belitski answer which I believes clarifies the case:

Running the next script shows better what is the problem I have:

#I __SOURCE_DIRECTORY__
#r @"..\packages\MathNet.Numerics.3.8.0\lib\net40\MathNet.Numerics.dll"
#r @"..\packages\MathNet.Filtering.0.4.0\lib\net40\MathNet.Filtering.dll"
#load @"..\packages\FSharp.Charting.0.91.1\lib\net45\FSharp.Charting.fsx"

let length, samplingRate,  amplitude = 750, 44100.,20.
let flow, fhigh = 200., 15000.
let lo = Generate.Sinusoidal(length,samplingRate,flow,amplitude)
let hi = Generate.Sinusoidal(length,samplingRate,fhigh,amplitude/4.)
let sumLoHi = lo |> Array.map2 (+) hi
let fs ,fcut, order = float(samplingRate), 5000., 10 

// first low pass filter
let lowPass2 = MathNet.Filtering.OnlineFilter.CreateLowpass(MathNet.Filtering.ImpulseResponse.Finite,fs,fcut,order)
let filtered = sumLoHi |> lowPass2.ProcessSamples

// second low pass filter
let lowPass3 = MathNet.Filtering.OnlineFilter.CreateLowpass(MathNet.Filtering.ImpulseResponse.Finite,fs,fcut/5.,order)
let filtered_2 = sumLoHi |> lowPass3.ProcessSamples

// plot
Chart.Combine([Chart.Line(lo, Name="lo", Color=Color.DarkBlue);
               Chart.Line(sumLoHi, Name="sumLoHi", Color=Color.LightSkyBlue);
               Chart.Line(filtered, Name="filtered ratio fcut/SamplingRatio = 0.1", Color=Color.Purple);
               Chart.Line(filtered_2, Name="filtered ratio fcut/SamplingRatio = 0.02", Color=Color.Fuchsia)])
|> Chart.WithLegend(Title="Combined",Docking=ChartTypes.Docking.Bottom)
|> Chart.WithTitle("OnlineFilter")

And the result is:

I have specified the ratio between the samplingRate and the filtering frequency because I believe that the problem problem is related with this parameter. Is it that I shouldn't use OnlineFilter in this way or is it something else?

I have also tried to use IIR and FIR filters and the result is the same. Instead, a similar situation with python/scipy works well.

最满意答案

在不了解您的样本数据的情况下,很难确定观察到的行为是对还是错。 它可能有助于整合一个快速的样本,如果过滤器工作与否,这将是显而易见的; 然后检查你的代码。

例如,我们可以采用较低频率的波数据,向其添加另一个较高频率的波,然后将滤波器应用于滤除较高频率的和,并期望滤波后的数据类似于较低频率。

以下脚本实现了上述场景:

#I __SOURCE_DIRECTORY__
#r @"..\packages\MathNet.Numerics.3.8.0\lib\net40\MathNet.Numerics.dll"
#r @"..\packages\MathNet.Filtering.0.4.0\lib\net40\MathNet.Filtering.dll"
#load @"..\packages\FSharp.Charting.0.91.1\lib\net45\FSharp.Charting.fsx"

open FSharp.Charting
open MathNet.Numerics
open MathNet.Filtering
open System.Drawing

let length, samplingRate,  amplitude = 250, 44100.,20.
let lo = Generate.Sinusoidal(length,samplingRate,1000.,amplitude)
let hi = Generate.Sinusoidal(length,samplingRate,15000.,amplitude/3.)
let sumLoHi = lo |> Array.map2 (+) hi
let fs ,fcut, order = 44100., 5000., 10
let lowPass2 = MathNet.Filtering.OnlineFilter.CreateLowpass(MathNet.Filtering.ImpulseResponse.Finite,fs,fcut,order)
let filtered = sumLoHi |> lowPass2.ProcessSamples
Chart.Combine([Chart.Line(lo, Name="lo", Color=Color.DarkBlue);
               Chart.Line(sumLoHi, Name="sumLoHi", Color=Color.LightSkyBlue);
               Chart.Line(filtered, Name="filtered", Color=Color.Purple)])
|> Chart.WithLegend(Title="Combined",Docking=ChartTypes.Docking.Bottom)

具有相同采样率和数据长度的两个sine以及对于lo 1kHz和对于hi为15kHz的频率被组合成sumLoHi 。 然后将滤波器应用于后者截止5kHz以上的频率,得到filtered数据。 得到的lo , sumLoHi和filtered组合图表显示过滤器正常工作:



Without knowing anything about your sample data it is hard to determine if the observed behavior is right or wrong. It might help putting together a quick sample where it would be obvious if the filter works or not; then review your code.

For example, we may take a wave data of a lower frequency, add to it another wave of higher frequency, then apply the filter to the sum filtering out higher frequency and expect that the filtered data will resemble the lower wave.

The below script implements the above scenario:

#I __SOURCE_DIRECTORY__
#r @"..\packages\MathNet.Numerics.3.8.0\lib\net40\MathNet.Numerics.dll"
#r @"..\packages\MathNet.Filtering.0.4.0\lib\net40\MathNet.Filtering.dll"
#load @"..\packages\FSharp.Charting.0.91.1\lib\net45\FSharp.Charting.fsx"

open FSharp.Charting
open MathNet.Numerics
open MathNet.Filtering
open System.Drawing

let length, samplingRate,  amplitude = 250, 44100.,20.
let lo = Generate.Sinusoidal(length,samplingRate,1000.,amplitude)
let hi = Generate.Sinusoidal(length,samplingRate,15000.,amplitude/3.)
let sumLoHi = lo |> Array.map2 (+) hi
let fs ,fcut, order = 44100., 5000., 10
let lowPass2 = MathNet.Filtering.OnlineFilter.CreateLowpass(MathNet.Filtering.ImpulseResponse.Finite,fs,fcut,order)
let filtered = sumLoHi |> lowPass2.ProcessSamples
Chart.Combine([Chart.Line(lo, Name="lo", Color=Color.DarkBlue);
               Chart.Line(sumLoHi, Name="sumLoHi", Color=Color.LightSkyBlue);
               Chart.Line(filtered, Name="filtered", Color=Color.Purple)])
|> Chart.WithLegend(Title="Combined",Docking=ChartTypes.Docking.Bottom)

Two sine waves of the same sampling rate and data lengths and frequencies 1kHz for lo and 15kHz for hi are combined into sumLoHi. Then the filter is applied to the latter cutting off frequencies above 5kHz getting filtered data. The resulting combined chart of lo, sumLoHi and filtered shows that the filter is working just fine:

更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg

  • 发表于 2022-11-28 10:07
  • 阅读 ( 1164 )
  • 分类:C/C++开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
王昭君
王昭君

209 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1470 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章