数字信号处理公式变程序(三)——压缩算法

原创 2015年07月06日 16:58:39

之前搞了一些数字信号处理算法编程(OC),一直没来得及整理,现在整理一下,包括FFT、巴特沃斯滤波器(高低带通、高低带阻)、数据差值(线性、sinc、三次样条*)、数据压缩(等距、平均、峰值检测)和模仿matlab的STFT功能(spectrogram函数三维绘图)。


注:我比较喜欢使用matlab(也喜欢自己修改matlab的源码做测试,所以重装了好几次了,囧。。。),有部分参考matlab的算法进行(或者直接翻译为OC),算法的运行结果经常会跟matlab运算结果进行比较,算法只做学习用,转载请注明。

另外可能会有不足或者理解偏差的地方,路过的高人请不吝赐教。


好啦,进入正题。

---------------------------------------------------------------------------------------

在数字信号处理中如果数据量太大往往需要从中按照一定原则抽取部分点进行分析,此过程叫做压缩。压缩有很多种,这里只实现其中3种:等距、平均和峰值检测。

一、等距压缩

1.原理及实现

等距压缩就是从一堆数据中,按照相等的步长抽取点。如数组{1,2,3,4,5,6,7,8,9,10},步长为2(每两个点取一个)压缩结果是:{1,3,5,7,9}。

实现代码如下:

/*=======================================================
 * 函数名:  compressDataNormal
 * 函数功能:普通压缩方法
 * 变量名称:
 *          xVector      - 自变量,一维数组
 *          yVector      - 因变量,一维数组
 *          length       - 原数组的长度
 *          toLength     - 压缩后数组的长度
 *          returnX      - 压缩后的自变量,一维数组
 *          returnY      - 压缩后的因变量,一维数组
 *
 * 返回值:  压缩是否成功,true-成功,false-失败
 *======================================================*/

+ (Boolean)compressDataNormal:(float *)xVector andY:(float *)yVector andLength:(int)length andToLength:(int)toLength andReturnX:(float *)returnX andReturnY:(float *)returnY
{
    Boolean isCompressOK = false;
    int stageCount = length / toLength; //每段点数,原数据被分为toLength段
    
    for(int i = 0; i < toLength; i++)
    {
        returnX[i] = xVector[stageCount * i];
        returnY[i] = yVector[stageCount * i];
    }
    
    isCompressOK = true;
    return isCompressOK;
}
2.运算结果测试

原数组为16个sin计算值,每两个点取一个,压缩后数组导入matlab绘图如下:

说明:蓝色线为原数组连线,红色线为压缩后数据的连线。


二、平均压缩

1.原理及实现

平均压缩是一个过程算法,即为动态压缩。举例如下:求平均次数为N的压缩结果,每次数据分别为s1, s2, s3, ..., sn。

第1次平均:s = s1/1;

第2次平均:s = (s*1+s2)/2;

...

第i次平均:s = (s*(i-1)+si)/i;

...

第n次平均:s = (s*(n-1)+sn)/n;


由于平均压缩为动态过程,所以实现方法有两种:

①多次调用,每次传入当前平均次数和当前信号的数组(本文采用的方法);

②单次调用,一次性传入多个数组(或一个二维数组),自动循环计算。


平均压缩的代码如下:

/*==========================================================================
 * 函数名:  compressDataAverage
 * 函数功能:平均压缩方法
 * 变量名称:
 *          yVector      - 因变量,一维数组,最新波形
 *          length       - 原数组的长度
 *          returnY      - 压缩后的因变量,一维数组,上一次平均后的波形
 *          times        - 波形刷新次数(第一次显示波形开始计数,为第一次刷新)
 *
 * 返回值:  压缩是否成功,true-成功,false-失败
 *=========================================================================*/

