曾宪武 发表于 2015-12-21 09:44

数值分析——图像还原

求用数值分析中的礼盒曲线还原图像的程序

Pseudo-lover 发表于 2015-12-21 14:58

礼盒曲线曲线是什么意思?

Matlab提供了强大的函数集合,可以从.fig文件中读取图中的数据,并重新绘制图形。如果原始数据丢失,我们可以从.fig文件中恢复原始数据,并基于原始数据做进一步的处理。

以下是一个从两个不同文件中读取原始数据,并重新绘制图形的例子。

h1 = openfig('1.fig','reuse'); % open figure
D1=get(gca,'Children'); %get the handle of the line object
XData1=get(D1,'XData'); %get the x data
YData1=get(D1,'YData'); %get the y data
Data1=; %join the x and y data on one array nx2

h2 = openfig('2.fig','reuse'); % open figure
D2=get(gca,'Children'); %get the handle of the line object
XData2=get(D2,'XData'); %get the x data
YData2=get(D2,'YData'); %get the y data
Data2=; %join the x and y data on one array nx2

figure;
plot( XData1{1}, YData1{3}, 'r-o', XData1{1}, YData1{2}, 'r--^', XData1{1}, YData1{1},'r-d', XData1{1}, YData2{3}, 'b-o', XData1{1}, YData2{2}, 'b--^', XData1{1}, YData2{1},'b-d','linewidth',1.5,'markersize',8);
legend('a','b','c','d','e','f');
xlabel('Number','fontsize',12);
ylabel('overhead','fontsize',12);
title('number and overhead')

Pseudo-lover 发表于 2015-12-21 15:08

以下转自平常心的博客:

前一段时间看到一篇文章"利用Matlab提取图图片中的数据",觉得思路挺好,遂下载下来研究了一番,发现作者所编写的程序没有考虑原始图片非水平放置的情况,而实际扫描图片时,将图片完全放置水平难度较大... 同时作者也没有考虑对数坐标的情况,且程序GUI界面不太人性化,操作有点不习惯。因此借着作者良好意愿,对其程序进行了改进~

考虑一张非水平无变形的曲线图,现将其曲线数据取出来,步骤如下:


[*]在坐标轴上取三点以定位坐标系。如图中红色点所示。
[*]在曲线上选取若干个点,如图中蓝色点所示。
[*]设定坐标轴选取点x和y的实际值。
[*]选取坐标系类型。
[*]变换。
[*]保存数据。
[*]数据后处理。


在变换过程中程序首先计算(xi,yi)到(x1,y1)和(x2,y2)所组成的y轴的距离Δx,同样的方法计算Δy,当然Δx和Δy是图片的像素值。接下来计算每个像素点所对应实际坐标值。对于线性x轴,比例系数为(Xmax-Xmin)/(sqrt((x1-x0)^2)+(y1-y0)^2),同样对于线性y轴,比例系数(Ymax-Ymin)/(sqrt((x0-x2)^2)+(y0-y2)^2)。这样即可求出每个点的实际坐标值
Xi=Δx *(Xmax-Xmin)/(sqrt((x1-x0)^2)+(y1-y0)^2)+Xmin
Yi=Δy *(Ymax-Ymin)/(sqrt((x0-x2)^2)+(y0-y2)^2)+Ymin
对数坐标的变换关系类似
Xi=10^(log10(Xmin)+Δx *(log10(Xmax)-log10(Xmin))/(sqrt((x1-x0)^2)+(y1-y0)^2))
Yi= 10^(log10(Ymin)+Δy *(log10(Ymax)-log10(Ymin))/(sqrt((x0-x2)^2)+(y0-y2)^2))

具体操作说明
1.导入图片。

2.定位坐标系。按del键可删除上一个点

3.定位曲线。

4.设置变换参数。

5.变换。单击[变换]按钮后,弹出变换后的结果。

6.保存数据。

7.数据后处理
导入数据,假定导入后变量名为test

在Matlab Command窗口中输入 x=test(:,1);y=test(:,2); cftool;弹出曲线拟合工具箱

创建数据集

拟合数据

程序流程

数据初始化程序段:
handles.optMode='zoom';
handles.linedata=[];
handles.dataCount=0;
handles.datah=[];
handles.axesdata=[];
handles.axesCount=0;
handles.axesh=[];
handles.newdata=[];
himage=findobj('tag','axes1');
axes(himage);

选定图片程序段:
=uigetfile({'*.jpg','图片文件(*.jpg)';'*.*','所有文件'},'请选择待分析图片...');
if ~isequal(file, 0)
cd(path);
set(handles.fileEdit,'String',);
end
导入图像程序段:
handles.dataCount=0;
handles.axesCount=0;

