声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 1657|回复: 2

[编程技巧] 数值分析——图像还原

[复制链接]
发表于 2015-12-21 09:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
求用数值分析中的礼盒曲线还原图像的程序
回复
分享到:

使用道具 举报

发表于 2015-12-21 14:58 | 显示全部楼层
礼盒曲线曲线是什么意思?

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

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

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

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

  11. figure;
  12. 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);
  13. legend('a','b','c','d','e','f');
  14. xlabel('Number','fontsize',12);
  15. ylabel('overhead','fontsize',12);
  16. title('number and overhead')
复制代码
发表于 2015-12-21 15:08 | 显示全部楼层
以下转自平常心的博客:

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

考虑一张非水平无变形的曲线图,现将其曲线数据取出来,步骤如下:
001.jpg
  • 在坐标轴上取三点以定位坐标系。如图中红色点所示。
  • 在曲线上选取若干个点,如图中蓝色点所示。
  • 设定坐标轴选取点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.导入图片。
002.jpg
2.定位坐标系。按del键可删除上一个点
003.jpg
3.定位曲线。
004.jpg
4.设置变换参数。
005.jpg
5.变换。单击[变换]按钮后,弹出变换后的结果。
006.jpg
6.保存数据。
007.jpg
7.数据后处理
导入数据,假定导入后变量名为test
008.jpg
在Matlab Command窗口中输入 x=test(:,1);y=test(:,2); cftool;弹出曲线拟合工具箱
009.jpg
创建数据集
010.jpg
拟合数据
011.jpg
程序流程
012.jpg
数据初始化程序段:
  1. handles.optMode='zoom';
  2. handles.linedata=[];
  3. handles.dataCount=0;
  4. handles.datah=[];
  5. handles.axesdata=[];
  6. handles.axesCount=0;
  7. handles.axesh=[];
  8. handles.newdata=[];
  9. himage=findobj('tag','axes1');
  10. axes(himage);
复制代码

选定图片程序段:
  1. [file,path]=uigetfile({'*.jpg','图片文件(*.jpg)';'*.*','所有文件'},'请选择待分析图片...');
  2. if ~isequal(file, 0)
  3. cd(path);
  4. set(handles.fileEdit,'String',[path file]);
  5. end
复制代码

导入图像程序段:
  1. handles.dataCount=0;
  2. handles.axesCount=0;

  3. image_temp=imread(get(handles.fileEdit,'string'));
  4. imshow(image_temp); %read and show
  5. handles.ximage=size(image_temp,2);
  6. handles.yimage=size(image_temp,1);
  7. guidata(hObject,handles);
  8. % 更新状态栏
  9. h=findobj('tag','edit7');
  10. set(h,'String',num2str(handles.dataCount));
  11. ZoomPB_Callback(hObject, eventdata, handles);
复制代码

点选取程序段:
  1. p=get(gca,'CurrentPoint');
  2. switch handles.optMode
  3. case ('pickdata')
  4. if p(end,1)>0&&p(end,1)<handles.ximage&&p(end,2)>0&&p(end,2)<handles.yimage
  5. handles.dataCount=handles.dataCount+1;
  6. handles.linedata(handles.dataCount,:)=p(end,1:2);
  7. set(handles.countEdit,'String',num2str(handles.dataCount));
  8. hold on;
  9. handles.datah(handles.dataCount,1)=plot(p(end,1),p(end,2),'b*');
  10. guidata(hObject, handles);
  11. end
  12. case ('pickaxes')
  13. if p(end,1)>0&&p(end,1)<handles.ximage&&p(end,2)>0&&p(end,2)<handles.yimage&&handles.axesCount<3
  14. handles.axesCount=handles.axesCount+1;
  15. handles.axesdata(handles.axesCount,:)=p(end,1:2);
  16. set(handles.countEdit,'String',num2str(handles.axesCount));
  17. hold on;
  18. handles.axesh(handles.axesCount,1)=plot(p(end,1),p(end,2),'r+');
  19. guidata(hObject, handles);
  20. end
  21. end
