在C中寻找没有STM32动态分配的数据压缩实现
Looking for a data compression implementation in C without dynamic allocation for STM32
我正在寻找可以在 STM32L4 上 运行 的无损数据压缩算法实现。数据是 ECG 曲线(所以基本上是一组 16 位数值,彼此相对接近)。
我发现了不同的实现方式,例如 miniz,但它们都使用动态内存分配(我想避免这种情况),而且非常复杂且耗费资源。
我读过 this post 但没有真正的答案。我想避免修改现有实现以摆脱动态分配,因为此功能(数据压缩)不是我的主要优先事项。
我不需要最先进的算法,而是一种简单的、资源有限的算法,即使压缩比不是最好的,也可以在无线发送数据时节省一些带宽。
您是否知道适合的算法?
我正在使用 https://github.com/pfalcon/uzlib
它使用 malloc 但很容易修改和使用固定大小的缓冲区。
看看试试
根据您的数据示例,您可以自己进行非常简单的压缩,无需外部库,速度更快,压缩率可能更高。
如果您查看数据,数字之间的差异通常小于 8 位整数的大小 (int8_t),它可以处理 -128 .. + 127 之间的数字。
这意味着如果范围在 -127 .. + 127 之间,您可以始终存储这些数字之间的差异。
Number -128 (0xff) 可能很神奇,这意味着这个数字后面将跟一个 16 位数字。这个幻数也将用作同步数,也将在开始时使用。
或者使用 4 位数字而不是 8 位数字(但这会更复杂一些)(幻数将为 -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 位数据数据。例如,在幻数之后,您可以指定后面的 16 位数字(未压缩数字)
但一切都取决于你的数据。
我正在寻找可以在 STM32L4 上 运行 的无损数据压缩算法实现。数据是 ECG 曲线(所以基本上是一组 16 位数值,彼此相对接近)。
我发现了不同的实现方式,例如 miniz,但它们都使用动态内存分配(我想避免这种情况),而且非常复杂且耗费资源。
我读过 this post 但没有真正的答案。我想避免修改现有实现以摆脱动态分配,因为此功能(数据压缩)不是我的主要优先事项。
我不需要最先进的算法,而是一种简单的、资源有限的算法,即使压缩比不是最好的,也可以在无线发送数据时节省一些带宽。
您是否知道适合的算法?
我正在使用 https://github.com/pfalcon/uzlib
它使用 malloc 但很容易修改和使用固定大小的缓冲区。
看看试试
根据您的数据示例,您可以自己进行非常简单的压缩,无需外部库,速度更快,压缩率可能更高。
如果您查看数据,数字之间的差异通常小于 8 位整数的大小 (int8_t),它可以处理 -128 .. + 127 之间的数字。
这意味着如果范围在 -127 .. + 127 之间,您可以始终存储这些数字之间的差异。
Number -128 (0xff) 可能很神奇,这意味着这个数字后面将跟一个 16 位数字。这个幻数也将用作同步数,也将在开始时使用。
或者使用 4 位数字而不是 8 位数字(但这会更复杂一些)(幻数将为 -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 位数据数据。例如,在幻数之后,您可以指定后面的 16 位数字(未压缩数字)
但一切都取决于你的数据。