在我们阅读文献、进行学术或工程研究的过程中,常常遇到一个问题:如何将论文中他人绘制的曲线图复原成由具体数值构成的数据表?
这一问题,可能出现在多个场景中,比如当我们需要将自己的研究结果与他人所展示的结果进行对比时;比如我们的某部分工作需要以他人提供的数据为基础时。
一般而言,对于学术论文中的曲线图和数据、公司提供的产品手册、某些机构公开的实验数据,我们可以通过邮件的方式联系作者以及相关人员以向其咨询并获取详细的支撑数据;然而,这些邮件常常石沉大海、不得回音;或者需要辗转数周才能得到回复;这一方法,很可能会严重耽误我们的工作进度。
另一方面,我们知道,论文中提供的曲线数据图,虽然仅仅是图片,但实际已然包含了原函数关系中x坐标与y坐标间的一一对应关系。 这一对应关系与原始数据相比虽然可能会有一定的精度损失,但如若有效复原,亦可以满足我们的工作需求。
MATLAB是工科研究中常用的编程平台,亦可以方便地衔接图片和数据。针对上面这样一个问题,我们将以MATLAB语言为工具,通过两篇博客,讨论如何运用MATLAB来提取论文曲线图中的数据。
知己知彼方能百战不殆。在第一篇博客中,我们将首先对曲线图常见的类型进行讨论,并将数据曲线图分类为两大类进行处理。随后,在第一篇博客中,针对第一大类图片,提出其解决办法并分析展示对应的MATLAB程序。
在第二篇博客中,我们将对第二类(也更复杂)的数据曲线图进行分析,找出提取复原其中数据的方法,并展示对应的程序示例。
图像处理是一件复杂的工作,对于复杂的图像,我们往往需要引入复杂的滤波器、神经网络模型以及算法对其进行处理与识别。但对于论文中的曲线图,我们却并不希望因为数据提取而产生过多的复杂度。
一般的,这些数据图往往可以分为几类,针对不同类型的图片使用不同的方法,将会更有效率。
下图展示了某型号卫星推力器在不同工况下测量得到的推力值变化曲线。如下图可以看到,在很多情况下,实验测量得到的自变量-因变量对应关系,仅仅需要稀疏的数个点既可进行描绘。对这样的曲线图进行数据提取,也是相对直接而简单的。
图1-1 数据点较少的曲线图示例:卫星推力器的工作性能 |
---|
下图展示了一种材料经实验测量得到的单轴拉伸-应力曲线,这可以视作变化趋势连续平缓的曲线图的代表。
一般来说,这类曲线往往由实验得到的数据绘制而成,而不具有精确的解析表达式。因此,在数据提取和复原的过程中,我们往往也只需要保证从图片中提取的数值对应关系满足数量和精度要求即可。
图1-2 变化趋势平缓的单曲线图示例:单轴拉伸-应力曲线 |
---|
对于计算机学科、电子科学学科以及相近学科的数据曲线图,由于涉及到大量随机变量的掺杂干扰,曲线图的变化趋势有可能非常复杂甚至是不连续的。例如下图所示的使用强化学习方法训练得到的倒立摆控制器的控制力随时间变化的曲线。
对于这样的曲线,必定要求选择尽可能多的点进行尽可能高精度的数据提取,以实现更好的数据提取。
图1-3 复杂曲线示例:强化学习控制器 |
---|
当然,一张图片内也不总是只包含一条曲线。一般的,这些曲线会使用不同的颜色进行区分,偶尔也会使用线形区分。即如下图所示的这样一幅强化学习训练过程图。
图1-4 复杂多色曲线示例:强化学习的训练过程 |
---|
使用线形区分的曲线图往往由数个离散的点连接而成,这样的曲线图数据量不大,基本可以视同为第i类曲线图。
使用颜色区分的曲线图则可以分解为RGB三张灰度图,进而转变为第iii类图片进行处理。
偶尔,很不幸,也会有一些图片同时包含了多条同色同样式的曲线。例如下面这张BASF工业提供的Elastollan聚氨酯材料的拉伸-应力关系图(链接:https://plastics-rubber.basf.com/global/en/performance_polymers/products/elastollan.html):在同一张图片中,包含了不同温度下测量得到的拉伸-应力关系图,且每一条曲线的颜色和样式都是相同的。
图1-5 包含多条同色曲线的曲线图:Elastollan拉设-应力关系图 |
---|
所幸,像如上的这类图片,其自变量-应变量关系一定是相对简介明了的,否则,绘图者绘制出的,必然是一幅自相干扰、表达不清的无效图片。因此,对于这样一类图片,我们亦可以视作第ii类图片进行处理。
讨论完上述图片的分类,我们就可以进一步针对不同类别的图片进行不同的处理。根据我们上面的讨论,对于第i,ii,v类图片,由于仅仅需要提取一定数量的数据点既可以实现数据的复原,我们可以采用编程相对简单的手动数据点提取方法进行数据复原;而对于第iii和第iv类图片,由于完整的数据复原需要提取数量足够多的数据点(一般是上百个点),我们则需要考虑更为复杂、更自动化的方法。接下来,我们将就上述两大类数据图,使用不同的方法进行数据提取。
对于第i,ii,v类曲线图,一般的,我们只需要在图片中提取一定数量的数据点便可以满足复原数据的要求。这样,我们便可以采用MATLAB中的ginput()函数实现图像数据的手动提取。
图片中展示的应变量-自变量对应关系,可以看作原数据应变量-自变量对应关系的一种线性变换,因此,我们可以以图片中的坐标轴作为参考,实现反向的线性变化以得到原有的应变量-自变量关系。
我们以图5所示的单轴拉伸-应力曲线图为基础展示手动提取简单曲线图数据的过程:
首先,我们使用ginput()函数确定坐标轴基准的图中位置,这里,为了提高定位精度,我们分别取坐标轴的左下、左上、右下、右上四点,计算坐标轴上下界的平均值,如图6;同时在程序中输入坐标轴的真实长度;以获得线性变换的参照关系。值得注意的是,此处我们所取的x坐标轴的上界并非曲线图的右边界,而是坐标轴中有数值标注的最大点,由此,才可以实现更精确的定量变换。
图2-1 坐标轴的提取 |
---|
随后,我们再次使用ginput()函数在图像中对曲线选点,以实现目标曲线图中坐标的提取,在提取完所需的数据点后,敲击Enter键以完成提取;最后,应用线性变换,获得曲线图所表征的原数据。
具体的代码如下所示:
clear all;
i=imread('Elastollan 1185 A.PNG'); %读取需要提取数据的图片
imshow(i,'InitialMagnification',80); %显示读取的图片,并设置显示比例
%提取坐标轴
[x_ax,y_ax] = ginput; %使用ginput函数实现坐标轴4端点(左下、左上、右下、右上)的图上坐标提取,在图窗上依次点击4端点,并按回车完成提取
x_ax=sort(x_ax); %使用sort函数对提取的4个x坐标进行排序,从而区分x轴的起点与x轴的终点,前两个数据为x轴的起点,后两个数据为x轴的终点
y_ax=sort(y_ax); %同上
Lx_pic=mean(x_ax(3:4)-x_ax(1:2)); %计算图像中的X轴长度;
Ly_pic=mean(y_ax(3:4)-y_ax(1:2)); %计算图像中的Y轴长度;
Lx_real=1000; %X轴真实坐标长度;
Ly_real=80; %Y轴真实坐标长度;
%提取数据
[x_data,y_data] = ginput; %使用ginput函数在目标曲线上取点,获取曲线上点的图上坐标;
x_real=(x_data-min(x_ax))*Lx_real/Lx_pic; %以坐标轴的图上坐标-真实坐标比例关系为基准获得数据的真实坐标x;
y_real=(max(y_ax)-y_data)*Ly_real/Ly_pic; %以坐标轴的图上坐标-真实坐标比例关系为基准获得数据的真实坐标y;
%对提取数据重绘图
plot(x_real,y_real);
axis([0,Lx_real,0,Ly_real]);
%保存提取的数据
save('Elastollan 1175 AW.mat');
图2-2 复原得到的曲线图 |
---|
上述方法的优势在于,由于曲线图中数据点的选取均为人工识别得到的,因此,这一方法可以处理几乎所有形式的曲线图,并有着良好的精度。但另一方面,这一方法也需要人花费大量的时间选点,因此并不能以较快的速度获得变化规律复杂的曲线以及多条曲线中的原数据。
也因此,对于如图1-3所示的更为复杂的待处理图片,需要编写一个更为完整的程序来进行快速准确的数据复原。