复制代码

点删除程序段:
  1. switch get(gcf,'CurrentKey')
  2. case('space')
  3. PickDataPB_Callback(hObject, eventdata, handles);
  4. case('z')
  5. ZoomPB_Callback(hObject, eventdata, handles);
  6. case('m')
  7. PanPB_Callback(hObject, eventdata, handles);
  8. case('delete')
  9. switch handles.optMode
  10. case ('pickdata')
  11. if(handles.dataCount>0)
  12. delete(handles.datah(handles.dataCount,1));
  13. handles.dataCount=handles.dataCount-1;
  14. set(handles.countEdit,'String',num2str(handles.dataCount));
  15. guidata(hObject, handles);
  16. end
  17. case ('pickaxes')
  18. if(handles.axesCount>0)
  19. delete(handles.axesh(handles.axesCount,1));
  20. handles.axesCount=handles.axesCount-1;
  21. set(handles.countEdit,'String',num2str(handles.axesCount));
  22. guidata(hObject, handles);
  23. end
  24. end
  25. end
复制代码

坐标轴定标及坐标变换:
  1. %提取坐标信息

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

  6. xType=get(handles.xTypePM,'value');
  7. yType=get(handles.yTypePM,'value');
  8. %数据分类整理
  9. tmpaxes=handles.axesdata;
  10. ct=6;
  11. [c,r]=max(tmpaxes(:,1));
  12. axesxP=tmpaxes(r,:);
  13. ct=ct-r;
  14. [c,r]=min(tmpaxes(:,2));
  15. axesyP=tmpaxes(r,:);
  16. ct=ct-r;
  17. originP=handles.axesdata(ct,:);
  18. Data=zeros(handles.dataCount,2);
  19. data_new=zeros(handles.dataCount,2);
  20. %起点归零和坐标调整
  21. for i=1:handles.dataCount
  22. Data(i,2)=det([originP-axesxP;handles.linedata(i,:)-axesxP])/norm(originP-axesxP);
  23. Data(i,1)=-det([originP-axesyP;handles.linedata(i,:)-axesyP])/norm(originP-axesyP);
  24. end
  25. switch xType
  26. case 1
  27. data_new(:,1)=Data(:,1)/pdist([originP;axesxP]); %坐标归一化
  28. data_new(:,1)=xmin+data_new(:,1)*(xmax-xmin); %数据还原
  29. case 2
  30. data_new(:,1)=Data(:,1)/pdist([originP;axesxP]); %坐标归一化
  31. data_new(:,1)=10.^(log10(xmin)+data_new(:,1)*(log10(xmax)-log10(xmin)));
  32. end
  33. switch yType
  34. case 1
  35. data_new(:,2)=Data(:,2)/pdist([originP;axesyP]);
  36. data_new(:,2)=ymin+data_new(:,2)*(ymax-ymin);
  37. case 2'
  38. data_new(:,2)=Data(:,2)/pdist([originP;axesyP]); %坐标归一化
  39. data_new(:,2)=10.^(log10(ymin)+data_new(:,2)*(log10(ymax)-log10(ymin))); %数据还原
  40. end
  41. figure(3);
  42. if xType==2
  43. if yType==2
  44. loglog(data_new(:,1),data_new(:,2),'b*');
  45. else
  46. semilogx(data_new(:,1),data_new(:,2),'b*');
  47. end
  48. else
  49. if yType==2
  50. semilogy(data_new(:,1),data_new(:,2),'b*');
  51. else
  52. plot(data_new(:,1),data_new(:,2),'b*');
  53. end
  54. end
  55. handles.newdata=data_new;
  56. guidata(hObject,handles);
复制代码

数据保存代码段:
  1. [file,path]=uiputfile({'*.txt','文本文件(*.txt)';'*.*','所有文件'},'请选择待分析图片...');
  2. if ~isequal(file, 0)
  3. idata=handles.newdata;
  4. save([path file],'idata','-ascii');
  5. end
复制代码
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-9-20 14:30 , Processed in 0.072898 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表