物理,计算机技术爱好者分享 http://blog.sciencenet.cn/u/guowei Guowei Zhao 等离子体,计算机,物理

博文

提取参考文献中图片(曲线)数据

已有 13680 次阅读 2008-1-16 23:41 |个人分类:学术教育

     在阅读国内外文献时,发现文章中有一张很有意义的图,很想得到它的原始数据,每个位置的数值到底是多少,这个想法基本上是每个人都有的.虽然我们可以得到电子版的文献,但是如何把数据提取出来,却没有一个很好的方法,只能估计或分析曲线趋势.

      在科研过程中,我也同样的碰到了这个问题.发现利用Matlab的图片处理函数,加上数据处理基本上可以很好的将数据提取出来,并将图形还原.

     过程其实也不复杂,但细节处理比较多.步骤为:

1)将文献中的图片,利用任意一种图片处理软件,从文章中复制出来,保存为图片文件.

2)在Matlab程序中,首先利用图形处理函数(如去噪等),将一些无用的杂点去掉,使图片看得干净些.

3)将图片数据转换成灰度或黑白数组,首先对坐标进行处理,确定曲线的起点和终点,通过阈值,去除XY坐标轴,因为这不是我们所需要的曲线.

4)对数据进行分析,一般认为曲线是连续的,处理后可以得到一条基本和原图一模一样的图片.

其中对数据处理的一些细节很多,简单来说有1)将图片转换成数组时,要合理的控制域值,太大太小都是不合适的.2)分析坐标轴时,最好将每个小间隔的信息也提取出来,这主要是考虑非均匀坐标系下的曲线.3)因为假定曲线是连续的,因此在查找下一个点时,是从前一个点的Y坐标开始找距离最小的值,如果没有,查找下一个,然后可以线性插值补上中间的值.4)如果点太多,可以取中间值来替代.5)如果有多条曲线,也是相同的处理,只不过在处理缺失点的时候要考虑一下。6)可以在程序中加入标准值,比如对特别模糊的区域,另外加入强制性的点来进行标定,有利于图形更加准确.

     这个原理,处理相对比较简单,但是很实用.篇幅所限,下面是部分源程序.

function [BW,Datay1,Datay2,Datax]=image2data(filename,BWLevel,GridLevelx,GridLevely,DataYstart,DataYstep,DataXstep)
filedata=imread(filename);
BW = im2bw(filedata,BWLevel);
imshow(BW);
filesize=size(BW);
Lx=filesize(2);%%%%%%%%%%%x
Ly=filesize(1);%%%%%%%%%%%%%%%%%y
%%%%%%%%%%%%%%%%%%%%找到XY坐标轴
Lxstart=0;%%%%%%%%%%%y开始的地方
Ldeltax=0;
Ldelta=0;
Ldeltai=1;
for Li=1:Lx
    temp=0;
    for Lj=1:Ly
        if BW(Lj,Li)==0
            temp=temp+1;
        end
    end
    if temp>Ly*GridLevely %%%%%%%%%%%%%%%表明是网格
        BW(1:Ly,Li)=1;%%%%%%%%%%%%grid off
        Ldelta(Ldeltai)=Li;
        Ldeltai=Ldeltai+1;
        %if Lxstart==0
        %    Lxstart=Li;
        %end
    end
end
Lxstart=1;
Lxstop=1;
for Li=1:temp
    if (BW(Lystep(Li),Ldelta(Lxstart)+1:Ldelta(Lxstart)+7)<4)%六个中有三个黑,则认为是标轴
        BW(Lystep(Li),Ldelta(Lxstart)+1:Ldelta(Lxstart)+7)=ones(1,7);
        if sum((BW(Lystep(Li),:)))>(1-GridLevelx)*Lx
        tfalse=0;
        ti=1;
        while(tfalse==0)
            if(BW(Lystep(Li),Ldelta(Lxstart)+7+ti)==0)
                BW(Lystep(Li),Ldelta(Lxstart)+7+ti)=1;
            else
                tfalse=1;
            end
            ti=ti+1;
        end
        end
    end
end
Lxstop=floor(mean(Ldelta(Lxstop:Ldeltai-1)));

Ldeltax=Ldelta(2)-Ldelta(1);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%去 网格
%%%%%%%%%%%%%%%%%去Y轴

filesize=size(BW);
Lx=filesize(2);%%%%%%%%%%%x
Ly=filesize(1);%%%%%%%%%%%%%%%%%y
imshow(BW);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Lynumber=0;
temp=0;
for Li=1:Lx
    if Li==361
        Li=361;
    end
    Datax(Li)=Li;
    number=find(BW(1:Ly,Li)==0);
    numbersize=size(number);
    Lynumber(Li)=numbersize(1);
    if numbersize(1)>0%%%%%%%%%%%%%%有数据
        if numbersize(1)<2%%%%%%%%%%%%%%%刚好有两个点
            if numbersize(1)==1
                Datay1(Li)=number(1);
               % Datay2(Li)=number(2);
               %else
               %%Datay1(Li)=number(1);
               %Datay2(Li)=0;
            end
        elseif numbersize(1)>1%%%%%%%%%%%%%%有很多点,就空
           
            temp1=0;
            %temp(1)=number(1);
            temp=number(1);
            Datay1(Li)=0;
%            Datay2(Li)=0;
            for LLi=2:numbersize(1)
                if (number(LLi)-number(LLi-1))<3   %%%%%%%%%表示这两个点很近,认为是一个点
                    temp(LLi-temp1)=number(LLi);
                else%%%%%%%%%%%%%%%%%%有离开的点
                    %%%%%%%%%%%%%%%%%%%取前两个点进行复制
            %        if Datay1(Li)==0&Datay2(Li)==0
            %            Datay1(Li)=floor(mean(temp));
            %        elseif Datay1(Li)>0&Datay2(Li)==0
           %             Datay2(Li)=floor(mean(temp));
           %         end
                    %%%%%%%%%%%%%%%%%%%%%%%%%%%
                    temp=number(LLi);
                    temp1=LLi-1;
                   

                end
            end
            %%%%%%%%%%%%%%%%%55无离开的点,
            if temp1==0
                Datay1(Li)=floor(mean(temp));
           %     Datay2(Li)=0;
            end
           % if Datay2(Li)==0&temp1>0
           %     Datay2(Li)=floor(mean(temp));
           % end
           
        end
    else  %%%%%%%%%%%%无数据
            Datay1(Li)=0;
            Datay2(Li)=0;
    end
if Datay1(Li)==0&Li>1
    Datay1(Li)=Datay1(Li-1);
end
%if Datay2(Li)==0&Li>1
%    Datay2(Li)=Datay2(Li-1);
%end
number;
Datay1(Li);
%Datay2(Li);
%figure(3);
%plot(Datay1);
end

 

%%%%将前面由于判断坐标去掉的点加上
temp=min(find(Datay1>0));
if temp>1
    Datay1(1:temp-1)=ones(1,temp-1)*Datay1(temp);
end



https://blog.sciencenet.cn/blog-29036-14572.html

上一篇:蒙特卡罗方法在等离子体密度分布中的应用
下一篇:对科研人员的编程要求
收藏 IP: .*| 热度|

0

发表评论 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-4-23 14:48

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部