目录

  • 0.引言
  • 1.思路详解与分析
  • 2.MATLAB程序

0.引言

  在读文献的时,经常遇到这样的情况:文章里提出的方法好有趣啊,好想拿文中用的数据来试试看看能不能得到相近的结果,可是文中只有根据原始数据绘制的曲线图,没有数据。如下图所示。

  此时,如果能从文中把这幅图截取下来,输入到一个函数中去,最后能返回从图片中提取到的曲线的坐标数据,岂不美哉。这便是本文的工作。

1.思路详解与分析

1.1准备待提取数据的曲线图片

将待提取数据的曲线的图片(如.jpg格式图片),利用 imread 输入到 matlab 中。

1.2曲线图片预处理与数据转换

曲线图片预处理步骤的主要工作包含如下:

(1)图像二值化

将输入图像进行二值化处理,但分割得到的结果并不全为数据,其中可能还包括坐标轴等干扰点需要去除。

(2)获取从图片像素到曲线坐标的定标数据

首先,通过ginput()手动从图片中提取到两个像素点,这两个点分别为曲线坐标框的左上角和右下角。

此时,便获得了曲线在图片上的像素范围

[x_index_min, x_index_max] & [y_index_min, y_index_max]

然后,手动输入实际曲线的数据坐标范围 [x_min, x_max] & [ymin, y_max_]. 如下所示。

此时,一方面得到了像素坐标,一方面得到了实际坐标。接下来便利用这对数据,将图片中全部的像素坐标转换到实际坐标。

最终,得到了由图片提取到的数据散点图,如下:

可以看到,此时得到的结果,虽然曲线与所需要的相近,但曲线外的部分,如坐标轴框、坐标轴刻度等也被转换成了数据,还需要进一步的处理。

1.3数据的进一步处理并得到最终曲线

这一步的主要工作是在数据中除去曲线之外的部分(包括坐标轴框、坐标轴刻度等);以及解决一个x数据对应多个y数据的情况。

显然,坐标轴在整幅数据中,均处于边界位置,因此,很容易想到的一种方法是,设定阈值,将距离边界较近的数据直接删除。这里,设定了两个阈值,一个用来限定x方向上的数据,一个用来限定y方向上的数据。比如设定:rate_x=0.08; rate_y=0.05; 意思是阈值设定为曲线最前端8%和最后段8%的数据,曲线最顶端5%和最底端5%的数据。

进一步的,对于提取到的数据图,大多数情况一个x会对应若干y,因为数据是由图片转化而来,而图片的分辨率有限,一个实际数据点会用多个像素来表示。解决此问题的中心思想是将同一个x对应的若干个y取均值,但不能直接求均值,因为还有很多y是噪声(如坐标轴线、由图片噪声带入的干扰点等)需要先去除,在第一个问题中,通过限定y的范围,已经在一定程度上除去了部分干扰,在此基础上,我们求取一个x对应的这组y值的均值mean与标准差std,当某些y值位于[mean-std , mean+std]之外,则认为这些y值波动太大,将它们删去。

到这里,我们就将数据的处理部分基本完成了,我们将处理后的数据再次绘制成曲线,便可以得到如下

对比处理之前的数据,由于限定了范围,因此曲线图片中带来的坐标框等内容转化而来的数据已经被删去。

将需要提取坐标的曲线图片,和我们提取并处理后的数据绘制的曲线,放在一起对比如下:

可以看到,与原曲线图片相比,提取到的数据曲线相似度能达到较高要求。但进一步观察会发现,右图曲线较左图而言,高频分量有一定的减少(即右图曲线更平滑),原因在于数据处理时,对同一个x对应的这组y值进行了均值处理,则在图像上近似反应为均值滤波,从而使得提取到的数据绘制成的曲线的高频分量被滤除。

最后,将提取到的最终数据,保存起来如下:

1.4进一步的讨论——曲线拟合

通过对图片中曲线的数据提取,可以得到数值上的答案,这会带来进一步的思考,即能否得到这些数据的解析表达式。很容易想到,利用最小二乘法来拟合这些数据,这便涉及到了曲线的拟合。(插值与拟合可以这么理解:对于数据点集,若均落在曲线上,则该曲线为插值曲线,否则为拟合曲线)

对于一些简单的曲线图片(如下),可以考虑用泰勒级数来近似,即多项式拟合。

数据提取并拟合的结果展示如下

同时还能得到拟合多项式的系数

从而得到该曲线的多项式(这里采用四阶多项式)表达式为:

理论上,泰勒级数可以分解任何函数,但实际上,多项式拟合的次数太高,会出现龙格库塔现象,即摆尾现象。因此,多项式拟合的阶数不易过高,一般低于5阶。对于本文最开始的那幅曲线而言,仅5阶的泰勒级数就显得力不从心了,因此,对于这种存在波动剧烈的函数,可以考虑用傅里叶级数进行拟合,或者如果能提供先验知识,可以直接用先验表达式进行拟合。

