我正在尝试在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是什么。
如果有人可以提供一些有用的见解,那就太棒了。我已经在低通滤波器上搜索了很多其他的例子,但我无法绕过实现。我希望我明白这个问题。我再次知道低通滤波器的工作原理。我只是不知道我需要比较什么值才能进行过滤。
发现这个问题:
答案 0 :(得分:1)
我有一个可能的解决方案。我正在尝试的是移动平均冷杉(我被告知是最简单的低通滤波器形式,可以实现)。
需要什么:
我没有实现这个代码,但我确实理解如何在理论层面上使用它。我在下面创建了一个图表来尝试解释这个过程。
基本上,从另一个输入数组中,值将一次一个地传递到FIFO缓冲区。每次传入一个值时,内核都将在具有'n'抽头的FIFO缓冲区中进行乘法运算。每个抽头都有一个与之关联的系数值。因此,特定元素的输入与系数值相乘,然后累计所有值并将其存储在输出缓冲区的一个元素中。
请注意,系数是在Matlab中生成的。我不知道如何抓住这些价值观。起初我只想使用1 / n的系数,但我很确定这只会扭曲信号的值。
这应该是诀窍,我现在要在代码中实现这个,但如果这个理论有任何问题,请随时纠正它。