信号的重建

本文深入探讨了信号重建的基本原理及其实现方法,包括利用sinc函数进行信号重建的数学公式,并通过具体的MATLAB代码示例展示了如何从采样信号中重建原始信号,同时对比了不同方法的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

信号的重建


1、原理

完成了时间轴的离散和幅值轴的量化后,这个问题貌似已经解决,但在实践过程中就会发现,即使按照信号采样定理完成信号的采样,信号显示的结果也可能会与原始信号相差甚远。这是为什么?有无办法改善这种巨大差异?当然,差异是可以改善的,否则采样定理就没用了,秘籍就是下面不算太复杂的公式。

x(t)=n=+x(nΔ)sin((tnΔ)1Δ)(tnΔ)1Δx(t)=∑n=−∞+∞x(nΔ)sin((t−nΔ)1Δ)(t−nΔ)1Δ

上式中的tt是连续的量,将个采样点的离散值与连续量相乘就可重建原来的信号。 
但由于计算机中只有离散和有限长的量,所以我们还要用间隔更小的时间离散量ykyk来代替连续时间量tt,要注意的是上式中xnxn是离散的量,而ykyk则是时间间隔更小的离散量,这个公式完成的运算就是从向量x⃗ x→转换到向量y⃗ y→,如何完成这样的转换呢?这就需要一个矩阵帮助实现这种变换,可以讨论一下矩阵的构造方法。

  • 蛮力 
    在每个xkxk对应时间点都计算相应sincsinc值,费时费力
  • 巧劲 不走重复路 
    只是计算一次,剩下的从第一次计算的值出发,延伸导出。

2、CSignal添加信号重构行为 蛮力方法

  1. function ReConstruct(sig)
  2. vec = sig.m_vec;
  3. dFs = sig.m_dFs;
  4. tStart = sig.m_tStart;
  5. deltaT = 1/dFs;
  6. dReFs = sig.m_dFs*50;
  7. t = tStart + (0:length(vec)-1)*deltaT;
  8. tRec = tStart:1/dReFs:((length(vec)-1)*deltaT);
  9. vecRec = zeros(1,length(tRec));
  10. figure(3)
  11. for ind = 0:length(vec)-1
  12. vecRecTmp = sinc((tRec - ind*deltaT)/deltaT);
  13. vecRec = vecRec + vec(ind+1)*vecRecTmp;
  14. plot(tRec, vecRec)
  15. pause;
  16. end
  17. figure(2)
  18. plot(t,vec, 'r:', tRec,vecRec, 'k-', 'linewidth', 2)
  19. xlabel('Time s','fontsize', 14)
  20. ylabel('Amplitude','fontsize', 14)
  21. set(gca, 'fontsize', 14)
  22. legend('²ÉÑù','ÖØ¹¹')
  23. end

3、script程序 使用类

  1. % sigProcess01.m
  2. % signal process exercise
  3. close all;
  4. clc;
  5. dFreq = 0.5;
  6. dFs = 2.2*dFreq;
  7. tStart = 0;
  8. t = tStart:1/dFs:10;
  9. vec = cos(2*pi*dFreq*t);
  10. sig = CSignal(vec, dFs, tStart);
  11. sig.ReConstruct;

4、新的成员函数

  1. function [vecTRecnt, vecSigRecnt] = ReconstructSig(varargin)
  2. if nargin == 1
  3. obj = varargin{1};
  4. nMultpRecnt = 10;
  5. else
  6. obj = varargin{1};
  7. nMultpRecnt = varargin{2};
  8. end
  9. dFsRecnt = obj.m_dFs*nMultpRecnt;
  10. vecTRecnt = 0:1/dFsRecnt:obj.m_dTime;% for calculate xtSinc
  11. xtSinc = sinc(obj.m_dFs*vecTRecnt);
  12. vecSigRecnt = zeros(1, length(vecTRecnt));
  13. vecSig = obj.m_vecSig;
  14. for ind = 1:length(obj.m_vecSig)
  15. % calculate sinc only once
  16. if ind == 1
  17. vecSigRecntTmp = xtSinc;
  18. else
  19. indexXtSincPre = ((ind-1)*nMultpRecnt+1):-1:2;
  20. indexXtSincPost = 1:(length(xtSinc)-(ind-1)*nMultpRecnt);
  21. vecSigRecntTmp = [xtSinc(indexXtSincPre) xtSinc(indexXtSincPost)];
  22. end
  23. % % calculate sinc every loop
  24. % vecSigRecntTmp = sinc(dFs*vecTRecnt - ind + 1);
  25. vecSigRecnt = vecSigRecnt + vecSig(ind)*vecSigRecntTmp;
  26. end
  27. % correspond to the time vector of signal
  28. vecTRecnt = obj.m_dTimeStart*ones(1,length(vecTRecnt)) + vecTRecnt;
  29. vecOrig = obj.m_vecSig;
  30. t_orig = (0:length(vecOrig)-1)/obj.m_dFs;
  31. figure;
  32. plot(vecTRecnt, vecSigRecnt, t_orig, vecOrig, 'linewidth',2)
  33. xlabel('时间 S')
  34. ylabel('信号')
  35. legend('插值后','未插值')
  36. end

5、新的SCRIPT程序

  1. % Exer_SigProcess_xcript.m
  2. close all;
  3. strCurrentPath = cd;
  4. addpath([strCurrentPath '\classdef']);
  5. vecAmp=[1 3 5];
  6. vecFreq = [1 2 3];
  7. vecPhi = [0 pi/3 pi/4];
  8. Fs = 4.3;
  9. t = 0:1/Fs:2*pi;
  10. xt = 0;
  11. for ind = 1:1
  12. xt = xt + vecAmp(ind)*cos(2*pi*vecFreq(ind)*t + vecPhi(ind));
  13. end
  14. sig = CSignal(Fs, xt);
  15. sig.DispSigCurve;
  16. [vecTRecnt, vecSigRecnt] = sig.ReconstructSig(20);
  17. rmpath([strCurrentPath '\classdef']);

程序运行结果 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值