+ (Boolean)compressDataAverage:(float *)yVector andLength:(int)length andReturnY:(float *)returnY andTimes:(int)times
{
    Boolean isCompressOK = false;
    
    for(int i = 0; i < length; i++)
    {
        returnY[i] = (returnY[i] * (times - 1) + yVector[i]) / times;
    }
    
    isCompressOK = true;
    return isCompressOK;
}

2.测试结果

将16个sin计算值和0.95倍的该值打包成两个数组,2次平均压缩后的数据导入matlab绘图如下:蓝色为第一次平均压缩的值绘制的线(第一个数组的值),红线为第二次平均压缩后绘制的曲线。


三、峰值检测

1.原理及实现

峰值检测在示波器应用中比较常见,所以就直接贴出来了。这里起始就是找出最值然后抽取保存即可,如每3个取最大值保留。

代码如下:

/*=======================================================
 * 函数名:  compressDataPeakValue
 * 函数功能:峰值检测压缩方法(取最小值,可改)
 * 变量名称:
 *          xVector      - 自变量,一维数组
 *          yVector      - 因变量,一维数组
 *          length       - 原数组的长度
 *          toLength     - 压缩后数组的长度
 *          returnX      - 压缩后的自变量,一维数组
 *          returnY      - 压缩后的因变量,一维数组
 *
 * 返回值:  压缩是否成功,true-成功,false-失败
 *======================================================*/

+ (Boolean)compressDataPeakValue:(float *)xVector andY:(float *)yVector andLength:(int)length andToLength:(int)toLength andReturnX:(float *)returnX andReturnY:(float *)returnY
{
    Boolean isCompressOK = false;
    int stageCount = length / toLength; //每段点数,原数据被分为toLength段
    
    for(int i = 0; i < toLength; i++)
    {
        int stageMin = stageCount * i;       //循环下线
        int stageMax = stageCount * (i + 1); //循环上线
        int minFoot = stageMin;              //记录最小值的下标
        int maxFoot = stageMin;              //记录最大值的下标
        float maxValueY = yVector[stageMin];//取最大值
        float minValueY = yVector[stageMin];//取最小值
        
        for(int j = stageMin; j < stageMax; j++) //求每段的平均值
        {
            if(maxValueY < yVector[j])
            {
                maxValueY = yVector[j];
                maxFoot = j;
            }
            if(minValueY > yVector[j])
            {
                minValueY = yVector[j];
                minFoot = j;
            }
        }
        
        //取最大值时
//        returnX[i] = xVector[maxFoot];
//        returnY[i] = maxValueY;
        
        //取最小值时
        returnX[i] = xVector[minFoot];
        returnY[i] = minValueY;
    }
    
    isCompressOK = true;
    return isCompressOK;
}

2.结果测试

将sin值压缩一般,结果导入matlab后绘图如下:



附:导入数据后的matlab程序

%MATLAB程序
close all;
clear,clc;

%% 压缩测试
% 原始信号
t =  [ 0.000000  1.000000  2.000000  3.000000  4.000000  5.000000  6.000000  7.000000  8.000000  9.000000  10.000000  11.000000  12.000000  13.000000  14.000000  15.000000  ];
s =  [0.000000  0.841471  0.909297  0.141120  -0.756802  -0.958924  -0.279415  0.656987  0.989358  0.412118  -0.544021  -0.999990  -0.536573  0.420167  0.990607  0.650288 ];


%% 普通压缩
t1 =  [ 0.000000  2.000000  4.000000  6.000000  8.000000  10.000000  12.000000  14.000000  ];
s1 =  [ 0.000000  0.909297  -0.756802  -0.279415  0.989358  -0.544021  -0.536573  0.990607  ];

figure;
plot(t,s,t,s,'bo');
grid on;
hold on;
plot(t1,s1,'r*',t1,s1,'r');
hold off
title('普通压缩');

