c - OpenCL 中的低通滤波器

标签 c opencl lowpass-filter

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

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

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

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

最佳答案

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

要求:

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

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

enter image description here

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

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

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

关于c - OpenCL 中的低通滤波器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37194610/

相关文章:

c++ - 如何使用 OpenCL 构建 ImageMagick?

audio - 具有特定截止频率的低通和高通滤波器

c - 如何在c中创建没有数据库的多变量数组

c - 将 ceil 的结果转换为整数是否安全?

c++ - TrackMouseEvent 不工作

opencl - 在 OpenCL 中选择 CPU 核心数

c - 归一化压缩距离C代码

c - beignet OpenCL xorg 连接失败

iphone - 使用核心音频实现后处理低通滤波器

javascript - 如何将JavaScript(UnityScript)转换为C#并实现低通滤波器?