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

原创 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,压缩算法随笔。

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

相关文章推荐

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

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

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

给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数

给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数。 1.   最基本的算法是,从小到大遍历: for (i = 2 to A -1)          if (i * B > A)...

利用K-means聚类算法根据经纬度坐标对中国省市进行聚类

K-means聚类算法是一种非层次聚类算法,在最小误差的基础上将数据划分了特定的类,类间利用距离作为相似度指标,两个向量之间的距离越小,其相似度就越高。程序读取全国省市经纬度坐标,然后根据经纬度坐标进...

Radon变换理论介绍与matlab实现--经验交流

本人最近在研究Radon变换,在查阅了各种资料之后在此写下个人的理解,希望与各位牛牛进行交流共同进步,也使得理解更加深刻些。 Radon变换的本质是将原来的函数做了一个空间转换,即,将原来的XY平...

CT图像重建技术

由于csdn贴图不方便,并且不能上传附件,我把原文上传到了资源空间CT图像重建技术 1.引言 计算机层析成像(Computed Tomography,CT)是通过对物体进行不同角度的射线投影测量而...

Matlab绘图-很详细,很全面

Matlab绘图强大的绘图功能是Matlab的特点之一,Matlab提供了一系列的绘图函数,用户不需要过多的考虑绘图的细节,只需要给出一些基本参数就能得到所需图形,这类函数称为高层绘图函数。此外,Ma...

linux查找目录下的所有文件中是否含有某个字符串

查找目录下的所有文件中是否含有某个字符串  find .|xargs grep -ri "IBM"  查找目录下的所有文件中是否含有某个字符串,并且只打印出文件名  find .|xargs g...

Radon变换入门matlab CT原理

http://hi.baidu.com/hi9394/blog/item/0d492b8bfd714700c8fc7aa9.html 简介 图像投影,就是说将图像在某一方向上做线性积分(或理解为累...

Excel2016右键新建工作表,打开时提示“因为文件格式或文件扩展名无效。请确定文件未损坏,并且文件扩展名与文件的格式匹配。”的解决办法

上午新建excel工作表时,发现新建完之后居然打不开 提示: 尼玛这坑爹的,难道我的Excel坏了?? 排查问题之后发现 只有新建“Microsoft Excel 工作表”时...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数字信号处理公式变程序(三)——压缩算法
举报原因:
原因补充:

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