%% 平均压缩
t2 =  [ 0.000000  1.000000  2.000000  3.000000  4.000000  5.000000  6.000000  7.000000  8.000000  9.000000  10.000000  11.000000  12.000000  13.000000  14.000000  15.000000  ];
s2 =  [ 0.000000  0.799397  0.863833  0.134064  -0.718962  -0.910978  -0.265445  0.624137  0.939890  0.391513  -0.516820  -0.949991  -0.509744  0.399159  0.941077  0.617773  ];

figure;
plot(t,s,t,s,'bo');
grid on;
hold on;
plot(t2,s2,'mp',t2,s2,'m');
hold off
title('平均压缩');

%% 峰值检测
t3 =  [ 0.000000  3.000000  5.000000  6.000000  9.000000  11.000000  12.000000  15.000000  ];
s3 =  [ 0.000000  0.141120  -0.958924  -0.279415  0.412118  -0.999990  -0.536573  0.650288  ];

figure;
plot(t,s,t,s,'bo');
grid on;
hold on;
plot(t3,s3,'mh',t3,s3,'m');
hold off
title('峰值检测(最小值)压缩');

==================================================

OK,压缩算法随笔。

版权声明:本文为博主原创文章,未经博主允许不得转载。

G.711 u律;A律 压缩算法

/**********************************************************************   * g711.c   * u-law, A-law ...
  • Zhu__
  • Zhu__
  • 2016年01月26日 09:59
  • 958

小而巧的数字压缩算法:zigzag

thrift里面简单·美的几十行代码~
  • zgwangbo
  • zgwangbo
  • 2016年06月07日 07:24
  • 12140

整数压缩算法

1 0~255的整数可以只用一个字节表示,256~65535的数据只需2个字节,65536~16777215需要3个字节,16777216以上4个字节 int uncompressed[] ...
  • gdp5211314
  • gdp5211314
  • 2015年05月05日 11:23
  • 974

数字信号处理公式变程序(四)——巴特沃斯滤波器(上)

之前搞了一些数字信号处理算法编程(OC),一直没来得及整理,现在整理一下,包括FFT、巴特沃斯滤波器(高通、低通、带通、带阻)、数据差值(线性、sinc、三次样条*)、数据压缩(等距、平均、峰值检测)...
  • shengzhadon
  • shengzhadon
  • 2015年07月07日 08:38
  • 9803

数字信号处理公式变程序(四)——巴特沃斯滤波器(中)

上一篇写了巴特沃斯滤波器设计的所有理论知识,这篇文章就着手编程吧~ 注:我比较喜欢使用matlab(也喜欢自己修改matlab的源码做测试,所以重装了好几次了,囧。。。),有部分参考matlab的算...
  • shengzhadon
  • shengzhadon
  • 2015年07月07日 17:15
  • 5799

几种压缩算法原理介绍

  • 2009年07月24日 12:31
  • 16KB
  • 下载

lz78数据压缩算法

  • 2013年10月28日 23:21
  • 39KB
  • 下载

数字信号处理公式变程序(二)——插值

之前搞了一些数字信号处理算法编程(OC),一直没来得及整理,现在整理一下。陆续会更新,包括FFT、巴特沃斯滤波器(高低带通、高低带阻)、数据差值(线性、sinc、三次样条*)、数据压缩(等距、平均、峰...
  • shengzhadon
  • shengzhadon
  • 2015年07月06日 16:02
  • 2082

数字信号处理公式变程序(一)——DFT、FFT

之前搞了一些数字信号处理算法编程(OC),一直没来得及整理,现在整理一下。陆续会更新,包括FFT、巴特沃斯滤波器(高低带通、高低带阻)、数据差值(线性、sinc、三次样条*)、数据压缩(等距、平均、峰...
  • shengzhadon
  • shengzhadon
  • 2015年07月03日 09:15
  • 10168

数据压缩算法的实现代码(可运行)

  • 2010年01月09日 11:00
  • 16KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数字信号处理公式变程序(三)——压缩算法
举报原因:
原因补充:

(最多只允许输入30个字)