在MATLAB中,提供了cftool工具箱,其提供了拟合与插值的GUI,使用非常方便,直接在命令窗输入cftool即可调用,cftool界面如下所示,其具体使用方法不在此赘述。

2.MATLAB程序

MATLAB源代码如下所示,和以往的风格一样,提供了详细的注释

% //提取图片中的曲线数据
clear,clc,close all
%% //图片与曲线间的定标
im=imread('tu1.jpg'); %//读入图片(替换成需要提取曲线的图片)
im=rgb2gray(im); %//灰度变化
thresh = graythresh(im); %//二值化阈值
im=im2bw(im,thresh); %//二值化
set(0,'defaultfigurecolor','w')
imshow(im) %//显示图片
[y,x]=find(im==0); %//找出图形中的“黑点”的坐标。该坐标是一维数据。
y=max(y)-y; %//将屏幕坐标转换为右手系笛卡尔坐标
y=fliplr(y); %//fliplr()——左右翻转数组
plot(x,y,'r.','Markersize', 2);
disp('请在Figrure中先后点击实际坐标框的两个顶点(左上点和右下点),即A、B两点. ');
[Xx,Yy]=ginput(2); %//Xx,Yy——指实际坐标框的两个顶点
min_x=input('最小的x值');  %//输入x轴最小值
max_x=input('最大的x值');  %//输入x轴最大值
min_y=input('最小的y值');  %//输入y轴最小值
max_y=input('最大的y值');  %//输入y轴最大值
x=(x-Xx(1))*(max_x-min_x)/(Xx(2)-Xx(1))+min_x;
y=(y-Yy(1))*(min_y-max_y)/(Yy(2)-Yy(1))+max_y;
plot(x,y,'r.','Markersize', 2);
axis([min_x,max_x,min_y,max_y])  %//根据输入设置坐标范围
title('由原图片得到的未处理散点图')
%% //将散点转换为可用的曲线
%//需处理的问题与解决思路
%//(1)散点图中可能一个x对应好几个y <---> 保留mean()-std()到mean()+std()之间的y值 并取平均处理
%//(2)曲线的最前端和最后段干扰较大 <---> 去掉曲线整体的前(如5%)和后5%
%//(3)曲线的最顶端和最底段干扰较大 <---> 去掉曲线整体的上10%和下10%%//参数预设
rate_x=0.08;  %//曲线的最前端和最后段删除比例
rate_y=0.05;  %//曲线的最顶端和最底段删除比例[x_uni,index_x_uni]=unique(x);  %//找出有多少个不同的x坐标x_uni(1:floor(length(x_uni)*rate_x))=[];  %//除去前rate_x(如5%)的x坐标
x_uni(floor(length(x_uni)*(1-rate_x)):end)=[];  %//除去后rate_x的x坐标
index_x_uni(1:floor(length(index_x_uni)*rate_x))=[];  %//除去前rate_x的x坐标
index_x_uni(floor(length(index_x_uni)*(1-rate_x)):end)=[];  %//除去后rate_x的x坐标[mxu,~]=size(x_uni);
[mx,~]=size(x);
for ii=1:mxuif ii==mxuytemp=y(index_x_uni(ii):mx);elseytemp=y(index_x_uni(ii):index_x_uni(ii+1));end% //删除方差过大的异常点threshold1=mean(ytemp)-std(ytemp);threshold2=mean(ytemp)+std(ytemp);ytemp(find(ytemp<threshold1))=[];  %//删除同一个x对应的一段y中的异常点ytemp(find(ytemp>threshold2))=[];% //删除距顶端和底端较近的点thresholdy=(max_y-min_y)*rate_y;  %//y坐标向阈值ytemp(find(ytemp>max_y-thresholdy))=[];  %//删除y轴向距离顶端与底端距离小于rate_y的坐标ytemp(find(ytemp<min_y+thresholdy))=[];% //剩下的y求均值y_uni(ii)=mean(ytemp);
end
% //此时很多x_uni点处对应的y_uni为空,即NAN,要进一步删去这些空点
x_uni(find(isnan(y_uni)))=[];
y_uni(find(isnan(y_uni)))=[];
% //画图
figure,plot(x_uni,y_uni),title('经处理后得到的扫描曲线')
axis([min_x,max_x,min_y,max_y])  %//根据输入设置坐标范围
% //将最终提取到的x与y数据保存
curve_val(1,:)=x_uni';
curve_val(2,:)=y_uni;
%% //对提取出的数据进行拟合(按实际情况进行修改)
[p,s]=polyfit(curve_val(1,:),curve_val(2,:),4);  %//多项式拟合(为避免龙格库塔,多项式拟合阶数不宜太高)
[y_fit,DELTA]=polyval(p,x_uni,s);  %//求拟合后多项式在x_uni对应的y_fit值
figure,plot(x_uni,y_fit),title('拟合后的曲线')
axis([min_x,max_x,min_y,max_y])  %//根据输入设置坐标范围

转自知乎专栏

