source: trunk/src/geometry_calib.m @ 59

Last change on this file since 59 was 54, checked in by sommeria, 14 years ago

sub_background modified to accept various movie and image inputs
geometry_calib, editxml, civ modified to read a unique PARAM.xml parameter file (instead of PARAM_LINUX...)

File size: 39.4 KB
Line 
1%'geometry_calib': performs geometric calibration from a set of reference points
2%
3% function varargout = geometry_calib(varargin)
4%
5%A%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
6%  Copyright Joel Sommeria, 2008, LEGI / CNRS-UJF-INPG, sommeria@coriolis-legi.org.
7%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
8%     This file is part of the toolbox UVMAT.
9%
10%     UVMAT is free software; you can redistribute it and/or modify
11%     it under the terms of the GNU General Public License as published by
12%     the Free Software Foundation; either version 2 of the License, or
13%     (at your option) any later version.
14%
15%     UVMAT is distributed in the hope that it will be useful,
16%     but WITHOUT ANY WARRANTY; without even the implied warranty of
17%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18%     GNU General Public License (file UVMAT/COPYING.txt) for more details.
19%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
20
21function varargout = geometry_calib(varargin)
22% GEOMETRY_CALIB M-file for geometry_calib.fig
23%      GEOMETRY_CALIB, by itself, creates a MenuCoord GEOMETRY_CALIB or raises the existing
24%      singleton*.
25%
26%      H = GEOMETRY_CALIB returns the handle to a MenuCoord GEOMETRY_CALIB or the handle to
27%      the existing singleton*.
28%
29%      GEOMETRY_CALIB('CALLBACK',hObject,eventData,handles,...) calls the local
30%      function named CALLBACK in GEOMETRY_CALIB.M with the given input arguments.
31%
32%      GEOMETRY_CALIB('Property','Value',...) creates a MenuCoord GEOMETRY_CALIB or raises the
33%      existing singleton*.  Starting from the left, property value pairs are
34%      applied to the GUI before geometry_calib_OpeningFunction gets called.  An
35%      unrecognized property name or invalid value makes property application
36%      stop.  All inputs are passed to geometry_calib_OpeningFcn via varargin.
37%
38%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
39%      instance to run (singleton)".
40%
41% See also: GUIDE, GUIDATA, GUIHANDLES
42
43% Edit the above text to modify the response to help geometry_calib
44
45% Last Modified by GUIDE v2.5 05-Jan-2010 23:22:04
46
47% Begin initialization code - DO NOT edit
48gui_Singleton = 1;
49gui_State = struct('gui_Name',       mfilename, ...
50                   'gui_Singleton',  gui_Singleton, ...
51                   'gui_OpeningFcn', @geometry_calib_OpeningFcn, ...
52                   'gui_OutputFcn',  @geometry_calib_OutputFcn, ...
53                   'gui_LayoutFcn',  [] , ...
54                   'gui_Callback',   []);
55if nargin & isstr(varargin{1})
56    gui_State.gui_Callback = str2func(varargin{1});
57end
58
59if nargout
60    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
61else
62    gui_mainfcn(gui_State, varargin{:});
63end
64% End initialization code - DO NOT edit
65
66
67% --- Executes just before geometry_calib is made visible.
68%INPUT:
69%handles: handles of the geometry_calib interface elements
70% PlotHandles: set of handles of the elements contolling the plotting
71% parameters on the uvmat interface (obtained by 'get_plot_handle.m')
72function geometry_calib_OpeningFcn(hObject, eventdata, handles, handles_uvmat,pos,inputfile)
73
74% Choose default command line output for geometry_calib
75handles.output = hObject;
76
77% Update handles structure
78guidata(hObject, handles);
79movegui(hObject,'east');% position the GUI ton the right of the screen
80if exist('handles_uvmat','var') %& isfield(data,'ParentButton')
81     set(hObject,'DeleteFcn',{@closefcn,handles_uvmat})%
82end
83%set the position of the interface
84if exist('pos','var')& length(pos)>2
85    pos_gui=get(hObject,'Position');
86    pos_gui(1)=pos(1);
87    pos_gui(2)=pos(2);
88    set(hObject,'Position',pos_gui);
89end
90inputxml='';
91if exist('inputfile','var')& ~isempty(inputfile)
92    [Path,Name,ext]=fileparts(inputfile);
93    form=imformats(ext([2:end]));
94    if ~isempty(form)% if the input file is an image
95        struct.XmlInputfile=inputfile;
96        set(hObject,'UserData',struct)
97        [Pathsub,RootFile,field_count,str2,str_a,str_b,ext,nom_type,subdir]=name2display(inputfile);
98        inputxml=[fullfile(Pathsub,RootFile) '.xml'];
99    end   
100end
101set(handles.ListCoord,'String',{''})
102if exist(inputxml,'file')
103    loadfile(handles,inputxml)% load the point coordiantes existing in the xml file
104end
105
106set(handles.ListCoord,'KeyPressFcn',{@key_press_fcn,handles})%set keyboard action function
107%set(hObject,'KeyPressFcn',{'keyboard_callback',handles})%set keyboard action function on uvmat interface when geometry_calib is on top
108%htable=uitable(10,5)
109%set(htable,'ColumnNames',{'x','y','z','X(pixels)','Y(pixels)'})
110
111%------------------------------------------------------------------------
112% --- Outputs from this function are returned to the command line.
113function varargout = geometry_calib_OutputFcn(hObject, eventdata, handles)
114%------------------------------------------------------------------------
115% Get default command line output from handles structure
116varargout{1} = handles.output;
117varargout{2}=handles;
118
119%------------
120function Phi_Callback(hObject, eventdata, handles)
121
122%------------------------------------------------------------------------
123%read input xml file and update the edit boxes
124function loadfile(handles,fileinput)
125%------------------------------------------------------------------------
126%read the input xml file
127t=xmltree(fileinput);
128s=convert(t);%convert to matlab structure
129%read data currently displayed on the interface
130PointCoord=[];
131Coord_cell=get(handles.ListCoord,'String');
132data=read_geometry_calib(Coord_cell);
133%data=read_geometry_calib(handles);
134Coord=[]; %default
135if isfield(data,'Coord')
136    Coord=data.Coord;
137end
138TabChar_0=get(handles.ListCoord,'String');
139nbcoord_0=size(TabChar_0,1);
140if isequal(get(handles.edit_append,'Value'),2) %edit mode  A REVOIR
141    val=get(handles.ListCoord,'Value')-1;
142else
143   val=length(TabChar_0);
144end
145nbcoord=0;
146
147%case of calibration (ImaDoc) input file
148% hcalib=get(handles.calib_type,'parent');
149CalibData=get(handles.figure1,'UserData');
150CalibData.XmlInput=fileinput;
151if isfield(s,'Heading')
152    CalibData.Heading=s.Heading;
153end
154
155set(handles.figure1,'UserData',CalibData);%store the heading in the interface 'UserData'
156if isfield(s,'GeometryCalib')
157    Calib=s.GeometryCalib;
158    if isfield(Calib,'CalibrationType')
159        CalibrationType=Calib.CalibrationType;
160        switch CalibrationType
161            case 'linear'
162                set(handles.calib_type,'Value',2)
163            case 'tsai'
164                set(handles.calib_type,'Value',3)
165        end
166    end
167    if isfield(Calib,'SourceCalib')
168        if isfield(Calib.SourceCalib,'PointCoord')
169            PointCoord=Calib.SourceCalib.PointCoord;
170        end
171    end
172    nbcoord=length(PointCoord);
173    if ~isfield(Calib,'ErrorRms')&~isfield(Calib,'ErrorMax') %old convention of Gauthier (cord in mm)
174        for i=1:length(PointCoord)
175          line=str2num(PointCoord{i});
176          Coord(i+val,4:5)=line(4:5);%px x
177          Coord(i+val,1:3)=line(1:3)/10;%phys x
178        end
179    else
180        for i=1:length(PointCoord)
181          line=str2num(PointCoord{i});
182          Coord(i,4:5)=line(4:5);%px x
183          Coord(i,1:3)=line(1:3);%phys x
184       end
185    end
186end
187%case of xml files of points
188if isfield(s,'Coord')
189    PointCoord=s.Coord;
190    nbcoord=length(PointCoord);
191     %case of image coordinates
192    if isfield(s,'CoordType')& isequal(s.CoordType,'px')
193        for i=1:nbcoord
194           line=str2num(PointCoord{i});
195           Coord(i+val,4:5)=line(1:2);
196        end
197     %case of  physical coordinates
198    else
199        for i=1:nbcoord
200           line=str2num(PointCoord{i});
201           Coord(i+val,1:3)=line(1:3);
202           nbcolumn=size(Coord,2);
203           if nbcolumn<5
204               Coord(i+val,nbcolumn+1:5)=zeros(1,5-nbcolumn);
205           end
206        end
207     end
208end
209CoordCell={};
210for iline=1:size(Coord,1)
211    for j=1:5
212        CoordCell{iline,j}=num2str(Coord(iline,j),4);
213    end
214end       
215Tabchar=cell2tab(CoordCell,'    |    ');%transform cells into table ready for display
216set(handles.ListCoord,'Value',1)
217set(handles.ListCoord,'String',Tabchar)
218
219
220%----------------------------------------------------
221% executed when closing: set the parent interface button to value 0
222function closefcn(gcbo,eventdata,handles_uvmat)
223huvmat=findobj(allchild(0),'Name','uvmat');
224if exist('handles_uvmat','var')
225    set(handles_uvmat.cal,'Value',0)
226    uvmat('cal_Callback',huvmat,[],handles_uvmat);
227%     set(parent_button,'Value',0)%put unactivated buttons to green
228%     set(parent_button,'BackgroundColor',[0 1 0]);
229end
230
231
232% % --- Executes on button press in MenuCoord.
233% function MenuCoord_Callback(hObject, eventdata, handles)
234
235%
236% % --- Executes on button press in delete.
237% function delete_Callback(hObject, eventdata, handles)
238% SetData=get(gcbf,'UserData');%get the interface data
239% IndexObj=SetData.IndexObj;
240% delete_object(IndexObj);
241
242
243%------------------------------------------------------------------
244% --- Executes on button press in calibrate_lin.
245function APPLY_Callback(hObject, eventdata, handles)
246%------------------------------------------------------------------
247calib_cell=get(handles.calib_type,'String');
248val=get(handles.calib_type,'Value');
249calib_type=calib_cell{val};
250Coord_cell=get(handles.ListCoord,'String');
251Object=read_geometry_calib(Coord_cell);
252
253if isequal(calib_type,'rescale')
254    GeometryCalib=calib_rescale(Object.Coord);
255elseif isequal(calib_type,'linear')
256    GeometryCalib=calib_linear(Object.Coord);
257elseif isequal(calib_type,'tsai')
258    GeometryCalib=calib_tsai(Object.Coord);
259end
260unitlist=get(handles.CoordUnit,'String');
261unit=unitlist{get(handles.CoordUnit,'value')};
262GeometryCalib.CoordUnit=unit;
263GeometryCalib.SourceCalib.PointCoord=Object.Coord;
264huvmat=findobj(allchild(0),'Name','uvmat');
265hhuvmat=guidata(huvmat);%handles of elements in the GUI uvmat
266RootPath='';
267RootFile='';
268if ~isempty(hhuvmat.RootPath)& ~isempty(hhuvmat.RootFile)
269    testhandle=1;
270    RootPath=get(hhuvmat.RootPath,'String');
271    RootFile=get(hhuvmat.RootFile,'String');
272    filebase=fullfile(RootPath,RootFile);
273    outputfile=[filebase '.xml'];
274else
275    question={'save the calibration data and point coordinates in'};
276    def={fullfile(RootPath,['ObjectCalib.xml'])};
277    options.Resize='on';
278    answer=inputdlg(question,'save average in a new file',1,def,options);
279    outputfile=answer{1};
280end
281update_imadoc(GeometryCalib,outputfile)
282% testappend=0;
283% if exist(outputfile,'file');%=1 if the output file already exists, 0 else
284%     t=xmltree(outputfile); %read the file
285%     backupfile=outputfile;
286%     testexist=2;
287%     while testexist==2
288%         backupfile=[backupfile '~'];% make a backup name by adding  ~ to the xml file name
289%         testexist=exist(backupfile,'file');
290%     end
291%     [success,message]=copyfile(outputfile,backupfile);%make backup   
292%     t=xmltree(outputfile); %read the file
293%     uid=find(t,'ImaDoc');
294%     if ~isequal(uid,1)%if the xml file is not ImaDoc, delete it (after backup)
295%         if isequal(success,1)
296%             delete(outputfile)
297%         else
298%             msgbox_uvmat('ERROR',['error in the backup of the existing xml file: ' message])
299%             return
300%         end
301%     else
302%         uid_calib=find(t,'ImaDoc/GeometryCalib');
303%         testappend=1;
304%         if isempty(uid_calib)
305%             [t,uid_calib]=add(t,1,'element','GeometryCalib');
306%         else %if GeometryCalib already exists, delete its content
307%             uid_child=children(t,uid_calib);
308%             t=delete(t,uid_child);
309% %             testappend=1;
310%         end
311%     end
312% end
313% if ~testappend %create a new xml file for calibration data
314%     t=xmltree;
315%     t=set(t,1,'name','ImaDoc');
316%     [t,uid_calib]=add(t,1,'element','GeometryCalib');
317% end
318% % hgrid=get(handles.REPLICATE,'parent');%read the calibration image source on the interface userdata
319% % imagename=get(hgrid,'UserData');
320% % if exist(imagename,'file')
321% %     GeometryCalib.SourceCalib.ImageCalib=imagename;
322% % end
323% GeometryCalib.SourceCalib.PointCoord=Object.Coord;
324% t=struct2xml(GeometryCalib,t,uid_calib);
325% save(t,outputfile);
326msgbox_uvmat('CONFIRMATION',{[outputfile ' updated with calibration data'];...
327    ['Error rms (along x,y)=' num2str(GeometryCalib.ErrorRms) ' pixels'];...
328    ['Error max (along x,y)=' num2str(GeometryCalib.ErrorMax) ' pixels']})
329
330%display image with new calibration in the currently opened uvmat interface
331hhh=findobj(hhuvmat.axes3,'Tag','calib_marker');% delete calib points and markers
332if ~isempty(hhh)
333    delete(hhh);
334end
335hhh=findobj(hhuvmat.axes3,'Tag','calib_points');
336if ~isempty(hhh)
337    delete(hhh);
338end
339set(hhuvmat.FixedLimits,'Value',0)% put FixedLimits option to 'off'
340set(hhuvmat.FixedLimits,'BackgroundColor',[0.7 0.7 0.7])
341uvmat('RootPath_Callback',hObject,eventdata,hhuvmat); %file input with xml reading  in uvmat
342
343%------------------------------------------------------------------
344% --- Executes on button press in calibrate_lin.
345function REPLICATE_Callback(hObject, eventdata, handles)
346%------------------------------------------------------------------
347calib_cell=get(handles.calib_type,'String');
348val=get(handles.calib_type,'Value');
349calib_type=calib_cell{val};
350Coord_cell=get(handles.ListCoord,'String');
351Object=read_geometry_calib(Coord_cell);
352
353if isequal(calib_type,'rescale')
354    GeometryCalib=calib_rescale(Object.Coord);
355elseif isequal(calib_type,'linear')
356    GeometryCalib=calib_linear(Object.Coord);
357elseif isequal(calib_type,'tsai')
358    GeometryCalib=calib_tsai(Object.Coord);
359end
360% %record image source
361GeometryCalib.SourceCalib.PointCoord=Object.Coord;
362
363%open and read the dataview GUI
364h_dataview=findobj(allchild(0),'name','dataview');
365if ~isempty(h_dataview)
366    delete(h_dataview)
367end
368CalibData=get(handles.figure1,'UserData');%read the calibration image source on the interface userdata
369
370if isfield(CalibData,'XmlInput')
371    XmlInput=fileparts(CalibData.XmlInput);
372    [XmlInput,filename,ext]=fileparts(XmlInput);
373end
374SubCampaignTest='n'; %default
375testinput=0;
376if isfield(CalibData,'Heading')
377    Heading=CalibData.Heading;
378    if isfield(Heading,'Record') && isequal([filename ext],Heading.Record)
379        [XmlInput,filename,ext]=fileparts(XmlInput);
380    end
381    if isfield(Heading,'Device') && isequal([filename ext],Heading.Device)
382        [XmlInput,filename,ext]=fileparts(XmlInput);
383        Device=Heading.Device;
384    end
385    if isfield(Heading,'Experiment') && isequal([filename ext],Heading.Experiment)
386        [PP,filename,ext]=fileparts(XmlInput);
387    end
388    testinput=0;
389    if isfield(Heading,'SubCampaign') && isequal([filename ext],Heading.SubCampaign)
390%         set(hhdataview.RootDirectory,'String',XmlInput)
391%         set(hhdataview.SubCampaignTest,'Value',1)
392        SubCampaignTest='y';
393        testinput=1;
394    elseif isfield(Heading,'Campaign') && isequal([filename ext],Heading.Campaign)
395%         set(hhdataview.RootDirectory,'String',XmlInput)
396%         set(hhdataview.SubCampaignTest,'Value',0)
397        testinput=1;
398    end
399end
400if ~testinput
401    filename='PROJETS';%default
402    if isfield(CalibData,'XmlInput')
403         [pp,filename]=fileparts(CalibData.XmlInput);
404    end
405    while ~isequal(filename,'PROJETS') && numel(filename)>1
406        filename_1=filename;
407        pp_1=pp;
408        [pp,filename]=fileparts(pp);
409    end
410    XmlInput=fullfile(pp_1,filename_1);
411    testinput=1;
412end
413if testinput
414    outcome=dataview(XmlInput,SubCampaignTest,GeometryCalib);
415end
416%     %A COMPLETER
417%     dataview('RootDirectory_Callback',hObject,eventdata,hhdataview)
418%     ListDevices=get(hhdataview.ListDevices,'String');
419%     for ilist=1:length(ListDevices)
420%         if isequal(ListDevices{ilist},Device)
421%             set(hhdataview.ListDevices,'Value',ilist)
422%             dataview('ListDevices_Callback',hObject,eventdata,hhdataview)
423%             break
424%         end
425%     end
426
427% % hhdataview=guidata(h_dataview);
428% CurrentPath=get(hhdataview.RootDirectory,'String');
429% ListExperiments=get(hhdataview.ListExperiments,'String');
430% Value=get(hhdataview.ListExperiments,'Value');
431% if ~isequal(Value,1)
432%     ListExperiments=ListExperiments(Value);
433% end
434% ListDevices=get(hhdataview.ListDevices,'String');
435% Value=get(hhdataview.ListDevices,'Value');
436% if isequal(Value,1)
437%     msgbox_uvmat('ERROR','manually select in the GUI dataview the device being calibrated')
438%     return
439% else
440%     ListDevices=ListDevices(Value);
441% end
442% ListRecords=get(hhdataview.ListRecords,'String');
443% Value=get(hhdataview.ListRecords,'Value');
444% if ~isequal(Value,1)
445%     ListRecords=ListRecords(Value);
446% end
447% [ListDevices,ListRecords,ListXml,List]=ListDir(CurrentPath,ListExperiments,ListDevices,ListRecords);
448% ListXml=get(hhdataview.ListXml,'String');
449% Value=get(hhdataview.ListXml,'Value');
450% if isequal(Value,1)
451%     msgbox_uvmat('ERROR','you need to select in the GUI dataview the xml files to edit')
452%     return
453% else
454%     ListXml=ListXml(Value);
455% end
456%
457% %update all the selected xml files
458% answer=msgbox_uvmat('INPUT_Y-N',[num2str(length(Value)) ' xml files for device ' ListDevices{1} ' will be refreshed with ' calib_type ' calibration data'])
459% if ~isequal(answer,'Yes')
460%     return
461% end
462% 'TESTcalib'
463% List=DataFiles.List
464% for iexp=1:length(List.Experiment)
465%     ExpName=List.Experiment{iexp}.name;
466%     if isfield(List.Experiment{iexp},'Device')
467%         for idevice=1:length(List.Experiment{iexp}.Device)
468%             DeviceName=List.Experiment{iexp}.Device{idevice}.name;       
469%             if isfield(List.Experiment{iexp}.Device{idevice},'xmlfile')
470%                 for ixml=1:length(List.Experiment{iexp}.Device{idevice}.xmlfile)
471%                     FileName=List.Experiment{iexp}.Device{idevice}.xmlfile{ixml};
472%                     for ilistxml=1:length(ListXml)
473%                         if isequal(FileName,ListXml{ilistxml})
474%                             set(hhdataview.ListXml,'Value',Value(ilistxml))
475%                             drawnow
476%                             xmlfullname=fullfile(CurrentPath,ExpName,DeviceName,FileName);
477%                             update_imadoc(GeometryCalib,xmlfullname)
478%                             break
479%                         end
480%                     end
481%                 end
482%              elseif isfield(List.Experiment{iexp}.Device{idevice},'Record')
483%                 for irecord=1:length(List.Experiment{iexp}.Device{idevice}.Record)
484%                     RecordName=List.Experiment{iexp}.Device{idevice}.Record{irecord}.name;
485%                     if isfield(List.Experiment{iexp}.Device{idevice}.Record{irecord},'xmlfile')
486%                         for ixml=1:length(List.Experiment{iexp}.Device{idevice}.Record{irecord}.xmlfile)
487%                             FileName=List.Experiment{iexp}.Device{idevice}.Record{irecord}.xmlfile{ixml};
488%                             for ilistxml=1:length(ListXml)
489%                                 if isequal(FileName,ListXml{ilistxml})
490%                                     set(hhdataview.ListXml,'Value',Value(ilistxml))
491%                                     drawnow
492%                                     xmlfullname=fullfile(CurrentPath,ExpName,DeviceName,RecordName,FileName);
493%                                     update_imadoc(GeometryCalib,xmlfullname)
494%                                     break
495%                                 end
496%                             end
497%                         end
498%                     end
499%                 end
500%             end
501%         end
502%     end
503% end
504% set(hhdataview.ListXml,'Value',Value)
505
506
507%-----------------------------------------------------------------
508% determine the parameters for a calibration by an affine function (rescaling and offset, no rotation)
509function GeometryCalib=calib_rescale(Coord)
510%------------------------------------------------------------------
511 
512X=Coord(:,1);
513Y=Coord(:,2);
514x_ima=Coord(:,4);
515y_ima=Coord(:,5);
516[px,sx]=polyfit(X,x_ima,1);
517[py,sy]=polyfit(Y,y_ima,1);
518T_x=px(2);
519T_y=py(2);
520GeometryCalib.CalibrationType='rescale';
521GeometryCalib.focal=1;
522GeometryCalib.CoordUnit=[];% default value, to be updated by the calling function
523GeometryCalib.Tx_Ty_Tz=[T_x T_y 1];
524GeometryCalib.R=[px(1),0,0;0,py(1),0;0,0,1];
525
526%check error
527Calib.dpx=1;
528Calib.dpy=1;
529Calib.sx=1;
530Calib.Cx=0;
531Calib.Cy=0;
532Calib.Tz=1;
533Calib.kappa1=0;
534Calib.f=GeometryCalib.focal;
535Calib.Tx=T_x;
536Calib.Ty=T_y;
537Calib.R=GeometryCalib.R;
538[Xpoints,Ypoints]=px_XYZ(Calib,X,Y,0);
539GeometryCalib.ErrorRms(1)=sqrt(mean((Xpoints-x_ima).*(Xpoints-x_ima)));
540GeometryCalib.ErrorMax(1)=max(abs(Xpoints-x_ima));
541GeometryCalib.ErrorRms(2)=sqrt(mean((Ypoints-y_ima).*(Ypoints-y_ima)));
542GeometryCalib.ErrorMax(2)=max(abs(Ypoints-y_ima));
543
544
545%------------------------------------------------------------------
546% determine the parameters for a calibration by a linear transform matrix (rescale and rotation)
547function GeometryCalib=calib_linear(Coord)
548%------------------------------------------------------------------
549X=Coord(:,1);
550Y=Coord(:,2);
551x_ima=Coord(:,4);
552y_ima=Coord(:,5);
553XY_mat=[ones(size(X)) X Y];
554a_X1=XY_mat\x_ima; %transformation matrix for X
555x1=XY_mat*a_X1;%reconstruction
556err_X1=max(abs(x1-x_ima));%error
557a_Y1=XY_mat\y_ima;%transformation matrix for X
558y1=XY_mat*a_Y1;
559err_Y1=max(abs(y1-y_ima));%error
560T_x=a_X1(1);
561T_y=a_Y1(1);
562GeometryCalib.CalibrationType='linear';
563GeometryCalib.focal=1;
564GeometryCalib.CoordUnit=[];% default value, to be updated by the calling function
565GeometryCalib.Tx_Ty_Tz=[T_x T_y 1];
566GeometryCalib.R=[a_X1(2),a_X1(3),0;a_Y1(2),a_Y1(3),0;0,0,1];
567
568%check error
569GeometryCalib.ErrorRms(1)=sqrt(mean((x1-x_ima).*(x1-x_ima)));
570GeometryCalib.ErrorMax(1)=max(abs(x1-x_ima));
571GeometryCalib.ErrorRms(2)=sqrt(mean((y1-y_ima).*(y1-y_ima)));
572GeometryCalib.ErrorMax(2)=max(abs(y1-y_ima));
573
574
575
576
577%------------------------------------------------------------------
578function GeometryCalib=calib_tsai(Coord)
579%------------------------------------------------------------------
580%TSAI
581% 'calibration_lin' provides a linear transform on coordinates,
582path_uvmat=which('uvmat');% check the path detected for source file uvmat
583path_UVMAT=fileparts(path_uvmat); %path to UVMAT
584% if isunix
585    %fid = fopen(fullfile(path_UVMAT,'PARAM_LINUX.txt'),'r');%open the file with civ binary names
586xmlfile=fullfile(path_UVMAT,'PARAM.xml');
587if exist(xmlfile,'file')
588    t=xmltree(xmlfile);
589    sparam=convert(t);
590end
591% else
592%     %fid = fopen(fullfile(path_UVMAT,'PARAM_WIN.txt'),'r');%open the file with civ binary names
593%     xmlfile=fullfile(path_UVMAT,'PARAM_WIN.xml');
594%     if exist(xmlfile,'file')
595%         t=xmltree(xmlfile);
596%         sparam=convert(t);
597%     end
598% end
599if ~isfield(sparam,'GeometryCalib_exe')
600    msgbox_uvmat('ERROR',['calibration program <GeometryCalib_exe> undefined in parameter file ' xmlfile])
601    return
602end
603Tsai_exe=sparam.GeometryCalib_exe;
604if ~exist(Tsai_exe,'file')%the binary is defined in /bin, default setting
605     Tsai_exe=fullfile(path_UVMAT,Tsai_exe);
606end
607if ~exist(Tsai_exe,'file')
608    msgbox_uvmat('ERROR',['calibration program ' sparam.GeometryCalib_exe ' defined in PARAM.xml does not exist'])
609    return
610end
611
612textcoord=num2str(Coord,4);
613dlmwrite('t.txt',textcoord,''); 
614% ['!' Tsai_exe ' -f1 0 -f2 t.txt']
615    eval(['!' Tsai_exe ' -f t.txt > tsaicalib.log']);
616if ~exist('calib.dat','file')
617    msgbox_uvmat('ERROR','no output from calibration program Tsai_exe: possibly too few points')
618end
619calibdat=dlmread('calib.dat');
620GeometryCalib.CalibrationType='tsai';
621GeometryCalib.focal=calibdat(10);
622GeometryCalib.dpx_dpy=[calibdat(5) calibdat(6)];
623GeometryCalib.Cx_Cy=[calibdat(7) calibdat(8)];
624GeometryCalib.sx=calibdat(9);
625GeometryCalib.kappa1=calibdat(11);
626GeometryCalib.CoordUnit=[];% default value, to be updated by the calling function
627GeometryCalib.Tx_Ty_Tz=[calibdat(12) calibdat(13) calibdat(14)];
628Rx_Ry_Rz=calibdat([15:17]);
629sa = sin(Rx_Ry_Rz(1)) ;
630ca=cos(Rx_Ry_Rz(1));
631sb=sin(Rx_Ry_Rz(2));
632cb =cos(Rx_Ry_Rz(2));
633sg =sin(Rx_Ry_Rz(3));
634cg =cos(Rx_Ry_Rz(3));
635r1 = cb * cg;
636r2 = cg * sa * sb - ca * sg;
637r3 = sa * sg + ca * cg * sb;
638r4 = cb * sg;
639r5 = sa * sb * sg + ca * cg;
640r6 = ca * sb * sg - cg * sa;
641r7 = -sb;
642r8 = cb * sa;
643r9 = ca * cb;
644%EN DEDUIRE MATRICE R ??
645GeometryCalib.R=[r1,r2,r3;r4,r5,r6;r7,r8,r9];
646%erreur a caracteriser?
647%check error
648Calib.dpx=GeometryCalib.dpx_dpy(1);
649Calib.dpy=GeometryCalib.dpx_dpy(2);
650Calib.sx=GeometryCalib.sx;
651Calib.Cx=GeometryCalib.Cx_Cy(1);
652Calib.Cy=GeometryCalib.Cx_Cy(2);
653Calib.kappa1=GeometryCalib.kappa1;
654Calib.f=GeometryCalib.focal;
655Calib.Tx=GeometryCalib.Tx_Ty_Tz(1);
656Calib.Ty=GeometryCalib.Tx_Ty_Tz(2);
657Calib.Tz=GeometryCalib.Tx_Ty_Tz(3);
658Calib.R=GeometryCalib.R;
659X=Coord(:,1);
660Y=Coord(:,2);
661Z=Coord(:,3);
662x_ima=Coord(:,4);
663y_ima=Coord(:,5);
664[Xpoints,Ypoints]=px_XYZ(Calib,X,Y,Z);
665
666GeometryCalib.ErrorRms(1)=sqrt(mean((Xpoints-x_ima).*(Xpoints-x_ima)));
667GeometryCalib.ErrorMax(1)=max(abs(Xpoints-x_ima));
668GeometryCalib.ErrorRms(2)=sqrt(mean((Ypoints-y_ima).*(Ypoints-y_ima)));
669GeometryCalib.ErrorMax(2)=max(abs(Ypoints-y_ima));
670% Nfx
671% dx
672% dy
673% 5 dpx
674% 6 dpy
675% cx
676% cy
677% sx
678% f
679% kappa1
680% tx
681% ty
682% tz
683% rx
684% ry
685% rz
686% p1
687% p2
688
689%calibcoeff=str2num(calibdat)
690
691
692
693% --- Executes on button press in rotation.
694function rotation_Callback(hObject, eventdata, handles)
695angle_rot=(pi/180)*str2num(get(handles.Phi,'String'));
696Coord_cell=get(handles.ListCoord,'String');
697data=read_geometry_calib(Coord_cell);
698data.Coord(:,1)=cos(angle_rot)*data.Coord(:,1)+sin(angle_rot)*data.Coord(:,2);
699data.Coord(:,1)=-sin(angle_rot)*data.Coord(:,1)+cos(angle_rot)*data.Coord(:,2);
700set(handles.XObject,'String',num2str(data.Coord(:,1),4));
701set(handles.YObject,'String',num2str(data.Coord(:,2),4));
702
703
704function XImage_Callback(hObject, eventdata, handles)
705update_list(hObject, eventdata,handles)
706
707function YImage_Callback(hObject, eventdata, handles)
708update_list(hObject, eventdata,handles)
709
710function XObject_Callback(hObject, eventdata, handles)
711update_list(hObject, eventdata,handles)
712
713function YObject_Callback(hObject, eventdata, handles)
714update_list(hObject, eventdata,handles)
715
716function ZObject_Callback(hObject, eventdata, handles)
717update_list(hObject, eventdata,handles)
718
719function update_list(hObject, eventdata, handles)
720str4=get(handles.XImage,'String');
721str5=get(handles.YImage,'String');
722str1=get(handles.XObject,'String');
723tt=double(str1);
724str2=get(handles.YObject,'String');
725str3=get(handles.ZObject,'String');
726if ~isempty(str1) & ~isequal(double(str1),32) & (isempty(str3)|isequal(double(str3),32))
727    str3='0';%put z to 0 by default
728end
729strline=[str1 '    |    ' str2 '    |    ' str3 '    |    ' str4 '    |    ' str5];
730Coord=get(handles.ListCoord,'String');
731val=get(handles.ListCoord,'Value');
732Coord{val}=strline;
733set(handles.ListCoord,'String',Coord)
734
735%--------------------------------------------------------------------
736% --- Executes on selection change in ListCoord.
737%--------------------------------------------------------------------
738function ListCoord_Callback(hObject, eventdata, handles)
739% hObject    handle to ListCoord (see GCBO)
740% eventdata  reserved - to be defined in a future version of MATLAB
741% handles    structure with handles and user data (see GUIDATA)
742
743% Hints: contents = get(hObject,'String') returns ListCoord contents as cell array
744%        contents{get(hObject,'Value')} returns selected item from ListCoord
745%set(handles.edit_append,'Value',2); %set to edit mode
746Coord_cell=get(handles.ListCoord,'String');
747val=get(handles.ListCoord,'Value');
748if length(Coord_cell)>0
749    coord_str=Coord_cell{val};
750    k=findstr('|',coord_str);
751    if isempty(k)
752        return
753    end
754    set(handles.XObject,'String',coord_str(1:k(1)-5))
755    set(handles.YObject,'String',coord_str(k(1)+5:k(2)-5))
756    set(handles.ZObject,'String',coord_str(k(2)+5:k(3)-5))
757    set(handles.XImage,'String',coord_str(k(3)+5:k(4)-5))
758    set(handles.YImage,'String',coord_str(k(4)+5:end))
759    huvmat=findobj(allchild(0),'Name','uvmat');%find the current uvmat interface handle
760    hplot=findobj(huvmat,'Tag','axes3');%main plotting axis of uvmat
761    h_menu_coord=findobj(huvmat,'Tag','menu_coord');
762    menu=get(h_menu_coord,'String');
763    choice=get(h_menu_coord,'Value');
764    if iscell(menu)
765        option=menu{choice};
766    else
767        option='px'; %default
768    end
769    if isequal(option,'phys')
770        XCoord=str2num(coord_str(1:k(1)-5));
771        YCoord=str2num(coord_str(k(1)+5:k(2)-5));
772    elseif isequal(option,'px')|| isequal(option,'')
773        XCoord=str2num(coord_str(k(3)+5:k(4)-5));
774        YCoord=str2num(coord_str(k(4)+5:end));
775    else
776        msgbox_uvmat('ERROR','the choice in menu_coord of uvmat must be px or phys ')
777    end
778    huvmat=findobj(allchild(0),'Name','uvmat');%find the current uvmat interface handle
779    hplot=findobj(huvmat,'Tag','axes3');%main plotting axis of uvmat
780    hhh=findobj(hplot,'Tag','calib_marker');
781    if isempty(hhh)
782        axes(hplot)
783        line(XCoord,YCoord,'Color','m','Tag','calib_marker','LineStyle','.','Marker','o','MarkerSize',20);
784    else
785        set(hhh,'XData',XCoord)
786        set(hhh,'YData',YCoord)
787    end
788end
789
790
791%----------------------------------------------------
792% --- Executes on button press in rotation_plus.
793function rotation_plus_Callback(hObject, eventdata, handles)
794Phi=0;
795Phi=get(handles.Phi,'String');
796if ~isempty(Phi)
797    Phi=str2num(Phi);
798end
799rotation(handles,Phi)
800
801%-------------------------------------------------
802% --- Executes on button press in rotation_minus.
803function rotation_minus_Callback(hObject, eventdata, handles)
804Phi=0;
805Phi=get(handles.Phi,'String');
806if ~isempty(Phi)
807    Phi=-str2num(Phi);
808end
809rotation(handles,Phi)
810
811
812
813function O_x_Callback(hObject, eventdata, handles)
814
815
816function O_y_Callback(hObject, eventdata, handles)
817
818
819function O_z_Callback(hObject, eventdata, handles)
820
821
822% --- Executes on selection change in edit_append.
823function edit_append_Callback(hObject, eventdata, handles)
824% val=get(handles.PLOT_append,'Value');
825% if isequal(val,2); %append mode
826%     %appeler mouse
827% end
828choice=get(handles.edit_append,'Value');
829if choice==1
830       Coord=get(handles.ListCoord,'String');
831       val=length(Coord);
832       if val>=1 & isequal(Coord{val},'')
833            val=val-1; %do not take into account blank
834       end
835       Coord{val+1}='';
836       set(handles.ListCoord,'String',Coord)
837       set(handles.ListCoord,'Value',val+1)
838end
839
840
841%A REVOIR
842% if choice==2
843%     %display image with px coordinates
844%     hrootpath=findobj(huvmat,'Tag','RootPath');
845%     hrootfile=findobj(huvmat,'Tag','RootFile');
846%     RootPath='';
847%     RootFile='';
848% %     if ~isempty(hrootpath)& ~isempty(hrootfile)
849%         testhandle=1;
850%         RootPath=get(hrootpath,'String');
851%         RootFile=get(hrootfile,'String');
852% %         filebase=fullfile(RootPath,RootFile);
853% %         outputfile=[filebase '.xml'];
854%         Indices=get(findobj(huvmat,'Tag','FileIndex'),'String');
855%         Ext=get(findobj(huvmat,'Tag','FileExt'),'String');
856%         imagename=[fullfile(RootPath,RootFile) Indices Ext];
857%         % input.menu_coord=1;
858%          h_menu_coord=findobj(huvmat,'Tag','menu_coord');
859%         set(h_menu_coord,'Value',3)
860%         huvmat=uvmat(imagename);%open uvmat, set phys coord (Value 1)
861%     
862% %     end
863% end
864   
865function NEW_Callback(hObject, eventdata, handles)
866%A METTRE SOUS UN BOUTON
867huvmat=findobj(allchild(0),'Name','uvmat');
868hchild=get(huvmat,'children');
869hcoord=findobj(hchild,'Tag','menu_coord');
870coordtype=get(hcoord,'Value');
871haxes=findobj(hchild,'Tag','axes3');
872AxeData=get(haxes,'UserData');
873if ~isequal(hcoord,2)
874    set(hcoord,'Value',2)
875    huvmat=uvmat(AxeData);
876    'relancer uvmat';
877end
878if ~isfield(AxeData,'ZoomAxes')
879    msgbox_uvmat('ERROR','first draw a window around a grid marker')
880    return
881end
882XLim=get(AxeData.ZoomAxes,'XLim');
883YLim=get(AxeData.ZoomAxes,'YLim');
884np=size(AxeData.A);
885ind_sub_x=round(XLim);
886ind_sub_y=np(1)-round(YLim);
887Mfiltre=AxeData.A([ind_sub_y(2):ind_sub_y(1)] ,ind_sub_x,:);
888Mfiltre_norm=double(Mfiltre);
889Mfiltre_norm=Mfiltre_norm/sum(sum(Mfiltre_norm));
890Mfiltre_norm=100*(Mfiltre_norm-mean(mean(Mfiltre_norm)));
891Atype=class(AxeData.A);
892Data.NbDim=2;
893Data.A=filter2(Mfiltre_norm,double(AxeData.A));
894Data.A=feval(Atype,Data.A);
895Data.AName='image';
896Data.AX=AxeData.AX;
897Data.AY=AxeData.AY;
898Data.CoordType='px';
899plot_field(Data)
900 
901
902
903%'key_press_fcn:' function activated when a key is pressed on the keyboard
904%-----------------------------------
905function key_press_fcn(hObject,eventdata,handles)
906hh=get(hObject,'parent');
907xx=double(get(hh,'CurrentCharacter')); %get the keyboard character
908
909if ismember(xx,[8 127])%backspace or delete
910    Coord_cell=get(handles.ListCoord,'String');
911    data=read_geometry_calib(Coord_cell);
912    Coord=[]; %default
913    if isfield(data,'Coord')
914        Coord=data.Coord;
915    end
916    val=get(handles.ListCoord,'Value');
917    Coord(val,:)=[];%suppress the selected item in the list
918    CoordCell={};
919    for iline=1:size(Coord,1)
920        for j=1:5
921            CoordCell{iline,j}=num2str(Coord(iline,j),4);
922        end
923    end
924    Tabchar=cell2tab(CoordCell,'    |    ');%transform cells into table ready for display
925    val=min(size(Coord,1),val);
926    set(handles.ListCoord,'Value',max(val,1))
927    set(handles.ListCoord,'String',Tabchar) 
928    ListCoord_Callback(hObject, eventdata, handles)
929    MenuPlot_Callback(hObject,eventdata,handles)
930end
931
932
933% --- Executes on button press in append_point.
934function append_point_Callback(hObject, eventdata, handles)
935
936       Coord=get(handles.ListCoord,'String');
937       val=length(Coord);
938       if val>=1 & isequal(Coord{val},'')
939            val=val-1; %do not take into account blank
940       end
941       Coord{val+1}='';
942       set(handles.ListCoord,'String',Coord)
943       set(handles.ListCoord,'Value',val+1)
944
945
946% --------------------------------------------------------------------
947function MenuOpen_Callback(hObject, eventdata, handles)
948%get the object file
949huvmat=findobj(allchild(0),'Name','uvmat');
950UvData=get(huvmat,'UserData');
951hchild=get(huvmat,'Children');
952hrootpath=findobj(hchild,'Tag','RootPath');
953oldfile=get(hrootpath,'String');
954if isempty(oldfile)
955    oldfile='';
956end
957%[FileName,PathName] = uigetfile('*.civ','Select a .civ file',oldfile)
958[FileName, PathName, filterindex] = uigetfile( ...
959       {'*.xml;*.mat', ' (*.xml,*.mat)';
960       '*.xml',  '.xml files '; ...
961        '*.mat',  '.mat matlab files '}, ...
962        'Pick a file',oldfile);
963fileinput=[PathName FileName];%complete file name
964testblank=findstr(fileinput,' ');%look for blanks
965if ~isempty(testblank)
966    msgbox_uvmat('ERROR','forbidden input file name or path: no blank character allowed')
967    return
968end
969sizf=size(fileinput);
970if (~ischar(fileinput)|~isequal(sizf(1),1)),return;end
971loadfile(handles,fileinput)
972
973
974% --------------------------------------------------------------------
975function Untitled_3_Callback(hObject, eventdata, handles)
976% hObject    handle to Untitled_3 (see GCBO)
977% eventdata  reserved - to be defined in a future version of MATLAB
978% handles    structure with handles and user data (see GUIDATA)
979
980
981% --------------------------------------------------------------------
982function MenuPlot_Callback(hObject, eventdata, handles)
983
984huvmat=findobj(allchild(0),'Name','uvmat');%find the current uvmat interface handle
985UvData=get(huvmat,'UserData');%Data associated to the current uvmat interface
986hhuvmat=guidata(huvmat); %handles of GUI elements in uvmat
987hplot=findobj(huvmat,'Tag','axes3');%main plotting axis of uvmat
988h_menu_coord=findobj(huvmat,'Tag','menu_coord');
989menu=get(h_menu_coord,'String');
990choice=get(h_menu_coord,'Value');
991if iscell(menu)
992    option=menu{choice};
993else
994    option='px'; %default
995end
996Coord_cell=get(handles.ListCoord,'String');
997ObjectData=read_geometry_calib(Coord_cell);
998%ObjectData=read_geometry_calib(handles);%read the interface input parameters defining the object
999if isequal(option,'phys')
1000    ObjectData.Coord=ObjectData.Coord(:,[1:3]);
1001elseif isequal(option,'px')||isequal(option,'')
1002    ObjectData.Coord=ObjectData.Coord(:,[4:5]);
1003else
1004    msgbox_uvmat('ERROR','the choice in menu_coord of uvmat must be px or phys ')
1005end
1006axes(hhuvmat.axes3)
1007hh=findobj('Tag','calib_points');
1008if isempty(hh)
1009    hh=line(ObjectData.Coord(:,1),ObjectData.Coord(:,2),'Color','m','Tag','calib_points','LineStyle','.','Marker','+');
1010else
1011    set(hh,'XData',ObjectData.Coord(:,1))
1012    set(hh,'YData',ObjectData.Coord(:,2))
1013end
1014
1015% --------------------------------------------------------------------
1016function MenuHelp_Callback(hObject, eventdata, handles)
1017path_to_uvmat=which ('uvmat');% check the path of uvmat
1018pathelp=fileparts(path_to_uvmat);
1019    helpfile=fullfile(pathelp,'uvmat_doc','uvmat_doc.html');
1020if isempty(dir(helpfile)), msgbox_uvmat('ERROR','Please put the help file uvmat_doc.html in the sub-directory /uvmat_doc of the UVMAT package')
1021else
1022   addpath (fullfile(pathelp,'uvmat_doc'))
1023   web([helpfile '#geometry_calib'])
1024end
1025
1026%------------------------------------------------------------------------
1027function MenuCreateGrid_Callback(hObject, eventdata, handles)
1028%------------------------------------------------------------------------
1029%hcalib=get(handles.calib_type,'parent');%handles of the GUI geometry_calib
1030CalibData=get(handles.figure1,'UserData');
1031Tinput=[];%default
1032if isfield(CalibData,'grid')
1033    Tinput=CalibData.grid;
1034end
1035T=create_grid(Tinput);%display the GUI create_grid
1036CalibData.grid=T;
1037set(handles.figure1,'UserData',CalibData)
1038
1039%grid in phys space
1040Coord_cell=get(handles.ListCoord,'String');
1041data=read_geometry_calib(Coord_cell);
1042nbpoints=size(data.Coord,1); %nbre of calibration points
1043data.Coord(1:size(T,1),1:3)=T;%update the existing list of phys coordinates from the GUI create_grid
1044for i=1:nbpoints
1045   for j=1:5
1046          Coord{i,j}=num2str(data.Coord(i,j),4);%display coordiantes with 4 digits
1047   end
1048end
1049for i=nbpoints+1:size(data.Coord,1)
1050    for j=1:3
1051          Coord{i,j}=num2str(data.Coord(i,j),4);%display coordiantes with 4 digits
1052    end
1053    for j=4:5
1054          Coord{i,j}='';%display coordiantes with 4 digi
1055    end
1056end
1057
1058
1059%size(data.Coord,1)
1060Tabchar=cell2tab(Coord,'    |    ');
1061set(handles.ListCoord,'Value',1)
1062set(handles.ListCoord,'String',Tabchar)
1063
1064%-----------------------------------------------------------------------
1065function MenuTranslatePoints_Callback(hObject, eventdata, handles)
1066%-----------------------------------------------------------------------
1067%hcalib=get(handles.calib_type,'parent');%handles of the GUI geometry_calib
1068CalibData=get(handles.figure1,'UserData');
1069Tinput=[];%default
1070if isfield(CalibData,'translate')
1071    Tinput=CalibData.translate;
1072end
1073T=translate_points(Tinput);%display translate_points GUI and get shift parameters
1074CalibData.translate=T;
1075set(handles.figure1,'UserData',CalibData)
1076%translation
1077Coord_cell=get(handles.ListCoord,'String');
1078data=read_geometry_calib(Coord_cell);
1079data.Coord(:,1)=T(1)+data.Coord(:,1);
1080data.Coord(:,2)=T(2)+data.Coord(:,2);
1081data.Coord(:,3)=T(3)+data.Coord(:,3);
1082data.Coord(:,[4 5])=data.Coord(:,[4 5]);
1083for i=1:size(data.Coord,1)
1084    for j=1:5
1085          Coord{i,j}=num2str(data.Coord(i,j),4);%phys x,y,z
1086   end
1087end
1088Tabchar=cell2tab(Coord,'    |    ');
1089set(handles.ListCoord,'Value',1)
1090set(handles.ListCoord,'String',Tabchar)
1091
1092
1093% --------------------------------------------------------------------
1094function MenuRotatePoints_Callback(hObject, eventdata, handles)
1095%hcalib=get(handles.calib_type,'parent');%handles of the GUI geometry_calib
1096CalibData=get(handles.figure1,'UserData');
1097Tinput=[];%default
1098if isfield(CalibData,'rotate')
1099    Tinput=CalibData.rotate;
1100end
1101T=rotate_points(Tinput);%display translate_points GUI and get shift parameters
1102CalibData.rotate=T;
1103set(handles.figure1,'UserData',CalibData)
1104%-----------------------------------------------------
1105%rotation
1106Phi=T(1);
1107O_x=0;%default
1108O_y=0;%default
1109if numel(T)>=2
1110    O_x=T(2);%default
1111end
1112if numel(T)>=3
1113    O_y=T(3);%default
1114end
1115Coord_cell=get(handles.ListCoord,'String');
1116data=read_geometry_calib(Coord_cell);
1117r1=cos(pi*Phi/180);
1118r2=-sin(pi*Phi/180);
1119r3=sin(pi*Phi/180);
1120r4=cos(pi*Phi/180);
1121x=data.Coord(:,1)-O_x;
1122y=data.Coord(:,2)-O_y;
1123data.Coord(:,1)=r1*x+r2*y;
1124data.Coord(:,2)=r3*x+r4*y;
1125% data.Coord(:,[4 5])=data.Coord(:,[4 5]);
1126for i=1:size(data.Coord,1)
1127    for j=1:5
1128          Coord{i,j}=num2str(data.Coord(i,j),4);%phys x,y,z
1129   end
1130end
1131Tabchar=cell2tab(Coord,'    |    ');
1132set(handles.ListCoord,'Value',1)
1133set(handles.ListCoord,'String',Tabchar)
1134
1135
Note: See TracBrowser for help on using the repository browser.