【发布时间】:2016-05-12 18:17:59
【问题描述】:
我正在尝试在 OpenCL 中实现一个低通滤波器,而这一切背后的理论让我有些困惑。在我解释了场景之后,我在底部附上了我的代码。
首先,让我试着用点的形式解释整个场景。
- 对于输入,我们有一个 cos 信号,它具有样本大小、频率(通过将样本大小与频率相乘获得的频率样本)和步长。
- 每个步长的值存储在一个数组中,频率和步长乘以函数
- 然后这个数组被传入内核,然后内核将执行低通滤波器功能。
- 内核返回一个包含新过滤值的输出数组。
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 中的过滤器实现中,将 data[j] 与 value 进行比较。我也不知道 numItems 或 workItems 是什么。
如果有人能对此提供一些见解,那就太好了。我已经搜索了很多关于低通滤波器的其他示例,但我无法完全理解实现。我希望我把这个问题说清楚了。同样,我知道低通滤波器是如何/做什么的。我只是不知道需要比较哪些值才能进行过滤。
也发现了这个问题:
【问题讨论】:
-
“频率和步长乘以函数”是什么意思?
-
cos(2*CL_M_PI * signalFreq * h);我只是将信号频率乘以余弦函数。每次我增加数组时,h 值都会增加步长。由于步长为 1/(频率样本),所以 h 几乎是 h= h + 1/(频率样本)。我希望这是修改具有给定频率的余弦波的正确方法。哦,频率样本只是 samplesize*signalFrequency
标签: c opencl lowpass-filter