Changeset 1184 for trunk/src/series/bed_scan.m
- Timestamp:
- Nov 6, 2025, 7:03:02 PM (4 weeks ago)
- File:
-
- 1 edited
-
trunk/src/series/bed_scan.m (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/series/bed_scan.m
r1183 r1184 61 61 %======================================================================= 62 62 63 function ParamOut=bed_scan (Param)63 function ParamOut=bed_scan(Param) 64 64 65 65 %% set the input elements needed on the GUI series when the action is selected in the menu ActionName or InputTable refreshed … … 67 67 ParamOut.NbViewMax=1;% max nbre of input file series (default , no limitation) 68 68 ParamOut.AllowInputSort='off';% allow alphabetic sorting of the list of input file SubDir (options 'off'/'on', 'off' by default) 69 ParamOut.WholeIndexRange='o ff';% prescribes the file index ranges from min to max (options 'off'/'on', 'off' by default)70 ParamOut.NbSlice= 1; %nbre of slices ('off' by default)69 ParamOut.WholeIndexRange='on';% prescribes the file index ranges from min to max (options 'off'/'on', 'off' by default) 70 ParamOut.NbSlice='off'; %nbre of slices ('off' by default) 71 71 ParamOut.VelType='off';% menu for selecting the velocity type (options 'off'/'one'/'two', 'off' by default) 72 72 ParamOut.FieldName='one';% menu for selecting the field (s) in the input file(options 'off'/'one'/'two', 'off' by default) … … 75 75 ParamOut.Mask='off';%can use mask option (option 'off'/'on', 'off' by default) 76 76 ParamOut.OutputDirExt='.bed';%set the output dir extension 77 ParamOut.OutputFileMode='NbSlice';% ='=NbInput': 1 output file per input file index, '=NbInput_i': 1 file per input file index i, '=NbSlice': 1 file per slice 78 %check the type of the existence and type of the first input file: 79 Param.IndexRange.last_i=Param.IndexRange.first_i;%keep only the first index in the series 80 if isfield(Param.IndexRange,'first_j') 81 Param.IndexRange.last_j=Param.IndexRange.first_j; 82 end 83 filecell=get_file_series(Param); 84 if ~exist(filecell{1,1},'file') 85 msgbox_uvmat('WARNING','the first input file does not exist') 86 else 87 FileInfo=get_file_info(filecell{1,1}); 88 FileType=FileInfo.FileType; 89 if isempty(find(strcmp(FileType,{'image','multimage','mmreader','video'})))% =1 for images 90 msgbox_uvmat('ERROR',['bad input file type for ' mfilename ': an image is needed']) 91 end 92 end 93 return 77 ParamOut.OutputFileMode='NbInput_i';% ='=NbInput': 1 output file per input file index, '=NbInput_i': 1 file per input file index i, '=NbSlice': 1 file per slice 78 return 94 79 end 95 80 … … 111 96 %% root input file names and nomenclature type (cell arrays with one element) 112 97 RootPath=Param.InputTable{1,1}; 113 98 SubDir=Param.InputTable{1,2}; 99 RootFile=Param.InputTable{1,3}; 100 NomType=Param.InputTable{1,4}; 101 FileExt=Param.InputTable{1,5}; 102 i_series=Param.IndexRange.first_i:Param.IndexRange.incr_i:Param.IndexRange.last_i; 103 j_series=Param.IndexRange.first_j:Param.IndexRange.incr_j:Param.IndexRange.last_j; 104 nbfield_i=numel(i_series); 105 nbfield_j=numel(j_series); 114 106 115 107 %% directory for output files … … 117 109 118 110 %% get the set of input file names (cell array filecell), and file indices 119 [filecell,i1_series,i2_series,j1_series,j2_series]=get_file_series(Param);111 %[filecell,i1_series,i2_series,j1_series,j2_series]=get_file_series(Param); 120 112 % filecell{iview,fileindex}: cell array representing the list of file names 121 113 % iview: line in the table corresponding to a given file series 122 % fileindex: file index within the file series, 123 % i1_series(iview,ref_j,ref_i)... are the corresponding arrays of indices i1,i2,j1,j2, depending on the input line iview and the two reference indices ref_i,ref_j 114 % fileindex: file index within the file series, 115 % i1_series(iview,ref_j,ref_i)... are the corresponding arrays of indices i1,i2,j1,j2, depending on the input line iview and the two reference indices ref_i,ref_j 124 116 % i1_series(iview,fileindex) expresses the same indices as a 1D array in file indices 125 nbfield_j=size(i1_series{1},1); %nb of fields for the j index (bursts or volume slices) 126 nbfield_i=size(i1_series{1},2); %nb of fields for the i index 127 128 %% set of y positions 129 ycalib=[-51 -1 49];% calibration planes 130 y_scan=-51+(100/400)*(i1_series{1}-1);% transverse position given by the translating system: first view at y=-51, view 400 at y=+49 117 %nbfield_j=size(i1_series{1},1); %nb of fields for the j index (bursts or volume slices) 118 % nbfield_i=size(i1_series{1},2); %nb of fields for the i index 119 % 120 % nbfield_j=size(i1_series{1},1); %nb of fields for the j index (bursts or volume slices) 121 CheckVirtual=false; 122 if isfield(Param,'FileSeries')% virtual file indexing used (e.g. multitif images) 123 CheckVirtual=true; 124 end 125 126 %%%%%%%%%%%% END STANDARD PART %%%%%%%%%%%%fullfile( 127 % EDIT FROM HERE 128 %% load the initial scan 129 [RootRoot,CamName]=fileparts(RootPath); 130 RootRoot=fileparts(RootRoot); 131 CalibFolder=fullfile(RootRoot,'EXP_INIT',CamName); 132 File_init=fullfile(CalibFolder,'images.png.bed','Z_init.nc'); 133 Data_init=nc2struct(File_init); 134 %% set of y positions 135 136 nb_scan=400;% nbre of planes for a scan 137 if nbfield_j<400 138 nb_scan=nbfield_j; 139 end 140 %ycalib=[-51 -1 49];% calibration planes 141 y_scan=-51+0.25*(1:nb_scan);% transverse position given by the translating system: first view at y=-51, view 400 at y=+49 142 coord_x=0.25:0.25:450;%% coord x in phys coordinates for final projection 143 131 144 Mfiltre=ones(2,10)/20;%filter matrix for imnages 132 145 133 146 %% calibration data and timing: read the ImaDoc files 134 XmlData_A=xml2struct(fullfile(RootPath,'planeA.xml')); 135 XmlData_B=xml2struct(fullfile(RootPath,'planeB.xml')); 136 XmlData_C=xml2struct(fullfile(RootPath,'planeC.xml')); 137 ycalib=[-51 -1 49];% the three y positions for calibration 138 fx(1)=XmlData_A.GeometryCalib.fx_fy(1); 147 148 XmlData_A=xml2struct(fullfile(CalibFolder,'planeA.xml')); 149 XmlData_B=xml2struct(fullfile(CalibFolder,'planeB.xml')); 150 XmlData_C=xml2struct(fullfile(CalibFolder,'planeC.xml')); 151 ycalib=[-51 -1 49];% the three y positions for calibration= 152 fx(1)=XmlData_C.GeometryCalib.fx_fy(1); 139 153 fx(2)=XmlData_B.GeometryCalib.fx_fy(1); 140 fx(3)=XmlData_ C.GeometryCalib.fx_fy(1);141 fy(1)=XmlData_ A.GeometryCalib.fx_fy(2);154 fx(3)=XmlData_A.GeometryCalib.fx_fy(1); 155 fy(1)=XmlData_C.GeometryCalib.fx_fy(2); 142 156 fy(2)=XmlData_B.GeometryCalib.fx_fy(2); 143 fy(3)=XmlData_ C.GeometryCalib.fx_fy(2);144 Tx(1)=XmlData_ A.GeometryCalib.Tx_Ty_Tz(1);157 fy(3)=XmlData_A.GeometryCalib.fx_fy(2); 158 Tx(1)=XmlData_C.GeometryCalib.Tx_Ty_Tz(1); 145 159 Tx(2)=XmlData_B.GeometryCalib.Tx_Ty_Tz(1); 146 Tx(3)=XmlData_ C.GeometryCalib.Tx_Ty_Tz(1);147 Ty(1)=XmlData_ A.GeometryCalib.Tx_Ty_Tz(2);160 Tx(3)=XmlData_A.GeometryCalib.Tx_Ty_Tz(1); 161 Ty(1)=XmlData_C.GeometryCalib.Tx_Ty_Tz(2); 148 162 Ty(2)=XmlData_B.GeometryCalib.Tx_Ty_Tz(2); 149 Ty(3)=XmlData_ C.GeometryCalib.Tx_Ty_Tz(2);150 R11(1)=XmlData_ A.GeometryCalib.R(1,1);163 Ty(3)=XmlData_A.GeometryCalib.Tx_Ty_Tz(2); 164 R11(1)=XmlData_C.GeometryCalib.R(1,1); 151 165 R11(2)=XmlData_B.GeometryCalib.R(1,1); 152 R11(3)=XmlData_ C.GeometryCalib.R(1,1);153 R12(1)=XmlData_ A.GeometryCalib.R(1,2);166 R11(3)=XmlData_A.GeometryCalib.R(1,1); 167 R12(1)=XmlData_C.GeometryCalib.R(1,2); 154 168 R12(2)=XmlData_B.GeometryCalib.R(1,2); 155 R12(3)=XmlData_ C.GeometryCalib.R(1,2);156 R21(1)=XmlData_ A.GeometryCalib.R(2,1);169 R12(3)=XmlData_A.GeometryCalib.R(1,2); 170 R21(1)=XmlData_C.GeometryCalib.R(2,1); 157 171 R21(2)=XmlData_B.GeometryCalib.R(2,1); 158 R21(3)=XmlData_ C.GeometryCalib.R(2,1);159 R22(1)=XmlData_ A.GeometryCalib.R(2,2);172 R21(3)=XmlData_A.GeometryCalib.R(2,1); 173 R22(1)=XmlData_C.GeometryCalib.R(2,2); 160 174 R22(2)=XmlData_B.GeometryCalib.R(2,2); 161 R22(3)=XmlData_ C.GeometryCalib.R(2,2);162 pfx=polyfit(ycalib,fx,1);%get th e linear interpolation of each parameter of the three calibrations175 R22(3)=XmlData_A.GeometryCalib.R(2,2); 176 pfx=polyfit(ycalib,fx,1);%get thfield_ie linear interpolation of each parameter of the three calibrations 163 177 pfy=polyfit(ycalib,fy,1); 164 178 pTx=polyfit(ycalib,Tx,1); … … 169 183 p22=polyfit(ycalib,R22,1); 170 184 %get the calibration parameters at each position y by interpolation of the 3 calibration parameters 171 for img=1:nb field_i185 for img=1:nb_scan 172 186 Calib(img).fx_fy(1)=pfx(1)*y_scan(img)+pfx(2); 173 187 Calib(img).fx_fy(2)=pfy(1)*y_scan(img)+pfy(2); … … 184 198 end 185 199 186 %% check coincdence in time for several input file series 187 %not relevant for this function 188 189 %% coordinate transform or other user defined transform 190 %not relevant for this function 191 192 %%%%%%%%%%%% END STANDARD PART %%%%%%%%%%%% 193 % EDIT FROM HERE 200 201 194 202 195 203 %% Load the init bed scan 196 204 tic 197 nb_scan=10; 198 for img=1:nb_scan 199 img 200 a=flipud(imread(filecell{1,img}));%image of the initial bed 201 if img==1 202 x=1:size(a,2);%image absissa in pixel coordinates 205 %filecell=reshape(filecell,nbfield_j,nbfield_i) 206 % main loop 207 for ifield=1:nbfield_i 208 for img=1:nbfield_j% loop on positions 209 if CheckVirtual 210 [FileName,FrameIndex]=index2filename(Param.FileSeries,i_series(ifield),j_series(img),nbfield_j); 211 InputFile=fullfile(RootPath,SubDir,FileName); 212 else 213 InputFile=fullfile_uvmat(RootPath,SubDir,RootFile,FileExt,NomType,FileIndex,ifield,[],img); 214 FrameIndex=1; 215 end 216 a=flipud(read_image(InputFile,'multimage',[],FrameIndex)); 217 %a=flipud(imread(InputFile));%image of the initial bed [X_b_new(img,:),Z_b_new(img,:)]=phys_XYZ(Calib(img),[],x,Z_sb(img,:)) 218 if img==1 219 [nby,nbx]=size(a); 220 x_ima=1:nbx;%image absissa in pixel coordinates 221 X_phys=zeros(nb_scan,nbx); 222 Z_phys=zeros(nb_scan,nbx); 223 end 224 % filtering 225 a=filter2(Mfiltre,a);%smoothed image 226 amean=mean(a,2); 227 [~,ind_max]=max(amean);% get the max of the image averaged along x, to restrict the search region 228 ind_range=max(1,ind_max-30):min(nby,ind_max+30);% search band to find the line 229 z_ima=get_max(a(ind_range,:))+ind_range(1)-1;% get the max in the search band and shift to express it in indices of the original image 230 231 % [~,iy]=max(a);% find the max along the first coordinate Z_s_new=zeros(nb_scan,size(Z_s,2)); y, max values imax and the corresponding y index iy along the first coordinate y 232 z_ima=smooth(z_ima,20,'rloess');%smooth Z, the image index of max luminosity (dependning on x) 233 [X_phys(img,:),Z_phys(img,:)]=phys_XYZ(Calib(img),[],x_ima,z_ima'); 203 234 end 204 % filtering 205 a=filter2(Mfiltre,a);%smoothed image 206 [imax,iy]=max(a);% find the max along the first coordinate y, max values imax and the corresponding y index iy along the first coordinate y 207 Z_s(img,:)=smooth(iy,40,'rloess');%smooth Z, the image index of max luminosity (dependning on x) 208 Yima=y_scan(img)*ones(size(x));%positions Y transformed into a vector 209 X_new(img,:)=phys_XYZ(Calib(img),x,Yima,1); 210 %X_new(:,img)=phys_scan(x,y(img)); 211 end 212 213 toc 214 215 [X,Y]=meshgrid(x,y_scan); 216 217 218 %% Load the current bed scan 219 for img=1:nb_scan 220 b=flipud(imread(filecell{2,img}));%image of the current bed 221 b=filter2(Mfiltre,b); % filtering 222 [imaxb,iyb]=max(b); 223 Z_sb(img,:)=smooth(iyb,20,'rloess'); 224 end 225 226 %% bed change 227 dZ=Z_s-Z_sb;% displacement between current position and initial 228 dZ_new=zeros(nb_scan,size(dZ,2)); 229 for img=1:nb_scan 230 Yima=y_scan(img)*ones(1,size(dZ,2)); 231 [~,dZ_new(img,:)]=phys_XYZ(Calib(img),dZ(img,:),Yima,1); 232 % dZ_new(:,img)=phys_scanz(dZ(:,img),y(img)); 233 end 234 235 236 %% PLOTS 237 coord_x=X_new(end,1):0.1:X_new(end,end); 238 [Y_m,X_m]=meshgrid(y_scan,coord_x); 239 %Y_new=Y'; 240 dZ_mesh=griddata(X_new,Y,dZ_new,X_m,Y_m); 241 242 if checkrun 243 figure(1) 244 hold on 245 plot(x,Z_s+700) 246 % xlim([0 4096]) 247 % ylim([0 3000]) 248 249 figure(2) 250 hold on 251 plot(x,Z_sb+700) 252 xlim([0 4096]) 253 ylim([0 3000]) 254 255 figure(3) 256 surfc(X_m,Y_m,dZ_mesh) 257 shading interp; 258 colorbar; 259 caxis([0 3]); 260 261 figure 262 pcolor(X_m,Y_m,dZ_mesh); 263 colormap; 264 set(gca,'Xdir','reverse'); 265 caxis([0 3]); 266 shading flat 267 hold on 268 colorbar 269 title('Dz') 270 end 271 272 %save(fullfile(DirOut,'18OS_f.mat'),'dZ','dZ_new','X','Y','Z_s','Z_sb','y') 273 274 % save netcdf 275 Data.ListVarName={'coord_x','coord_y','dZ'}; 276 Data.VarDimName={'coord_x','coord_y',{'coord_y','coord_x'}}; 277 Data.VarAttribute{1}.Role='coord_x'; 278 Data.VarAttribute{1}.unit='cm'; 279 Data.VarAttribute{2}.Role='coord_y'; 280 Data.VarAttribute{2}.unit='cm'; 281 Data.VarAttribute{3}.Role='scalar'; 282 Data.VarAttribute{3}.unit='cm'; 283 Data.coord_x=[coord_x(1) coord_x(end)]; 284 Data.coord_y=[y(1) y(end)]; 285 Data.dZ=dZ_mesh'; 286 struct2nc(fullfile(DirOut,'dZ.nc'),Data) 287 288 %% gives the physical position x from the image position X and the physical position y of the laser plane 289 function F=phys_scan(X,y) 290 % linear fct of X whose coefficient depend on y in a quadratic way 291 F=(9.4*10^(-7)*y.^2-3.09*10^(-4)*y+0.07).*X +(-0.001023*y.^2+0.469*y+186.9); 292 293 %% gives the physical position z from the image position Z and the physical position y of the laser plane 294 function Fz=phys_scanz(Z,y) 295 % scale factor applied to Z depending on the physical position y of the laser plane 296 Fz=(-1.4587*10^(-5)*y.^2 + 0.001072*y+0.0833).*Z; %+(-2.1*10^(-6)*x.^2+5.1*10^(-4)*x+0.0735).*Z; 297 298 235 disp(['last file of ' num2str(ifield)]) 236 disp(FileName) 237 disp(FrameIndex) 238 239 %% interpolate on a regular grid 240 %coord_x=X_phys(end,1):0.1:X_phys(end,end);%% coord x in phys coordinates based in the last view plane (the last) 241 [X_m,Y_m]=meshgrid(coord_x,y_scan); 242 Y=y_scan'*ones(1,nbx);%initialisation of X, Y final topography map 243 244 Data.Z=griddata(X_phys,Y,Z_phys,X_m,Y_m);% dZ interpolated on the regular ph1ys grid X_m,Y_m 245 size(Data.Z) 246 size(Data_init.Z_init) 247 Data.dZ=Data.Z-Data_init.Z_init; 248 249 toc 250 251 % save netcdf 252 Data.ListVarName={'coord_x','y_scan','Z','dZ'}; 253 Data.VarDimName={'coord_x','y_scan',{'y_scan','coord_x'},{'y_scan','coord_x'}}; 254 Data.VarAttribute{1}.Role='coord_x'; 255 Data.VarAttribute{1}.unit='cm'; 256 Data.VarAttribute{2}.Role='coord_y'; 257 Data.VarAttribute{2}.unit='cm'; 258 Data.VarAttribute{3}.Role='scalar'; 259 Data.VarAttribute{3}.unit='cm'; 260 Data.VarAttribute{4}.Role='scalar'; 261 Data.VarAttribute{4}.unit='cm'; 262 Data.coord_x=coord_x; 263 Data.y_scan=y_scan; 264 struct2nc(fullfile(DirOut,['dZ_' num2str(ifield) '.nc']),Data) 265 end 266 267 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 268 function iy=get_max(a)% get the max with sub picel resolution 269 [a_max,iy]=max(a); 270 [Nby,Nbx]=size(a); 271 for ind_x=1:Nbx 272 if iy(ind_x)>1 && iy(ind_x)<Nby 273 a_plus=a(iy(ind_x)+1,ind_x); 274 a_min=a(iy(ind_x)-1,ind_x); 275 denom=2*a_max(ind_x)-a_plus-a_min; 276 if denom >0 277 iy(ind_x)=iy(ind_x)+0.5*(a_plus-a_min)/denom;%adjust the position of the max with a quadratic fit of the three points around the max 278 end 279 end 280 end
Note: See TracChangeset
for help on using the changeset viewer.