利用matlab从图片中提取曲线坐标数据相关推荐

  1. matlab中根据表格数据画图,excel 表格数据画图-如何利用matlab根据excel表格里面的数据画图...

    在matlab上如何导入excel表格然后画图 "在excel中由数据画图,且显示图线的函数"的操作步骤是: 1.以Excel 2016为例,打开Excel工作表: 2.选择数据区 ...

  2. matlab读Excel表格数据画图,matlab读Excel表格数据画图-如何利用matlab根据excel表格里面的数据画图...

    用matlab读取excel数据并把对应的数据分别画出曲线图 1.第我们首先需要找到需要导excel表格,这里表格需要是office,其它入有问题,我们可以使用电脑自带的2003版本office 2. ...

  3. matlab中根据表格数据画图,excel表格中数据作图-如何利用matlab根据excel表格里面的数据画图...

    如何用excel表格中的数据制图 方法/步骤 1,在excel中输入制图表所需要的数据. 2,选择数据(选择不连续的数据可以按住"ctrl"在选择就可以了.还有选择时要连表头一起选 ...

  4. matlab表格中的数画图,excel数据表格画图-如何利用matlab根据excel表格里面的数据画图...

    如何利用matlab根据excel表格里面的数据画图 方法/步骤 1,在excel中输入制图表所需要的数据. 2,选择数据(选择不连续的数据可以按住"ctrl"在选择就可以了.还有 ...

  5. opencv获取图片像素坐标_利用OpenCV从图片中提取矩形并标注坐标(室内平面地图)(一)

    ​某城市会展中心室内地图 背景 一名室内设计师的日常工作从设计一张会展地图开始.常常有这样的场景:划分除规范的展位后,进入销售阶段,频繁的需要修改这张地图,如展示拆分.合并.换位置.标记已交易. 问题 ...

  6. vba 提取 json某个值_利用VBA字典,提取两列数据的重复值

    大家好,今日我们继续讲解VBA数组与字典解决方案,今日讲解第52讲:利用字典,提取两列数据重复值.有人讲:字典是VBA中最为精华的部分,持这种观点的人肯定有自己的道理,确实,利用字典可以给我的代码带来 ...

  7. 利用OpenCV从图片中提取矩形并标注坐标(室内平面地图)——(一)

    某城市会展中心室内地图 背景 一名室内设计师的日常工作从设计一张会展地图开始.常常有这样的场景:划分除规范的展位后,进入销售阶段,频繁的需要修改这张地图,如展示拆分.合并.换位置.标记已交易. 问题 ...

  8. 利用Matlab从图片中获取凸多边形的内角角度

    利用matlab中的ginput函数获取坐标,求该三点确定的三角形的边长,然后利用三边长求角度的公式 求出夹角,将角度在坐标后面标出来.想获取每个内角的角度的话可以对每一个角重复一次操作. 标注效果如 ...

  9. [GUI] 使用MATLAB从图片中提取曲线数据

    用MATLAB 2017b GUI写的一款小工具. 无论是课堂.会议上随手拍的照片,还是阅读文献的截图,很快可以提取到曲线的原始数据点作为学习研究的参考. 主要思路是: 1)预处理:裁剪选区.透视变换 ...

最新文章

  1. iOS :UIPickerView reloadAllComponets not work
  2. cookie、session以及token的定义、区别、使用环境
  3. win32 断言函数和转换到COFF期间失败错误
  4. 趣话题:底层码农的心酸,那么我们 如何避免成为底层码农呢?
  5. android通过webservice连接SQL数据库(二)客户端
  6. Redis windows学习(一)——redis安装和基础使用
  7. 【UML】使用环境(转)
  8. docker load tar.gz包失败解决方法
  9. Android Studio 开发JNI应用
  10. 51单片机中模拟IIC的代码编写
  11. CTFHub技能书解题笔记-信息泄露-备份文件下载-网站源码
  12. Netbean 打开报 Cannot locate java installation in specified jdkhome: ***错误
  13. Ubuntu 14.04安装 skype
  14. jQuery实现打字机效果
  15. 乐高太多没处放?解放女朋友双手,1 个顶 100 个的乐高智能分拣机来了!
  16. (glidejs)glidejs的使用
  17. 微信公众号视频录制开发 踩坑汇总
  18. 复习总结:马克思主义基本原理概论(马原)
  19. 在J2EE项目中集成快钱支付接口
  20. 如何实现用户id生成一个唯一邀请码

热门文章

  1. 了解js中什么是回调函数?
  2. 自己开店怎么选会员卡管理系统
  3. Apache Hadoop缓冲区溢出漏洞(CVE-2021-37404)
  4. 电力电子技术-整流电路1
  5. mysql 把所有行的id用逗号串连起来
  6. 字幕剪切视频神器AutoCut的安装和使用
  7. 自制USB充电接口,手机不显示充电状态的原因
  8. 用上 RNN,这个视频抠像工具效果绝了
  9. 视频智能分析系统EasyCVR视频流媒体安防监控云服务实现城市视频智能化应用
  10. Ebay买家号也会被封吗?