【DSP】理解并用MATLAB手动实现unwrap()

unwrap函数详解
  • 一般在计算一个系统相频特性时,就要用到反正切函数提取相位,计算机中反正切函数规定:在一、二象限中的角度为0 ~ π,三、四象限的角度为0 ~ -π
  • 但实际得到的结果会发生相位跳变,跳变幅度为2π,这就叫做相位的卷绕
  • unwrap的作用就是解卷绕,使相位在π处不发生跳变,从而反映出真实的相位变化
unwarp标准系统函数
  • unwrap(pha, tol, dim)
    • pha为数列或矩阵
    • tol为判断的阈值
    • dim可以设置为操作对象
      • 若对每一列进行操作,那参数可填1或者省略
      • 若对每一行进行操作,那参数需填2
手动实现unwrap
拟一组数据
  • 假设此时我们拥有一组数据:Data = [-59, -92, -126, -158, 166, 133, 96, 61, 26, -7, -18, -59, -92, -126, -158, 166, 133, 96, 61, 26, -7, -18];

  • DATA

  • 如上图所示,这些数据呈现一种类似周期性的循环,但这并不是真的周期函数,只是因为当他的数值跨越 ±π 时,就会根据其变化形式,条编导边界重新计算

  • 这种状态我们一般称之为相位的卷绕或相位的折叠,用wrap表示,则相位饿解卷绕被称为unwrap

分析拟定数据
  • 数据本身呈现递减趋势,从-59°开始不断递减
  • 数据中在 -158° -> 166° 出现第一次跳变,跳变后继续下降,直到下一次跳变的出现
修订拟定数据 - 解卷绕
  1. 恢复原本的度数 -158° -> 166°
    • -158°到边界点的距离 = |-158° - (-180°)| = 22°
    • 边界点到166°的距离 = |180° - 166°| = 14°
    • 故整体变化度数 = 22° + 14° = 36°
    • 原本度数 = -158° - 36° = -194°
  2. 观察跳变数据
    • 166 - (-194°) = 360°,恰好为360°,从-180°跳到了180°,将函数值增加了360°
  3. 得出本质
    • 根据函数值的变化,wrap的本质就是:当相位超出边界时,补偿360°并继续计算,而unwrap就是为了消除这种补偿
  4. 后续数据
    • 后续数据也应该随着跳变点处恢复原本数据而进行改变,即在遇到下一个跳变点之前,所有数据均应该减去360°得到原始数值
    • 在遇到第二个跳变点时,由于进一步的跳变令补偿再次增加了360°,故第二次跳变之后的值到第三次跳变到来之前,所有数据应该在原本基础上修正360°*2 = 720°
整理公式
  • 根据上述分析unwrap与wrap的关系可以表达为
    u n w r a p ( x ) = w r a p ( x ) ± 360 ∗ w r a p N u m b e r ( x ) unwrap(x) = wrap(x) ± 360 * wrapNumber(x) unwrap(x)=wrap(x)±360wrapNumber(x)
  • 公式中的±分别对应数据递增或递减的情况,将其使用wrapCycle表示,公式可变为
    u n w r a p ( x ) = w r a p ( x ) − w r a p C y c l e ∗ w r a p N u m b e r ( x ) unwrap(x) = wrap(x) - wrapCycle * wrapNumber(x) unwrap(x)=wrap(x)wrapCyclewrapNumber(x)
  • 公式中每个对应的数据点均为其对应一个wrapCycle表示其跳变,公式可变为
    u n w r a p ( x ) = w r a p ( x ) − w r a p C y c l e ( x ) ∗ w r a p N u m b e r ( x ) unwrap(x) = wrap(x) - wrapCycle(x) * wrapNumber(x) unwrap(x)=wrap(x)wrapCycle(x)wrapNumber(x)
MATLAB手动实现
%% unwrap
% unwrap(x) = wrap(x) - wrapCycle*wrapNum(x)

% data0
Data = [-59, -92, -126, -158, 166, 133, 96, 61, 26, -7, -18, -59, -92, -126, -158, 166, 133, 96, 61, 26, -7, -18];
subplot(3, 1, 1);
plot(1:length(Data), Data);
title('Ram simulated data')
grid on;

% use system function unwrap
unwrap_Data = unwrap(deg2rad(Data), [], 2);
unwrap_finallyData = rad2deg(unwrap_Data);
subplot(3, 1, 2);
plot(1:length(Data), unwrap_finallyData);
title('Use system function unwrap')
grid on;

