在OpenCL中的低通滤波器

3
我正在尝试在OpenCL中实现一个低通滤波器,但其中的理论让我有些困惑。在解释情况后,我已经在底部附上了我的代码。
首先,让我尝试用要点来解释整个情况:
- 对于输入,我们有一个余弦信号,具有样本大小、频率(通过将样本大小乘以频率获得频率样本)和步长。 - 在每个步长处的值存储在一个数组中,并将频率和步长乘以该函数。 - 然后将此数组传递到内核中,内核将执行低通滤波器函数。 - 内核返回一个包含新滤波值的输出数组。
余弦函数始终返回(-1,1)之间的值,唯一修改该值的是频率。因此,根据频率不同,它可能会更快或更慢地重复,但始终在(-1,1)之间。
这就是我困惑的地方,我不确定如何将低通滤波器应用于这些值。假设过滤器的截止频率为100Hz。我不能只说:
if(array[i] > 100 ) { //delete or ignore this value. Else store in a 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]与value进行比较。我不知道numItems或workItems是什么。
如果有人能提供一些见解,那就太好了。我已经搜索了很多其他低通滤波器的示例,但我就是无法理解其实现方式。我希望我已经清楚地表达了这个问题。再次强调,我知道低通滤波器如何工作。我只是不知道需要比较哪些值才能进行过滤。
还发现了这个问题: C语言中的低通滤波器

“with the frequency and step size multiplied to the function”这句话是什么意思? - Paul Ogilvie
cos(2*CL_M_PI * signalFreq * h); 我只是将信号频率乘以余弦函数。每次我增加数组时,h值会按步长递增。由于步长为1 /(采样频率),因此h基本上是h = h + 1 /(采样频率)。我希望这是使用给定频率修改余弦波的正确方法。哦,而采样频率只是samplesize * signalFrequency。 - VedhaR
1个回答

2
我有一个可能的解决方案。我正在尝试使用移动平均FIR(据说是可以实现的最简单的低通滤波器形式)。

所需内容:

  • FIFO缓冲区
  • 系数值(我为特定截止频率生成和获取了我的matlab)
  • 程序的输入和输出数组

我还没有实现这个代码,但我理解如何在理论上使用它。我创建了下面的图表,试图解释这个过程。

enter image description here

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

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

这样就可以了,我现在要在代码中实现它,但如果这个理论有任何问题,请随时纠正它。


我将接受自己的答案,因为目前这就是全部。 - VedhaR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接