OpenCL 中的低通滤波器

Low Pass Filter in OpenCL

我正在尝试在 OpenCL 中实现低通滤波器,这一切背后的理论让我有些困惑。在解释完场景后,我在底部附上了我的代码。

首先,让我尝试以点的形式解释整个场景。

cos函数总是从(-1,1)返回一个值,唯一修改这个值的是频率。因此它可能会根据频率重复得更快或更慢,但它总是在 (-1,1) 之间。

这是我感到困惑的地方,我不确定如何对这些值应用低通滤波器。假设滤波器的截止频率为 100Hz。我不能只说:

if(array[i] > 100 ) { //delete or ignore this value. Else store in a array }

这行不通的原因是 array[i] 的值范围是 (-1,1)。那么我将如何应用这个过滤器呢?我要比较哪些值?

从物理角度来看,我可以看到它是如何工作的,一个电容器和一个电阻器计算截止频率并通过电路发送输入。但是以编程方式,我看不出如何实现它。我在网上看到过很多这种实现,但是代码没有足够的文档来很好地理解正在发生的事情。

这是我主机端的代码:

//Array to hold the information of signal
float *Array;

//Number of sampling points 
int sampleSize = 100;
float h = 0;

//Signal Frequency in Hz
float signalFreq = 10;

//Number of points between 0 and max val (T_Sample)
float freqSample = sampleSize*signalFreq;

//Step = max value or T_Sample
float stepSize = 1.0 / freqSample;

//Allocate enough memory for the array
Array = (float*)malloc(sampleSize*sizeof(float));

//Populate the array with modified cosine
for (int i = 0; i < sampleSize; i++) {
    Array[0] = cos(2*CL_M_PI*signalFreq*h);
    h = h + stepSize;
    printf("Value of current sample for cos is: %f \n", Array[0]);
}

我的内核只有如下:(显然这不是过滤器的代码,这是我困惑的地方)。

__kernel void lowpass(__global int *Array, __local float *cutOffValue, __global int *Output) { 
    int idx = get_global_id(0); 
    Output[idx] = Array[idx];
};

我发现这个 PDF 实现了很多过滤器。在文档末尾,您可以找到低通滤波器的浮点实现。

http://scholar.uwindsor.ca/cgi/viewcontent.cgi?article=6242&context=etd

在该 pdf 的过滤器实现中,将数据 [j] 与值进行比较。我也不知道 numItems 或 workItems 是什么。

如果有人可以对此提供一些见解,那就太好了。我已经搜索了很多关于低通滤波器的其他示例,但我无法全神贯注于实现。我希望我把这个问题说清楚了。同样,我知道 how/what 低通滤波器可以。我只是不知道我需要比较哪些值才能进行过滤。

也发现了这个问题:

Low Pass filter in C

我有一个可能的解决方案。我正在尝试的是移动平均冷杉(有人告诉我这是可以实现的最简单的低通滤波器形式)。

要求:

  • 先进先出缓冲器
  • 系数值(我针对特定的截止频率从 matlab 生成并获得了我的值)
  • 程序的输入和输出数组

我没有明智地实现这段代码,但我确实了解如何在理论层面上使用它。我在下面创建了一个图表来尝试解释这个过程。

本质上,来自另一个输入数组的值将一次一个地传递到 FIFO 缓冲区。每次传入一个值时,内核都会在具有 'n' 个抽头的 FIFO 缓冲区中进行乘法运算。每个抽头都有一个与之关联的系数值。因此,特定元素的输入与系数值相乘,然后将所有值累加并存储在输出缓冲区的一个元素中。

请注意,系数是在 Matlab 中生成的。我不知道如何获取这些值。起初我打算只使用 1/n 的系数,但我很确定这只会扭曲信号的值。

这应该可以解决问题,我现在将在代码中实现它,但如果这个理论有任何错误,请随时纠正。