硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4131|回复: 1
收起左侧

[DSP] 【安富莱DSP教程】第21章 InterpolationFunctions的使用

[复制链接]

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
发表于 2015-4-2 10:41:27 | 显示全部楼层 |阅读模式
特别说明:完整45期数字信号处理教程,原创高性能示波器代码全开源地址:链接
第21章 InterpolationFunctions的使用


   本期教程主要讲解一维数据的线性插值和二维数据的双线性插值。
    21.1 线性插补 Linear Interpolation
    21.2 双线性插补 Bilinear Interpolation
    21.3 总结

21.1 线性插值 Linear Interpolation

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在输入范围之下返回第一个样本值,如果相爱输入范围之上,返回最后一个样本值。

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位用于小数部分。

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位用于小数部分。

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位用于小数部分。

21.1.5 实例讲解

实验目的:
    1. 学习InterpolationFunctions中线性插补的实现
实验内容:
    1. 按下按键K1, 串口打印函数DSP_MatLinearInterpolation的输出结果
实验现象:
    通过窗口上位机软件SecureCRT(V5光盘里面有此软件)查看打印信息现象如下:

程序设计:
  1. /* ----------------------------------------------------------------------                              (1)
  2. * Test input data for F32 SIN function
  3. * Generated by the MATLAB rand() function
  4. * randn('state', 0)
  5. * xi = (((1/4.18318581819710)* randn(blockSize, 1) * 2* pi));
  6. * --------------------------------------------------------------------*/
  7. float32_t testInputSin_f32[TEST_LENGTH_SAMPLES] =
  8. {
  9.    -0.649716504673081170, -2.501723745497831200,
  10.     0.188250329003310100,  0.432092748487532540,
  11.    -1.722010988459680800,  1.788766476323060600,
  12.     1.786136060975809500, -0.056525543169408797,
  13.     0.491596272728153760,  0.262309671126153390
  14. };
  15. /*------------------------------------------------------------------------------
  16. *  Reference out of SIN F32 function for Block Size = 10
  17. *  Calculated from sin(testInputSin_f32)
  18. *------------------------------------------------------------------------------*/
  19. float32_t testRefSinOutput32_f32[TEST_LENGTH_SAMPLES] =
  20. {
  21.    -0.604960695383043530, -0.597090287967934840,
  22.     0.187140422442966500,  0.418772124875992690,
  23.    -0.988588831792106880,  0.976338412038794010,
  24.     0.976903856413481100, -0.056495446835214236,
  25.     0.472033731854734240,  0.259311907228582830
  26. };
  27. /*------------------------------------------------------------------------------
  28. *  Method 1: Test out Buffer Calculated from Cubic Interpolation                                      (2)
  29. *------------------------------------------------------------------------------*/
  30. float32_t testOutput[TEST_LENGTH_SAMPLES];
  31. /*------------------------------------------------------------------------------
  32. *  Method 2: Test out buffer Calculated from Linear Interpolation
  33. *------------------------------------------------------------------------------*/
  34. float32_t testLinIntOutput[TEST_LENGTH_SAMPLES];
  35. /*------------------------------------------------------------------------------
  36. *  External table used for linear interpolation
  37. *------------------------------------------------------------------------------*/
  38. extern float arm_linear_interep_table[188495];
  39. /* ----------------------------------------------------------------------
  40. * Global Variables for caluclating SNR's for Method1 & Method 2
  41. * ------------------------------------------------------------------- */
  42. float32_t snr1;
  43. float32_t snr2;
  44. /*
  45. *********************************************************************************************************
  46. *    函 数 名: DSP_MatLinearInterpolation
  47. *    功能说明: 线性插值
  48. *    形    参:无
  49. *    返 回 值: 无
  50. *********************************************************************************************************
  51. */
  52. static void DSP_MatLinearInterpolation(void)
  53. {
  54. uint32_t i;
  55. arm_linear_interp_instance_f32 S = {188495, -3.141592653589793238, XSPACING,
  56. &arm_linear_interep_table[0]};
  57. /*------------------------------------------------------------------------------
  58. *  Method 1: Test out Calculated from Cubic Interpolation
  59. *------------------------------------------------------------------------------*/
  60. for(i=0; i< TEST_LENGTH_SAMPLES; i++)
  61. {
  62. testOutput[i] = arm_sin_f32(testInputSin_f32[i]);
  63. }
  64. /*------------------------------------------------------------------------------
  65. *  Method 2: Test out Calculated from Cubic Interpolation and Linear interpolation
  66. *------------------------------------------------------------------------------*/
  67. for(i=0; i< TEST_LENGTH_SAMPLES; i++)
  68. {
  69. testLinIntOutput[i] = arm_linear_interp_f32(&S, testInputSin_f32[i]);
  70. }
  71. /*------------------------------------------------------------------------------
  72. *            SNR calculation for method 1
  73. *------------------------------------------------------------------------------*/
  74. snr1 = arm_snr_f32(testRefSinOutput32_f32, testOutput, 2);                                         (3)
  75. printf("Cubic Interpolation snr1 = %f\r\n", snr1);
  76. /*------------------------------------------------------------------------------
  77. *            SNR calculation for method 2
  78. *------------------------------------------------------------------------------*/
  79. snr2 = arm_snr_f32(testRefSinOutput32_f32, testLinIntOutput, 2);
  80. printf("Linear Interpolation snr2 = %f\r\n", snr2);
  81. /*------------------------------------------------------------------------------
  82. *            Initialise status depending on SNR calculations
  83. *------------------------------------------------------------------------------*/
  84. if( snr2 > snr1)
  85. {
  86. printf("ARM_MATH_SUCCESS\r\n");
  87. }
  88. else
  89. {
  90. printf("ARM_MATH_TEST_FAILURE\r\n");
  91. }
  92. }
