特别说明:完整45期数字信号处理教程,原创高性能示波器代码全开源地址:链接& ]; E# c9 y( w/ A z2 E$ R
第21章 InterpolationFunctions的使用 8 G2 X0 h+ w/ `5 L* m0 k5 r7 G
本期教程主要讲解一维数据的线性插值和二维数据的双线性插值。 21.1 线性插补 Linear Interpolation 21.2 双线性插补 Bilinear Interpolation 21.3 总结
3 H: {2 Y! `4 s* \; S! ~% [% Z" x3 b21.1 线性插值 Linear Interpolation1 Z$ ^) l$ m% A5 P$ B2 X* O' [$ Z: o
21.1.1 arm_linear_interp_f32公式描述: 直线插补曲线可以通过线性多项式进行拟合。线性内插的工作原理有效地绘制两个相邻样本之间的直线和沿该线再返回相应的插补点。 如上图所示,确定了输入参数x在样本数据中的位置后,就可以绘制这两个样本值之间的直线。然后返回X值对应的Y值。返回方法就是下面的直线公式: y = y0 + (x - x0) * ((y1 - y0)/(x1-x0)) 其中x0和x1是输入值x最近的两个数据,y0和y1是输出值y最近的两个值。 函数定义如下: static __INLINE float32_t arm_linear_interp_f32( arm_linear_interp_instance_f32 * S, float32_t x) 参数定义: [in,out] *S is an instance of the floating-point Linear Interpolation structure [in] x input sample to process return y processed output sample. 注意事项: 1. 结构arm_linear_interp_instance_f32的定义如下(在文件arm_math.h文件): typedef struct { uint32_t nValues; /**< nValues */ float32_t x1; /**< x1 */ float32_t xSpacing; /**< xSpacing */ float32_t *pYData; /**< pointer to the table of Y values */ } arm_linear_interp_instance_f32; 2. 如果输入参数x在输入范围之下返回第一个样本值,如果相爱输入范围之上,返回最后一个样本值。
/ L6 ?% [; v5 ]" G2 t/ U# ^21.1.2 arm_linear_interp_q31函数定义如下: static __INLINE q31_t arm_linear_interp_q31( q31_t * pYData, q31_t x, uint32_t nValues) 参数定义: [in] *pYData pointer to Q31 Linear Interpolation table [in] x input sample to process [in] nValues number of table values return y processed output sample. 注意事项: 1. 结构arm_linear_interp_instance_q31的定义如下(在文件arm_math.h文件): typedef struct { uint16_t numRows; /**< number of rows in the data table. */ uint16_t numCols; /**< number of columns in the data table. */ q31_t *pData; /**< points to the data table. */ } arm_bilinear_interp_instance_q31; 2. 如果输入参数x在输入范围之下返回第一个样本值,如果相爱输入范围之上,返回最后一个样本值。 3. 输入参数x的数据格式是12.20。这样32位数据的12位整数部分用于样本数据的检测,所以最大值就是2的12次方。后20位用于小数部分。 - _: W O0 X3 L# P' B
21.1.3 arm_linear_interp_q15函数定义如下: static __INLINE q15_t arm_linear_interp_q15( q15_t * pYData, q31_t x, uint32_t nValues) 参数定义: [in] *pYData pointer to Q15 Linear Interpolation table [in] x input sample to process [in] nValues number of table values return y processed output sample. 注意事项: 1. 结构arm_linear_interp_instance_q15的定义如下(在文件arm_math.h文件): typedef struct { uint16_t numRows; /**< number of rows in the data table. */ uint16_t numCols; /**< number of columns in the data table. */ q15_t *pData; /**< points to the data table. */ } arm_bilinear_interp_instance_q15; 2. 如果输入参数x在输入范围之下返回第一个样本值,如果相爱输入范围之上,返回最后一个样本值。 3. 输入参数x的数据格式是12.20。这样32位数据的12位整数部分用于样本数据的检测,所以最大值就是2的12次方。后20位用于小数部分。 6 {. \/ |! E" U
21.1.4 arm_linear_interp_q7函数定义如下: static __INLINE q7_t arm_linear_interp_q7( q7_t * pYData, q31_t x, uint32_t nValues) 参数定义: [in] *pYData pointer to Q7 Linear Interpolation table [in] x input sample to process [in] nValues number of table values return y processed output sample. 注意事项: 1. 结构arm_linear_interp_instance_q7的定义如下(在文件arm_math.h文件): typedef struct { uint16_t numRows; /**< number of rows in the data table. */ uint16_t numCols; /**< number of columns in the data table. */ q7_t *pData; /**< points to the data table. */ } arm_bilinear_interp_instance_q7; 2. 如果输入参数x在输入范围之下返回第一个样本值,如果相爱输入范围之上,返回最后一个样本值。 3. 输入参数x的数据格式是12.20。这样32位数据的12位整数部分用于样本数据的检测,所以最大值就是2的12次方。后20位用于小数部分。 9 [2 w' [7 ^3 ~ i2 a/ l
21.1.5 实例讲解实验目的: 1. 学习InterpolationFunctions中线性插补的实现 实验内容: 1. 按下按键K1, 串口打印函数DSP_MatLinearInterpolation的输出结果 实验现象: 通过窗口上位机软件SecureCRT(V5光盘里面有此软件)查看打印信息现象如下: 程序设计: - /* ---------------------------------------------------------------------- (1)
& z! o2 N: u6 x% e# p - * Test input data for F32 SIN function
7 G+ g4 b' {! {% L2 ] j - * Generated by the MATLAB rand() function
; ?' p5 }4 C% K8 d6 H - * randn('state', 0)( @& R6 m& |2 b( g. \' P4 `( z
- * xi = (((1/4.18318581819710)* randn(blockSize, 1) * 2* pi));
5 w |: i; B# [- ]0 n- H# Y - * --------------------------------------------------------------------*/8 S* B$ I& _ r* q1 D1 u
- float32_t testInputSin_f32[TEST_LENGTH_SAMPLES] =
6 {# e C1 {* U) C' d& E$ j, P, I - {
4 l, m% w) ~& W S9 x+ Q4 x - -0.649716504673081170, -2.501723745497831200,
) b9 Z; j8 v. |0 f2 A - 0.188250329003310100, 0.432092748487532540,
3 ~* z) o6 m9 O% O. t1 K - -1.722010988459680800, 1.788766476323060600,
* o" D. R Q( A2 C - 1.786136060975809500, -0.056525543169408797,
% M5 j4 I) n* a) J& Y, K) V - 0.491596272728153760, 0.2623096711261533900 d4 L. c& M X- c5 J
- }; U! v" i4 c% \1 }# s
-
+ c2 S% |/ K4 N/ Q1 \ - /*------------------------------------------------------------------------------( [& [! ]& F! b4 ~
- * Reference out of SIN F32 function for Block Size = 10
) R+ e5 }2 n# Y - * Calculated from sin(testInputSin_f32)
8 q% F. y0 @3 P0 b9 q0 L - *------------------------------------------------------------------------------*/, @. e9 F, H6 b
- float32_t testRefSinOutput32_f32[TEST_LENGTH_SAMPLES] =: R8 e: }$ p9 c: N
- {
, y$ d- T* G, }6 j! G6 f - -0.604960695383043530, -0.597090287967934840,# }6 |) f m& y( H, A
- 0.187140422442966500, 0.418772124875992690,, K ^2 v' n, r% {# K
- -0.988588831792106880, 0.976338412038794010,
5 Y. \, f4 C# A$ J1 G+ G - 0.976903856413481100, -0.056495446835214236,. o2 `, _) |. Z0 ^
- 0.472033731854734240, 0.259311907228582830
+ V! _: E) g3 N& w, A: \ - };
7 Y" ^% i; e. _' X0 c - " W3 A6 b! H$ M
- /*------------------------------------------------------------------------------
* r' Y. D9 K; k - * Method 1: Test out Buffer Calculated from Cubic Interpolation (2)" F4 H5 q! M% M ? f
- *------------------------------------------------------------------------------*/
; r2 d2 X0 G( b7 n# i - float32_t testOutput[TEST_LENGTH_SAMPLES];
/ H" P* M. A& H - % f, a0 A& M6 c' L
- /*------------------------------------------------------------------------------
& [2 ~) o/ ^& O( `# B - * Method 2: Test out buffer Calculated from Linear Interpolation
+ _3 S4 _2 I* x - *------------------------------------------------------------------------------*/( F- A# E! P; a! u) ]$ t
- float32_t testLinIntOutput[TEST_LENGTH_SAMPLES];
0 ~8 f3 M' w6 f- H/ ? - 7 R. T# ~, I( X/ L5 {' [
- /*------------------------------------------------------------------------------
8 K: v8 a/ ?' r0 {- i) C - * External table used for linear interpolation5 b, R4 O2 [1 |
- *------------------------------------------------------------------------------*/! [9 L" g5 K7 z* h; [% R) Q
- extern float arm_linear_interep_table[188495];
( V) i& E! S. \# w - ) G- @% A. j( Q5 a# r
- /* ----------------------------------------------------------------------- o' [/ L' ]: E) [ }; f5 j. L3 `
- * Global Variables for caluclating SNR's for Method1 & Method 2
5 n: P+ J, A/ U1 d+ o: f - * ------------------------------------------------------------------- */
0 s$ Y* {" G B$ G2 J& Y! V - float32_t snr1;% `* r$ p X- m9 m
- float32_t snr2;+ q( Q2 ]) q" h5 m4 z
- /*
/ d" _) Q5 J" j; L - *********************************************************************************************************
( B% z0 h# D4 L& O. X1 W- g - * 函 数 名: DSP_MatLinearInterpolation2 |: l& s0 n1 {2 |+ X
- * 功能说明: 线性插值( b1 X2 {" [: y' I
- * 形 参:无2 y% F y( z- B/ B) s0 a
- * 返 回 值: 无
0 f) q8 @5 S: t( d8 K, C c - *********************************************************************************************************9 l; D9 k# D% n: `; @) p. U8 Q( ^
- */% B0 m. T& H* `; d G/ E m
- static void DSP_MatLinearInterpolation(void)
`+ T6 B# K9 V" u6 b( j" F5 } - {/ n3 z0 e$ U7 R6 |# c
- uint32_t i;
, M8 v* x3 T! V9 E- T C -
9 z; d9 L! c a' S& A4 ^8 Y - arm_linear_interp_instance_f32 S = {188495, -3.141592653589793238, XSPACING, : V8 y c& z9 L. h; Y2 q9 z, b
- &arm_linear_interep_table[0]};4 V3 A* V, h4 v% D% f7 s
-
+ k8 a0 U8 l/ u& T- k" l - /*------------------------------------------------------------------------------, |5 }" q) G5 `* a/ ]' V* O- F
- * Method 1: Test out Calculated from Cubic Interpolation
+ O4 e( a% [% U1 W - *------------------------------------------------------------------------------*/0 t( ^) k! G; f) s3 k( c3 S! j
- for(i=0; i< TEST_LENGTH_SAMPLES; i++)- V' z7 B$ T( C7 U$ \% n
- {
& e9 E! \! h' O1 a6 T1 T - testOutput[i] = arm_sin_f32(testInputSin_f32[i]);
2 i# ~6 L! D: s+ U2 K - }/ Q. w- l2 y( }0 q- y) [0 m
- 8 V' q$ F, f5 o) e: y/ w
- /*------------------------------------------------------------------------------
r+ A6 ]- R; i( x - * Method 2: Test out Calculated from Cubic Interpolation and Linear interpolation* i( t% ~. q1 U
- *------------------------------------------------------------------------------*/( E3 E/ D O7 G, `2 M) L) U0 M
-
2 \- M% u( r: ` - for(i=0; i< TEST_LENGTH_SAMPLES; i++)
. F% Z3 @% m$ j6 n, ]0 t - {
4 f& Y- L3 a7 C; B# ]8 H$ q2 D - testLinIntOutput[i] = arm_linear_interp_f32(&S, testInputSin_f32[i]);
( ?5 X& r3 Y% I - }( R6 K8 F/ V/ O( U7 X
-
) e) w$ ?/ D& X2 d4 r+ f - /*------------------------------------------------------------------------------
; O! s$ G8 p- @% v - * SNR calculation for method 1
" I" l; t$ `8 ~ - *------------------------------------------------------------------------------*/3 [7 U/ g- j1 F+ z" d0 E" A' X
- snr1 = arm_snr_f32(testRefSinOutput32_f32, testOutput, 2); (3)( x( O3 w# j4 @1 H$ ~ N7 Y! W) Y
- printf("Cubic Interpolation snr1 = %f\r\n", snr1);
& M/ a5 K$ N+ O) X- s8 ^( k -
9 k0 l# C8 W- w o! N' Q - /*------------------------------------------------------------------------------
! t- N1 S. D- x v1 m: p; W7 V - * SNR calculation for method 2
& {% C: U( f; B4 [$ B1 ` - *------------------------------------------------------------------------------*/
4 n3 q5 I+ w4 { - snr2 = arm_snr_f32(testRefSinOutput32_f32, testLinIntOutput, 2);
5 A, C4 A7 w) A& Q4 Z6 Q - printf("Linear Interpolation snr2 = %f\r\n", snr2);/ K2 y1 a2 i( C. Z
- , l7 Q5 K- E' Y" [
- /*------------------------------------------------------------------------------' N4 `1 V- ~& ? o
- * Initialise status depending on SNR calculations
) E C0 Z5 M1 D# H0 v [& K- S - *------------------------------------------------------------------------------*/
' o; Y0 f8 `( u0 M6 _, E - if( snr2 > snr1)
# T6 V1 E$ k: S# L- V, j/ m" z - {
$ K( ]4 q5 d8 m( ~ - printf("ARM_MATH_SUCCESS\r\n");
/ A' O2 l- a7 A5 l - }
$ D6 U) L y0 I W5 W - else
& w" s5 }2 h8 N& y+ ]8 ~" L+ I - {, `3 r# g2 f/ ^ }
- printf("ARM_MATH_TEST_FAILURE\r\n");
; p% |5 l, ?# f+ }( ]1 Q - }
1 D i. Z f) w8 l1 O# J7 t# C - }
复制代码1. 使用这个程序前需要通过Matlab获取如下的插值样本: x = -pi: 0.00005 : (2*pi - 0.00005); y = sin(x); 这个插值样本已经放在在了如下文件中 2. 这个函数通过信噪比来对比了前面讲的三次插补和线性插补。最终结果是线性插补的结果要优于三次插补。 3. 关于信噪比的计算,我们会在下章做详细的讲解。 3 h: {+ {& O& ?) v: L" `( a* W3 d
|
21.2.1 arm_bilinear_interp_f32
21.2.2 arm_bilinear_interp_q31
21.2.3 arm_bilinear_interp_q15
21.2.4 arm_linear_interp_q7