image_temp=imread(get(handles.fileEdit,'string'));
imshow(image_temp); %read and show
handles.ximage=size(image_temp,2);
handles.yimage=size(image_temp,1);
guidata(hObject,handles);
% 更新状态栏
h=findobj('tag','edit7');
set(h,'String',num2str(handles.dataCount));
ZoomPB_Callback(hObject, eventdata, handles);
点选取程序段:
p=get(gca,'CurrentPoint');
switch handles.optMode
case ('pickdata')
if p(end,1)>0&&p(end,1)<handles.ximage&&p(end,2)>0&&p(end,2)<handles.yimage
handles.dataCount=handles.dataCount+1;
handles.linedata(handles.dataCount,:)=p(end,1:2);
set(handles.countEdit,'String',num2str(handles.dataCount));
hold on;
handles.datah(handles.dataCount,1)=plot(p(end,1),p(end,2),'b*');
guidata(hObject, handles);
end
case ('pickaxes')
if p(end,1)>0&&p(end,1)<handles.ximage&&p(end,2)>0&&p(end,2)<handles.yimage&&handles.axesCount<3
handles.axesCount=handles.axesCount+1;
handles.axesdata(handles.axesCount,:)=p(end,1:2);
set(handles.countEdit,'String',num2str(handles.axesCount));
hold on;
handles.axesh(handles.axesCount,1)=plot(p(end,1),p(end,2),'r+');
guidata(hObject, handles);
end
end
点删除程序段:
switch get(gcf,'CurrentKey')
case('space')
PickDataPB_Callback(hObject, eventdata, handles);
case('z')
ZoomPB_Callback(hObject, eventdata, handles);
case('m')
PanPB_Callback(hObject, eventdata, handles);
case('delete')
switch handles.optMode
case ('pickdata')
if(handles.dataCount>0)
delete(handles.datah(handles.dataCount,1));
handles.dataCount=handles.dataCount-1;
set(handles.countEdit,'String',num2str(handles.dataCount));
guidata(hObject, handles);
end
case ('pickaxes')
if(handles.axesCount>0)
delete(handles.axesh(handles.axesCount,1));
handles.axesCount=handles.axesCount-1;
set(handles.countEdit,'String',num2str(handles.axesCount));
guidata(hObject, handles);
end
end
end
坐标轴定标及坐标变换:
%提取坐标信息

xmin=str2double(get(handles.xminEdit,'string'));
xmax=str2double(get(handles.xmaxEdit,'string'));
ymin=str2double(get(handles.yminEdit,'string'));
ymax=str2double(get(handles.ymaxEdit,'string'));

xType=get(handles.xTypePM,'value');
yType=get(handles.yTypePM,'value');
%数据分类整理
tmpaxes=handles.axesdata;
ct=6;
=max(tmpaxes(:,1));
axesxP=tmpaxes(r,:);
ct=ct-r;
=min(tmpaxes(:,2));
axesyP=tmpaxes(r,:);
ct=ct-r;
originP=handles.axesdata(ct,:);
Data=zeros(handles.dataCount,2);
data_new=zeros(handles.dataCount,2);
%起点归零和坐标调整
for i=1:handles.dataCount
Data(i,2)=det()/norm(originP-axesxP);
Data(i,1)=-det()/norm(originP-axesyP);
end
switch xType
case 1
data_new(:,1)=Data(:,1)/pdist(); %坐标归一化
data_new(:,1)=xmin+data_new(:,1)*(xmax-xmin); %数据还原
case 2
data_new(:,1)=Data(:,1)/pdist(); %坐标归一化
data_new(:,1)=10.^(log10(xmin)+data_new(:,1)*(log10(xmax)-log10(xmin)));
end
switch yType
case 1
data_new(:,2)=Data(:,2)/pdist();
data_new(:,2)=ymin+data_new(:,2)*(ymax-ymin);
case 2'
data_new(:,2)=Data(:,2)/pdist(); %坐标归一化
data_new(:,2)=10.^(log10(ymin)+data_new(:,2)*(log10(ymax)-log10(ymin))); %数据还原
end
figure(3);
if xType==2
if yType==2
loglog(data_new(:,1),data_new(:,2),'b*');
else
semilogx(data_new(:,1),data_new(:,2),'b*');
end
else
if yType==2
semilogy(data_new(:,1),data_new(:,2),'b*');
else
plot(data_new(:,1),data_new(:,2),'b*');
end
end
handles.newdata=data_new;
guidata(hObject,handles);
数据保存代码段:
=uiputfile({'*.txt','文本文件(*.txt)';'*.*','所有文件'},'请选择待分析图片...');
if ~isequal(file, 0)
idata=handles.newdata;
save(,'idata','-ascii');
end
页: [1]
查看完整版本: 数值分析——图像还原