2016-05-12 183 views
2

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

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

  • 对于输入,我们有一个带有样本大小,频率(通过样本大小乘以频率获得的频率样本)和步长的余弦信号。
  • 将每个步长的值存储在一个数组中,频率和步长乘以函数
  • 然后将该数组传递给内核,然后执行低通滤波器函数。
  • 内核返回一个输出数组与新的过滤值。

cos函数总是从(-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]的值来。此外,我不知道什么numItems或workItems。

如果有人可以提供一些有关这将是伟大的见解。我已经在低通滤波器上搜索了很多其他的例子,但是我无法将我的头包裹在实现中。我希望我明确提出这个问题。再次,我知道低通滤波器的功能。我只是不知道我需要比较哪些值才能进行过滤。

发现这个问题藏汉:

Low Pass filter in C

+0

你是什么意思与“与频率和步长乘以功能”? –

+0

cos(2 * CL_M_PI * signalFreq * h);我只是将信号频率乘以余弦函数。每增加一个数组,h值就会增加步长。由于步长为1 /(频率采样),h几乎是h = h + 1 /(频率采样)。我希望这是用给定频率修改余弦波的正确方法。哦,频率样本只是样本* signalFrequency – VedhaR

回答

1

我有一个可能的解决方案。我所尝试的将是一个移动平均杉木(我被告知是可以实现的低通滤波器的最简单形式)。

什么是必需的:

  • FIFO缓冲器
  • 系数的值(I产生并从MATLAB特定截止频率获得的矿)
  • 用于程序
  • 输入和输出阵列

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

enter image description here

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

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

而且应该做的伎俩,我现在要在代码中实现这一点,但如果这个理论有什么问题,请随时纠正它。

+0

我要接受我自己的答案,因为这是现在所有的。 – VedhaR