代码之家  ›  专栏  ›  技术社区  ›  Guillaume Petitjean

在C中寻找STM32的无动态分配的数据压缩实现

  •  1
  • Guillaume Petitjean  · 技术社区  · 6 年前

    我正在寻找一个可以在STM32L4上运行的无损数据压缩算法实现。数据是ECG曲线(所以基本上是一组16位的数值,彼此比较接近)。

    我发现了不同的实现,例如 miniz 但它们都使用动态内存分配(我希望避免这种情况),而且也相当复杂,而且资源消耗很大。

    我读过 this post 但没有真正的答案。我希望避免修改现有的实现以摆脱动态分配,因为这个功能(数据压缩)不是我的主要任务。

    我不需要一个花哨的最先进的算法,而是一个简单的,资源有限的算法,以节省一些带宽时,发送我的数据在空中,即使压缩比不是最好的。

    你知道适合的算法吗?

    2 回复  |  直到 6 年前
        1
  •  1
  •   0___________    6 年前

    我在用 https://github.com/pfalcon/uzlib

    它使用malloc,但是很容易修改和使用固定大小的缓冲区。

    试试看。

        2
  •  0
  •   vlk    6 年前

    根据您的数据示例,您可以进行自己的非常简单的压缩,无需外部库,速度更快,也许压缩比更好。

    如果查看数据,数字之间的差异通常小于8位整数(int8)的大小,后者可以处理-128之间的数字。。+127号。

    这意味着,如果范围在-127之间,则可以始终存储这些数字之间的差异。。+127号。

    数字-128(0xff)可以是魔术,这意味着这个数字后面跟着一个16位数字。这个神奇的数字也将被用作同步数字和开始。

    或者用8位数字代替4位数字(但这会更复杂一些)(幻数是-8,存储范围是-7。。+7号。你用一个字节存储两个数字。

    所以,以你的例子来说:

    input    |  output 8bit  |  output 4bit
    int16    |  int8  int16  |  int4  int16
    ---------+---------------+---------------
      -12    |  -128    -12  |    -8    -12
      -12    |     0         |     0
      -12    |     0         |     0
      -11    |     1         |     1
      -15    |    -4         |    -4
       -8    |     7         |     7
      -16    |    -8         |    -8    -16
      -29    |   -13         |    -8    -29
       28    |    57         |    -8     28
      169    |  -128    169  |    -8    141
      327    |  -128    327  |    -8    158
      217    |  -110         |    -8    217
      -79    |  -128    -79  |    -8    -79
      -91    |   -12         |    -8
      -59    |    32         |    -8    -59
      -41    |    18         |    -8    -41
      -36    |     5         |     5
      -29    |     7         |     7
      -26    |     3         |     3
      -24    |     2         |     2
      -22    |     2         |     2
      -19    |     3         |     3
      -14    |     5         |     5
      -14    |     0         |     0
      -12    |     2         |     2
      -10    |     2         |     2
      -10    |     0         |     0
       -5    |     5         |     5
       -2    |     3         |     3
        1    |     3         |     3
        5    |     4         |     4
       10    |     5         |     5
       15    |     5         |     5
       17    |     2         |     2
       21    |     4         |     4
       22    |     1         |     1
       20    |    -2         |    -2
       20    |     0         |     0
       15    |    -5         |    -5
        9    |    -6         |    -6
        2    |    -7         |    -7
       -6    |    -8         |    -8    -6
    ---------+---------------+---------------------
       42    |    42      4  |    42    11     count
       84    |    42      8  |    21    22     bytes
       84    |        50     |       43        bytes total
      100%   |        60%    |       51%       compression ratio
    

    所以,正如你所看到的,用非常简单的算法你可以得到非常好的结果。

    此外,还可以找到该算法的其他改进,例如将相同的数据分组,或者在幻数之后压缩16位数据。例如,在magic number之后,可以指定后跟的16位数字(未压缩的数字)

    但一切都取决于你的数据。