在工作和生活中,经常会有这样的需求,将测试过程中得到的数据进行记录。手动的点击识别效率会非常慢。最近自己写了一个自动识别数据水平段的值并记录的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