复制代码
1. 使用这个程序前需要通过Matlab获取如下的插值样本:
    x = -pi: 0.00005 : (2*pi - 0.00005);
    y = sin(x);
    这个插值样本已经放在在了如下文件中

2. 这个函数通过信噪比来对比了前面讲的三次插补和线性插补。最终结果是线性插补的结果要优于三次插补。
3. 关于信噪比的计算,我们会在下章做详细的讲解。
21.1.png
21.2.png
21.3.png
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2015-4-2 10:53:13 | 显示全部楼层
21.2 双线性插值 Bilinear Interpolation

21.2.1 arm_bilinear_interp_f32

公式描述:
    双线性插值要麻烦些,不过同线性插值的原理是一样的,公式如下:
    其中由x,y来指定插补点,那么做如下定义
        XF = floor(x)
        YF = floor(y)
    插补值的输出结果计算如下:
    f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
                 + f(XF+1, YF) * (x-XF)*(1-(y-YF))
                 + f(XF, YF+1) * (1-(x-XF))*(y-YF)
                 + f(XF+1, YF+1) * (x-XF)*(y-YF)
    (x,y)数据是由整数和小数两部分组成,整数部分用来获取所在的插补样值的位置,小数部分用于实际数据的处理。如果(x, y)数值在插补样值的范围之外,那么返回0。
函数定义如下:
      static __INLINE float32_t arm_bilinear_interp_f32(
      const arm_bilinear_interp_instance_f32 * S,
      float32_t X,
      float32_t Y)
参数定义:
        [in,out] *S points to an instance of the interpolation structure.
       [in] X       interpolation coordinate.
       [in] Y       interpolation coordinate.
        return out interpolated value.
注意事项:
    1. 结构arm_bilinear_interp_instance_f32的定义如下(在文件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. */
       float32_t *pData;     /**< points to the data table. */
        } arm_bilinear_interp_instance_f32;
    2. 如果(x, y)数值在插补样值的范围之外,那么返回0。

21.2.2 arm_bilinear_interp_q31

函数定义如下:
      static __INLINE q31_t arm_bilinear_interp_q31(
      arm_bilinear_interp_instance_q31 * S,
      q31_t X,
      q31_t Y)
参数定义:
         [in,out] *S points to an instance of the interpolation structure.
         [in] X interpolation coordinate in 12.20 format.
         [in] Y interpolation coordinate in 12.20 format.
         return out interpolated value.
注意事项:
    1. 结构arm_bilinear_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, y)数值在插补样值的范围之外,那么返回0。
    3. 输入参数x和y的数据格式是12.20。这样32位数据的12位整数部分用于样本数据的检测,所以最大值就是2的12次方。后20位用于小数部分。

21.2.3 arm_bilinear_interp_q15

函数定义如下:
      static __INLINE q15_t arm_bilinear_interp_q15(
      arm_bilinear_interp_instance_q15 * S,
      q31_t X,
      q31_t Y)
参数定义:
         [in,out] *S points to an instance of the interpolation structure.
         [in] X interpolation coordinate in 12.20 format.
         [in] Y interpolation coordinate in 12.20 format.
         return out interpolated value.
注意事项:
    1. 结构arm_bilinear_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和y的数据格式是12.20。这样32位数据的12位整数部分用于样本数据的检测,所以最大值就是2的12次方。后20位用于小数部分。
    3. 如果(x, y)数值在插补样值的范围之外,那么返回0。

21.2.4 arm_linear_interp_q7

函数定义如下:
      static __INLINE q7_t arm_bilinear_interp_q7(
       arm_bilinear_interp_instance_q7 * S,
       q31_t X,
       q31_t Y)
参数定义:
          [in,out] *S points to an instance of the interpolation structure.
          [in] X interpolation coordinate in 12.20 format.
         [in] Y interpolation coordinate in 12.20 format.
          return out interpolated value.
注意事项:
    1. 结构arm_bilinear_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的数据格式是12.20。这样32位数据的12位整数部分用于样本数据的检测,所以最大值就是2的12次方。后20位用于小数部分。
    3. 如果(x, y)数值在插补样值的范围之外,那么返回0。
    4. 输入参数x和y的数据格式是12.20。这样32位数据的12位整数部分用于样本数据的检测,所以最大值就是2的12次方。后20位用于小数部分。

21.3 总结

     本期教程就跟大家讲这么多,有兴趣的可以深入研究下算法的具体实现。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-4 19:01 , Processed in 0.173062 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表