2025年3月29日 星期六 甲辰(龙)年 月廿八 设为首页 加入收藏
rss
您当前的位置:首页 > 电子 > 嵌入式系统

嵌入式算法11---矩阵转置与压缩

时间:03-17来源:作者:点击数:56

在整个物联网系统中,嵌入式设备作为数据采集、过滤、缓存、传输的节点,前面系列文章分别介绍了嵌入式设备相关的各种数据过滤、校验和压缩存储算法。缓存和传输阶段,考虑到嵌入式设备的存储空间和传输带宽限制,数据包的压缩还可进一步优化。

以嵌入式终端环境数据采集为例,以10秒间隔采样温度、湿度、气压、风速、四项环境数据,正常情况下,数据在短时间内都是小幅波动或者维持不变。假如采集结果(瞎编的,表意为主)如下表:

时间戳 温度 湿度 气压 风速
10 27 75 98 3
20 27 75 98 3
30 27 75 99 3
40 27 76 99 3
50 28 76 99 2
60 29 76 99 2

数据按字节流存储到文件或者传输出去,占30字节。

  • unsigned char source_data[30]={10,27,75,98,3,20,27,75,98,3,30,27,75,99,3,40,27,76,99,3,50,28,76,99,2,60,29,76,99,2}

前文行程编码要求数据中尽可能出现连续的内容,上表数据并不适合行程编码来压缩。

线性代数的基础是矩阵,此时此刻,矩阵转置的算法就可发挥作用了。将数据原始数据以二维数据的方式保存。

  • unsigned char source_matrix[5][6]={
  • 10,10,30,98,3,
  • 20,27,75,98,3,
  • 30,27,75,99,3,
  • 40,27,76,99,3,
  • 50,28,76,99,2,
  • 60,29,76,99,2}

观察数据,按C语言的行优先方式没有连续的数据,但如果以列为优先,则数据中存在较多的连续数据。因此先将数据进行矩阵行列转置后,即可满足行程编码的要求。

实现效果以及源码如下:

  • #include "stdio.h"
  • #include "string.h"
  • void log(char *head,unsigned char* data,unsigned int len,unsigned char line)
  • {
  • unsigned int i;
  • printf("%s\r\n",head);
  • for(i=0;i<len;i++)
  • {
  • printf("%3d ",data[i]);
  • if(((i+1)%line)==0)
  • {
  • printf("\r\n");
  • }
  • }
  • printf("\r\n");
  • }
  • //矩阵转置,执行一次行列交互,再次执行则恢复原样
  • // row 和 column 表示输入矩阵的行和列
  • void matrix_transpose(unsigned char* input, unsigned char row, unsigned char column, unsigned char* output)
  • {
  • unsigned char i, j;
  • for(i = 0; i < row; i++)
  • {
  • for(j = 0; j < column; j++)
  • {
  • *(output + j * row + i) = *(input + i * column + j);
  • }
  • }
  • }
  • int main(int argc, char *argv[])
  • {
  • //原始6行5列的数据
  • unsigned char source[30]={10,27,75,98,3,20,27,75,98,3,30,27,75,99,3,40,27,76,99,3,50,28,76,99,2,60,29,76,99,2};
  • //转成5行6列,用于行程编码
  • unsigned char change[30]={0};
  • //恢复为原始的6行5列
  • unsigned char resume[30]={0};
  • log("source",(unsigned char*)source,sizeof(source),15);
  • log("source",(unsigned char*)source,sizeof(source),5);
  • matrix_transpose((unsigned char*)source,6,5,change);
  • log("change",change,sizeof(change),5);
  • log("[new]",(unsigned char*)change,sizeof(change),15);
  • matrix_transpose(change,5,6,(unsigned char*)resume);
  • log("resume",(unsigned char*)resume,sizeof(resume),5);
  • return 0;
  • }

运行结果如下:

  • source
  • 10 27 75 98 3 20 27 75 98 3 30 27 75 99 3
  • 40 27 76 99 3 50 28 76 99 2 60 29 76 99 2
  • source
  • 10 27 75 98 3
  • 20 27 75 98 3
  • 30 27 75 99 3
  • 40 27 76 99 3
  • 50 28 76 99 2
  • 60 29 76 99 2
  • change
  • 10 20 30 40 50
  • 60 27 27 27 27
  • 28 29 75 75 75
  • 76 76 76 98 98
  • 99 99 99 99 3
  • 3 3 3 2 2
  • [new]
  • 10 20 30 40 50 60 27 27 27 27 28 29 75 75 75
  • 76 76 76 98 98 99 99 99 99 3 3 3 3 2 2
  • 【转置后相同数据集中连续出现】
  • resume
  • 10 27 75 98 3
  • 20 27 75 98 3
  • 30 27 75 99 3
  • 40 27 76 99 3
  • 50 28 76 99 2
  • 60 29 76 99 2

其中[new]块数据就适合行程编码来压缩空间,为提高压缩比,可以每20组数据包分为一个矩阵进行转置压缩,太少则压缩比不明显。

矩阵转置与行程编码两算法,可以解决固定长度重复出现,内部数据变化趋于稳定的数据包压缩。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门