matlab曲线数据序列水平段数据自动识别并标注

在工作和生活中,经常会有这样的需求,将测试过程中得到的数据进行记录。手动的点击识别效率会非常慢。最近自己写了一个自动识别数据水平段的值并记录的matlab代码,这里分享给大家。
这个识别代码要求数据是有一定水平段的,也就是说测试的时候需要在需要记录数据的点停留一段时间,就像下面这张图:

数据示例
最后的结果是这个样子
最终识别效果

点击这里下载数据,免费
下面我们就使用代码一步一步识别水平段的数据,首先打开matlab,并将工作路径切换到保存数据的文件夹下。

1. 加载数据并绘图

下面展示一些 。

load data.mat;% 加载数据
plot(data);  % 绘制图像
grid on;  % 打开网格
hold on;  % 保持绘图

然后会得到上面第一幅图

2. 初始化参数化

step = 50;  % 设置计算变化率的步长
len = length(data);  % 获取总的数据长度
j = 1;  % 初始化存放识别结果的角标
state = 0;  % 初始化识别状态,1表示识别水平段数据结束
mark = zeros(floor(len/step),2);  % 初始化存放识别结果的内存

3. 循环识别数据

下面展示一些。

% 从第一帧开始识别,间隔一个步长,为防止数组越界需要len-step
for i = 1:step:len-step  
    dif = (data(i+step)-data(i))/step;  % 计算每一个步长的变化率
    % 如果步长变化率绝对值小于阈值,且识别状态为0,认为进入水平段
    if(abs(dif)<0.005 && state == 0)  
        mark(j,1) = i+step;% 将数据位置存入
        state = 1;  % 将状态设为1,开始识别水平段的结束
    % 如果变化率大于阈值且识别状态为1,则认为识别到水平段结尾
    elseif(abs(dif)>0.01 && state == 1)
        mark(j,2) = i;
        j = j+1;
        state = 0;
    end
end
mark(j:end,:) = [];   % 删除未使用的内存

4. 绘制识别结果

y = [data(mark(:,1)),data(mark(:,2))];  % 根据角标将y值提取出来
for i = 1:length(x)  % 循环绘制线条
    line(mark(i,:),y(i,:),'Color','red','LineWidth',2);
end

其中蓝色为演示数据曲线,红色为识别到的水平段数据。
识别结果

5. 将识别到的水平段数据求取平均值并显示在曲线上

y = [data(mark(:,1)),data(mark(:,2))];
mark_mean = zeros(length(y),1);  % 初始化存放平均值的数组
for i = 1:length(y)
    mark_mean(i) = mean(data(mark(i,1):mark(i,2)));  % 求水平段的平均值
    line(mark(i,:),y(i,:),'Color','red','LineWidth',2);
    % 显示识别结果
    text(mark(i,1),y(i,1),num2str(mark_mean(i)),'VerticalAlignment','bottom');
end

6. 最终结果如下图所示

最终识别结果

将图片局部放大如下
局部放大图
最终结果还是十分满意的,希望对大家有所帮助。

最后附上全部源码

load data.mat;
plot(data,'b','LineWidth',2);
grid on;
hold on;
step = 30;
len = length(data);
j = 1;
state = 0;
mark = zeros(floor(len/step),2);
for i = 1:step:len-step
    dif = (data(i+step)-data(i))/step;
    if(abs(dif)<0.01 && state == 0)
        mark(j,1) = i;
        state = 1;
    elseif(abs(dif)>0.01 && state == 1)
        mark(j,2) = i;
        j = j+1;
        state = 0;
    end
end
mark(j:end,:) = []; 
y = [data(mark(:,1)),data(mark(:,2))];
mark_mean = zeros(length(y),1);
for i = 1:length(y)
    mark_mean(i) = mean(data(mark(i,1):mark(i,2)));
    line(mark(i,:),y(i,:),'Color','red','LineWidth',2);
    text(mark(i,1),y(i,1),num2str(mark_mean(i)),'VerticalAlignment','bottom');
end
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值