- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
FIR 滤波器有一个算法,但它是 float : FIR filter implementation in C programming
如果我想要一个符合此规范的定点算法,我该怎么做?
the FIR-filter receives and sends 8-bit fixed-point numbers in the Q7-format via the standard input and output. Remember to output the measured time (number of ticks) also in hex format. Following the guidelines presented in the previous section, your program should call getchar() to read a Q7-value. should call putchar() to write a Q7-value.
系数是
c0=0.0299 c1=0.4701 c2=0.4701 c3=0.299
对于定点算法,我需要为定点数实现自己的乘法,对吗?
我应该像结构一样存储固定点数吗?
struct point
{
int integer;
int fraction;
};
我应该使用轮类来实现编号,具体如何实现?
数字是 32 位的,所以我可以像下面这样写移位吗?
#define SHIFT_AMOUNT 16 // 2^16 = 65536
#define SHIFT_MASK ((1 << SHIFT_AMOUNT) - 1)
所以我认为我必须先实现一种乘法算法,然后再实现 FIR 算法本身?那是对的吗?你能帮帮我吗?
我在 anser 中编译并运行了一个程序,但它给了我意想不到的输出。
#include <stdio.h>
#include "system.h"
#define FBITS 16 /* number of fraction bits */
const int c0 = (( 299<<FBITS) + 5000) / 10000; /* (int)(0.0299*(1<<FBITS) + 0.5) */
const int c1 = ((4701<<FBITS) + 5000) / 10000; /* (int)(0.4701*(1<<FBITS) + 0.5) */
/* Ditto for C3 and C2 */
const int c2 = (( 4701<<FBITS) + 5000) / 10000; /* (int)(0.4701 *(1<<FBITS) + 0.5) */
const int c3 = ((299<<FBITS) + 5000) / 10000; /* (int)(0.299*(1<<FBITS) + 0.5) */
#define HALF (1 << (FBITS) >> 1) /* Half adjust for rounding = (int)(0.5 * (1<<FBITS)) */
signed char input[4]; /* The 4 most recent input values */
int output = 0;
void firFixed()
{
signed char sum = c0*input[0] + c1*input[1] + c2*input[2] + c3*input[3];
output = (signed char)((sum + HALF) >> FBITS);
printf("output: %d\n", output);
}
int main( void )
{
int i=0;
signed char inVal;
while (scanf("%c", &inVal) > 0)
{
if (i>3)
{
i=0;
}
input[i]=inVal;
firFixed();
i++;
}
return 0;
}
为什么输出计算不正确,为什么一次输入后多次写入输出?
我尝试编写定点 FIR 滤波器,算法可能不是 100% 正确:
#include <stdio.h>
#include "system.h"
#define FBITS 16 /* number of fraction bits */
const int c0 = (( 299<<FBITS) + 5000) / 10000; /* (int)(0.0299*(1<<FBITS) + 0.5) */
const int c1 = ((4701<<FBITS) + 5000) / 10000; /* (int)(0.4701*(1<<FBITS) + 0.5) */
/* Ditto for C3 and C2 */
const int c2 = (( 4701<<FBITS) + 5000) / 10000; /* (int)(0.4701 *(1<<FBITS) + 0.5) */
const int c3 = ((299<<FBITS) + 5000) / 10000; /* (int)(0.299*(1<<FBITS) + 0.5) */
#define HALF (1 << (FBITS) >> 1) /* Half adjust for rounding = (int)(0.5 * (1<<FBITS)) */
signed char input[4]; /* The 4 most recent input values */
char get_q7( void );
void put_q7( char );
void firFixed()
{
int sum = c0*input[0] + c1*input[1] + c2*input[2] + c3*input[3];
signed char output = (signed char)((sum + HALF) >> FBITS);
put_q7(output);
}
int main( void )
{
int i=0;
while(1)
{
if (i>3)
{
i=0;
}
input[i]=get_q7();
firFixed();
i++;
}
return 0;
}
#include <sys/alt_stdio.h>
char get_q7( void );
char prompt[] = "Enter Q7 (in hex-code): ";
char error1[] = "Illegal hex-code - character ";
char error2[] = " is not allowed";
char error3[] = "Number too big";
char error4[] = "Line too long";
char error5[] = "Line too short";
char get_q7( void )
{
int c; /* Current character */
int i; /* Loop counter */
int num;
int ok = 0; /* Flag: 1 means input is accepted */
while( ok == 0 )
{
num = 0;
for( i = 0; prompt[i]; i += 1 )
alt_putchar( prompt[i] );
i = 0; /* Number of accepted characters */
while( ok == 0 )
{
c = alt_getchar();
if( c == (char)26/*EOF*/ ) return( -1 );
if( (c >= '0') && (c <= '9') )
{
num = num << 4;
num = num | (c & 0xf);
i = i + 1;
}
else if( (c >= 'A') && (c <= 'F') )
{
num = num << 4;
num = num | (c + 10 - 'A');
i = i + 1;
}
else if( (c >= 'a') && (c <= 'f') )
{
num = num << 4;
num = num | (c + 10 - 'a');
i = i + 1;
}
else if( c == 10 ) /* LF finishes line */
{
if( i > 0 ) ok = 1;
else
{ /* Line too short */
for( i = 0; error5[i]; i += 1 )
alt_putchar( error5[i] );
alt_putchar( '\n' );
break; /* Ask for a new number */
}
}
else if( (c & 0x20) == 'X' || (c < 0x20) )
{
/* Ignored - do nothing special */
}
else
{ /* Illegal hex-code */
for( i = 0; error1[i]; i += 1 )
alt_putchar( error1[i] );
alt_putchar( c );
for( i = 0; error2[i]; i += 1 )
alt_putchar( error2[i] );
alt_putchar( '\n' );
break; /* Ask for a new number */
}
if( ok )
{
if( i > 10 )
{
alt_putchar( '\n' );
for( i = 0; error4[i]; i += 1 )
alt_putchar( error4[i] );
alt_putchar( '\n' );
ok = 0;
break; /* Ask for a new number */
}
if( num >= 0 && num <= 255 )
return( num );
for( i = 0; error3[i]; i += 1 )
alt_putchar( error3[i] );
alt_putchar( '\n' );
ok = 0;
break; /* Ask for a new number */
}
}
}
return( 0 ); /* Dead code, or the compiler complains */
}
#include <sys/alt_stdio.h>
void put_q7( char ); /* prototype */
char prom[] = "Calculated FIR-value in Q7 (in hex-code): 0x";
char hexasc (char in) /* help function */
{
in = in & 0xf;
if (in <=9 ) return (in + 0x30);
if (in > 9 ) return (in - 0x0A + 0x41);
return (-1);
}
void put_q7( char inval)
{
int i; /* Loop counter */
for( i = 0; prom[i]; i += 1 )
alt_putchar( prom[i] );
alt_putchar (hexasc ((inval & 0xF0) >> 4));
alt_putchar (hexasc (inval & 0x0F));
alt_putchar ('\n');
}
最佳答案
FIR 滤波器结果中的每个点都只是未过滤数据的加权和。如果您有 8 位输入数据和 32 位算术,则除了简单的乘法和加法之外,您不需要任何其他东西。
快速访问维基百科告诉我 Q7 本质上是一个 8 位 2 的补码整数,因此如果目标平台使用 2 的补码,那么简单地将接收到的字节描述为 (signed char) 将在以下情况下为其提供正确的数值提升为 int。如果您将系数预乘以 2 的幂,则加权和将乘以 2 的相同幂。然后,舍入除法只是简单地添加一个半调整值,然后是一个带符号的右移。对于 16 位小数,预乘常量为:
#define FBITS 16 /* number of fraction bits */
const int C0 = (( 299<<FBITS) + 5000) / 10000; /* (int)(0.0299*(1<<FBITS) + 0.5) */
const int C1 = ((4701<<FBITS) + 5000) / 10000; /* (int)(0.4701*(1<<FBITS) + 0.5) */
/* Ditto for C3 and C2 */
#define HALF (1 << (FBITS) >> 1) /* Half adjust for rounding = (int)(0.5 * (1<<FBITS)) */
这种奇怪的原因是在不依赖任何浮点舍入的情况下获得您想要的有效位。现在,如果:
signed char input[4];
...包含最近的 4 个输入值,您的输出值为:
sum = c0*input[0] + c1*input[1] + c2*input[2] + c3*input[3];
output = (signed char)((sum + HALF) >> FBITS);
因为你所有的系数都是正的并且总和为 1.0,所以没有溢出的可能性。
在您获得一个简单的版本后,您可以尝试一些优化。其他系数的一个可能的小故障是 C0-C3 常量的四舍五入产生的值加起来不完全等于 1<<FBITS
。 .我测试了这些值并没有发生这种情况(你需要 c0*(1<<LBITS)
的小数部分恰好是 0.5;这意味着所有其他缩放系数也将 0.5 作为它们的小数部分。它们都是圆的向上,总和将太大 2。这可能会给您的过滤器增加一个非常小的意外增益。
您提供的系数不会发生这种情况。
编辑:我忘了。求和时整数部分和小数部分都在同一个32位int中。使用 8 位输入(7+符号)和 16 位小数,您最多可以在过滤器中拥有 2^(32 - 16 - 8) = 2^8 = 256 个点(此时,您显然会有一个系数数组,以及计算总和的乘加循环。如果(输入大小)+(分数位)+ log2(滤波器大小)超过 32,则可以尝试将总和字段扩展为 C99 long long 或int64_t 值(如果可用),如果不可用,则编写扩展精度加法和移位逻辑。如果可用,硬件中的扩展精度更好用。
关于c - C 中的定点 FIR 滤波器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19192358/
所以我试图增强我的图像的对比度,我发现一位绅士通过在线 Gamma 校正来做到这一点,代码如下: (im/255).^0.45*255 据我了解,1/gammavalue = 0.45,其中 gamm
我有一个包含简单时间序列数据的向量(从 deSolve 矩阵中提取),用于测试目的可以是: x x r for (n in 2:length(x)) r[n] (r) [1] NA 1 1
我有这段实现 Prewitt 边缘检测的代码。我需要做的是只用一个缓冲区来实现它,也就是说,我不会创建图像的拷贝,而是编辑原始图像。所以如果我想改变值 78 的像素,我不能把新值,例如100,直到所有
我想制作一个 FIR 滤波器。我有一个系数数组 (buffer[size]) 和一个数据数组 (filter[size_filter])。我必须在两个数组之间进行卷积: for(j = 0;j < s
我正在尝试制作 IIR 滤波器。我做了FIR滤波器,但是我觉得IIR比FIR难。 我认为 IIR 与 FIR 类似,但它让我感到困惑。 我觉得过滤器是这样的 FIR : y(n) = b0(x[n])
我想在 Python 中通过窗口创建一个基本的高通 FIR 滤波器。 我的代码在下面并且是故意惯用的 - 我知道你可以(很可能)用 Python 中的一行代码完成它,但我正在学习。我使用了一个带有矩形
我正在尝试用树莓派创建一个相机来检测在走廊中移动的人(这里我假设只有移动的东西是人),并识别那些在该区域花费太多时间的人(使用计时器),我使用背景减法来检测运动并尝试使用基于相关性的跟踪器(例如 MO
我正在研究用于特征提取的超像素。我已经成功地将超像素功能应用于图像。 A = imread('kobi.png'); [L,N] = superpixels(A,5); figure BW = bou
你好 我需要在应用中使用这个 Kolmogorov 过滤器。您将一些测量数据放入其中,并使用过滤器对其进行一些平滑处理。我试着用“nchoosek”来做,但是当我尝试为 50 或更多的 I 做这件事时
我正在尝试在具有静态掩码 5x5 并在 applyFilter() 函数中进行卷积编码的图像上实现 LoG 过滤器。然而,无论我使用什么面具,我都会得到奇怪的结果。保存图像而不通过函数传递它是有效的,
我已经在 Haskell 中实现了一个 FIR 滤波器。我不太了解 FIR 滤波器,我的代码很大程度上基于现有的 C# 实现。因此,我觉得我的实现有太多的 C# 风格,而不是真正的 Haskell 风
我需要制作一个简单的带通音频滤波器。现在我使用了这个简单的 C++ 类:http://www.cardinalpeak.com/blog/a-c-class-to-implement-low-pass
CUDA NPP 库支持使用 nppiFilter_8u_C1R 命令过滤图像,但不断出现错误。我可以毫无问题地启动并运行 boxFilterNPP 示例代码。 eStatusNPP = nppiFi
我是 OpenCV 和 gabor 过滤器的新手,只想获得这样的 gabor 小波: 我在 Java 中使用这个 OpenCV 代码: double sigma_bar = 40; double th
我正在使用 FIR 滤波器对音频进行过采样。这是一个简单的典型窗口 sinc,即一个被截断和窗口化的 sinc 函数。像往常一样,它需要过去和“ future ”的样本才能工作。实际上,这意味着音频输
目前我正在尝试实现 FIR 低通滤波器。 FIR 系数在 MATLAB 中计算。现在我需要用 C++ 实现 FIR 算法。 我将一个类定义为过滤器,将 FIR 的一个函数定义为: double * F
我有一个用 C 语言实现 FIR 滤波器的家庭作业,我想知道您是否认为我理解正确。我认为解决问题的程序是: #include float FIRfloats[5]; void floatFIR(fl
我希望对图像的每条水平线应用频域滤波器,例如低通或带通。这可能使用 opencv 吗? 最佳答案 我认为您需要详细说明您的问题。也许,举一些具体的例子。 如果我将您的问题解释为: 你有一张 10 x
我的问题与 A. Levy 的解释相关: Analyze audio using Fast Fourier Transform 如何在这些复数上生成带通滤波器... [-636.00000000 +0
FIR 滤波器有一个算法,但它是 float : FIR filter implementation in C programming 如果我想要一个符合此规范的定点算法,我该怎么做? the FIR
我是一名优秀的程序员,十分优秀!