% try to simulate unwrap
length_Data = length(Data);
finallyData = [];
CycleNumber = [];
wrapCycle = [];
% calculata CycleNum
for i = 1 : length_Data
    if i > 1
        if (Data(i) - Data(i-1)) > 180 
            CycleNumber(i)= CycleNumber(i-1) + 1;
        elseif (Data(i) - Data(i-1)) < -180
            CycleNumber(i) = CycleNumber(i-1) + 1;
        else
            CycleNumber(i) = CycleNumber(i-1);
        end
    else
        CycleNumber(i) = 0;
    end
end
% calculata wrapCycle
for i = 1 : length_Data
    if i > 1
        if (Data(i) - Data(i-1)) > 180 
            wrapCycle(i)= 360;
        elseif (Data(i) - Data(i-1)) < -180
            wrapCycle(i) = -360;
        else
            wrapCycle(i) = wrapCycle(i-1);
        end
    else
        wrapCycle(i) = 0;
    end        
end
% updata Data
for i = 1 : length_Data
    finallyData(i) = Data(i) - wrapCycle(i)*CycleNumber(i);
end
subplot(3, 1, 3);
plot(1:length(Data), finallyData);
title('try to simulate unwrap')
grid on;
MATLAB代码解释
  1. % data0
    • 拟定一组含有跳变的数据值,并将其进行绘制,作为对比
  2. % use system function unwrap
    • 使用系统标准unwrap函数进行解卷绕
    • 由于拟定数据表示角度,故在调用unwrap()函数需要对数据进行deg2rad角度到弧度的转换
    • 使用unwrap()解卷绕之后,为方便对比,对数据进行rad2deg弧度到角度的转换
    • 进行绘制作为对比
  3. % try to simulate unwrap
    • 手动实现unwrap
  4. % calculata CycleNum
    • 第一个数据跳变次数为0
    • 之后所有的数据是否跳变取决于与前一个数据的差值是否超过180°
    • 当跳变出现,说明针对前序数据发生一次跳变,即新跳变数据的跳变数比前一次跳变的跳变数多一
  5. % calculata wrapCycle
    • 第一个数据的跳变大小为0
    • 之后所有的数据跳变大小取决于与前一个数据的差值是否超过180°
      • 若差值在[-180, 180],跳变大小与前序数据跳变大小相等
      • 若差值 > 180, 跳变大小为360°进行解卷绕
      • 若差值 < -180, 跳变大小为-360°进行解卷绕
  6. % updata Data
    • 更新手动实现的unwrap数据结果
    • 进行绘制作为对比
MATLAB结果对比
  • 数据对比

数据对比

  • 图像对比

finally

  • 7
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
相位解缠绕算法在MATLAB中可以使用unwrap函数来实现。该函数的作用是通过在相位角度之间添加±2π的倍数来纠正绝对跳变大于或等于默认跳变容差π弧度的连续元素之间的弧度相位角。如果输入是一个矩阵,unwrap函数将按列操作。如果输入是一个多维数组,unwrap函数将在第一个非单例维度上操作。\[2\] 具体实现相位解缠绕的MATLAB代码如下: ```matlab function p = LocalUnwrap(p, cutoff) m = length(p); dp = diff(p, 1, 1); % 计算偏离2*pi的整数倍的次数 dp_corr = dp./(2*pi); % 对于dp_corr小于等于0.5的情况,向下取整 roundDown = abs(rem(dp_corr, 1)) <= 0.5; dp_corr(roundDown) = fix(dp_corr(roundDown)); % 对dp_corr进行四舍五入 dp_corr = round(dp_corr); % 如果dp小于cutoff,则停止跳变(如果cutoff小于等于π,则没有效果) dp_corr(abs(dp) < cutoff) = 0; % 对修正进行积分并添加到P中以产生平滑的相位值 p(2:m,:) = p(2:m,:) - (2*pi)*cumsum(dp_corr, 1); end ``` 这段代码实现了相位解缠绕的核心逻辑,通过对相位差进行修正和积分,从而得到平滑的相位值。\[3\] #### 引用[.reference_title] - *1* [相位解缠算法matlab](https://blog.csdn.net/weixin_39895995/article/details/116075072)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [MATLAB库函数unwrap(相位解卷绕)的C语言实现](https://blog.csdn.net/wlwdecs_dn/article/details/108687654)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值