source: trunk/src/RUN_STLIN.m @ 589

Last change on this file since 589 was 264, checked in by sommeria, 10 years ago

stereo option repaired

File size: 9.4 KB
Line 
1%'RUN_STLIN': combine velocity fields for stereo PIV
2% file_A,file_B: input velocity files
3%vel_type: string ='civ1' or 'civ2'
4function RUN_STLIN(file_A,file_B,vel_type,file_st,nx_patch,ny_patch,thresh_patch,fileAxml,fileBxml)
5               
6 [XmlDataA,error]=imadoc2struct(fileAxml);%read xml file associated to image series A
7 [XmlDataB,error]=imadoc2struct(fileBxml);%read xml file associated to image series B
8 npxA=[]; npyA=[]; pxB=[]; npyB=[];
9 if isfield(XmlDataA,'Camera') && isfield(XmlDataB,'Camera')
10      if isfield(XmlDataA.Camera,'ImageSize')&& isfield(XmlDataB.Camera,'ImageSize')
11          ImageSizeA=XmlDataA.Camera.ImageSize;
12          ImageSizeB=XmlDataB.Camera.ImageSize;
13          if ~isempty(ImageSizeA)&& ~isempty(ImageSizeB)
14               xindex=findstr(ImageSizeA,'x');
15               if length(xindex)>=2
16                    npxA=str2num(ImageSizeA(1:xindex(1)-1));
17                    npyA=str2num(ImageSizeA(xindex(1)+1:xindex(2)-1));
18               end
19               xindex=findstr(ImageSizeB,'x');
20               if length(xindex)>=2
21                    npxB=str2num(ImageSizeB(1:xindex(1)-1));
22                    npyB=str2num(ImageSizeB(xindex(1)+1:xindex(2)-1));
23               end
24          end
25     end
26 end
27 %%%%%%%% added for Duran
28 if isfield(XmlDataA,'Npx')&&isfield(XmlDataA,'Npy')&&isfield(XmlDataB,'Npx')&&isfield(XmlDataB,'Npy')
29     npxA=XmlDataA.Npx;
30     npyA=XmlDataA.Npy;
31     npxB=XmlDataB.Npx;
32     npyB=XmlDataB.Npy;
33 end
34 %%%%%%%% added for Duran
35 if isempty(npxA) ||isempty(npxB)
36     msgbox_uvmat('ERROR','The size of image A needs to be defined in the xml file ImaDoc')
37     return
38 elseif isempty(npxB) || isempty(npyB)
39      msgbox_uvmat('ERROR','The size of image B needs to be defined in the xml file ImaDoc')
40     return
41 end
42 if isfield(XmlDataA,'GeometryCalib')
43     tsaiA=XmlDataA.GeometryCalib;
44 else
45     msgbox_uvmat('ERROR','no geometric calibration available for image A')
46     return
47 end
48 if isfield(XmlDataB,'GeometryCalib')
49     tsaiB=XmlDataB.GeometryCalib;
50 else
51     msgbox_uvmat('ERROR','no geometric calibration available for image B')
52     return
53 end
54 
55 %corners of each image in px coordinates:
56 cornerA(:,1)=[0 0 npxA npxA]';%x positions
57 cornerA(:,2)=[0 npyA 0 npyA]';%y positions
58 cornerB(:,1)=[0 0 npxB npxB]';%x positions
59 cornerB(:,2)=[0 npyB 0 npyB]';%y positions
60  %corners of each image in phys coordinates:
61[xyA(:,1),xyA(:,2)]=phys_XYZ(tsaiA,cornerA(:,1),cornerA(:,2));
62[xyB(:,1),xyB(:,2)]=phys_XYZ(tsaiB,cornerB(:,1),cornerB(:,2));
63 max_x=max(max(xyA(:,1)),max(xyB(:,1)));%maximum on the 4 corners of the the images
64 min_x=min(min(xyA(:,1)),min(xyB(:,1)));%minimum on the 4 corners of the the images
65 max_y=max(max(xyA(:,2)),max(xyB(:,2)));
66 min_y=min(min(xyA(:,2)),min(xyB(:,2)));
67 array_realx=[min_x:(max_x-min_x)/(nx_patch-1):max_x];
68 array_realy=[min_y:(max_y-min_y)/(ny_patch-1):max_y];
69 [grid_realx,grid_realy]=meshgrid(array_realx,array_realy);
70 grid_real(:,1)=reshape(grid_realx,nx_patch*ny_patch,1);
71 grid_real(:,2)=reshape(grid_realy,nx_patch*ny_patch,1);
72 grid_real(:,3)=zeros(nx_patch*ny_patch,1);
73[grid_imaA(:,1),grid_imaA(:,2)]=px_XYZ(tsaiA,grid_real(:,1),grid_real(:,2));
74[grid_imaB(:,1),grid_imaB(:,2)]=px_XYZ(tsaiB,grid_real(:,1),grid_real(:,2));
75
76 flagA=grid_imaA(:,1)>0 & grid_imaA(:,1)<npxA & grid_imaA(:,2)>0 & grid_imaA(:,2)<npyA;
77 flagB=grid_imaB(:,1)>0 & grid_imaB(:,1)<npxB & grid_imaB(:,2)>0 & grid_imaB(:,2)<npyB;
78 ind_good=find(flagA==1&flagB==1);
79 XimaA=grid_imaA(ind_good,1);
80 YimaA=grid_imaA(ind_good,2);
81 XimaB=grid_imaB(ind_good,1);
82 YimaB=grid_imaB(ind_good,2);
83 grid_real_x=grid_real(ind_good,1);
84 grid_real_y=grid_real(ind_good,2);
85
86% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
87% %read the velocity fields
88% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89%read field A
90[Field,VelTypeOut]=read_civxdata(file_A,[],vel_type);
91%removes false vectors
92if isfield(Field,'FF')
93    Field.X=Field.X(find(Field.FF==0));
94    Field.Y=Field.Y(find(Field.FF==0));
95    Field.U=Field.U(find(Field.FF==0));
96    Field.V=Field.V(find(Field.FF==0));
97end
98%interpolate on the grid common to both images in phys coordinates
99dXa= griddata_uvmat(Field.X,Field.Y,Field.U,XimaA,YimaA);
100dYa= griddata_uvmat(Field.X,Field.Y,Field.V,XimaA,YimaA);
101dt=Field.dt;
102time=Field.Time;
103
104%read field B
105[Field,VelTypeOut]=read_civxdata(file_B,[],vel_type);
106if ~isequal(Field.dt,dt)
107    msgbox_uvmat('ERROR','different time intervals for the two velocity fields ')
108     return
109end
110if ~isequal(Field.Time,time)
111    msgbox_uvmat('ERROR','different times for the two velocity fields ')
112     return
113end
114%removes false vectors
115if isfield(Field,'FF')
116Field.X=Field.X(find(Field.FF==0));
117Field.Y=Field.Y(find(Field.FF==0));
118Field.U=Field.U(find(Field.FF==0));
119Field.V=Field.V(find(Field.FF==0));
120end
121%interpolate on XimaB
122dXb=griddata_uvmat(Field.X,Field.Y,Field.U,XimaB,YimaB);
123dYb=griddata_uvmat(Field.X,Field.Y,Field.V,XimaB,YimaB);
124%eliminate Not-a-Number
125ind_Nan=find(and(~isnan(dXa),~isnan(dXb)));
126dXa=dXa(ind_Nan);
127dYa=dYa(ind_Nan);
128dXb=dXb(ind_Nan);
129dYb=dYb(ind_Nan);
130grid_phys1(:,1)=grid_real_x(ind_Nan);
131grid_phys1(:,2)=grid_real_y(ind_Nan);
132 
133%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134%compute the differential coefficients of the geometric calibration
135%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136[A11,A12,A13,A21,A22,A23]=pxcm_tsai(tsaiA,grid_phys1);
137[B11,B12,B13,B21,B22,B23]=pxcm_tsai(tsaiB,grid_phys1);
138
139C1=A11.*A22-A12.*A21;
140C2=A13.*A22-A12.*A23;
141C3=A13.*A21-A11.*A23;
142D1=B11.*B22-B12.*B21;
143D2=B13.*B22-B12.*B23;
144D3=B13.*B21-B11.*B23;
145A1=(A22.*D1.*(C1.*D3-C3.*D1)+A21.*D1.*(C2.*D1-C1.*D2));
146A2=(A12.*D1.*(C3.*D1-C1.*D3)+A11.*D1.*(C1.*D2-C2.*D1));
147B1=(B22.*C1.*(C3.*D1-C1.*D3)+B21.*C1.*(C1.*D2-C2.*D1));
148B2=(B12.*C1.*(C1.*D3-C3.*D1)+B11.*C1.*(C2.*D1-C1.*D2));
149Lambda=(A1.*dXa+A2.*dYa+B1.*dXb+B2.*dYb)./(A1.*A1+A2.*A2+B1.*B1+B2.*B2);
150
151%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
152%Projection for compatible displacements
153%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
154Ua=dXa-Lambda.*A1;
155Va=dYa-Lambda.*A2;
156Ub=dXb-Lambda.*B1;
157Vb=dYb-Lambda.*B2;
158
159%%%%%%%%%%%%%%%%%%%%%%%%%%%%
160%Calculations of displacements and error
161%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
162U=(A22.*D2.*Ua-A12.*D2.*Va-B22.*C2.*Ub+B12.*C2.*Vb)./(C1.*D2-C2.*D1);
163V=(A21.*D3.*Ua-A11.*D3.*Va-B21.*C3.*Ub+B11.*C3.*Vb)./(C3.*D1-C1.*D3);
164W=(A22.*D1.*Ua-A12.*D1.*Va-B22.*C1.*Ub+B12.*C1.*Vb)./(C2.*D1-C1.*D2);
165W1=(-A21.*D1.*Ua+A11.*D1.*Va+B21.*C1.*Ub-B11.*C1.*Vb)./(C1.*D3-C3.*D1);
166
167error=sqrt((A1.*dXa+A2.*dYa+B1.*dXb+B2.*dYb).*(A1.*dXa+A2.*dYa+B1.*dXb+B2.*dYb)./(A1.*A1+A2.*A2+B1.*B1+B2.*B2));
168
169ind_error=(find(error<thresh_patch));
170U=U(ind_error);
171V=V(ind_error);
172W=W(ind_error);%correction for water interface
173error=error(ind_error);
174
175%create nc grid file
176Result.ListGlobalAttribute={'nb_coord','nb_dim','constant_pixcm','absolut_time_T0','hart','dt','civ'};
177Result.nb_coord=3;%grid file, no velocity
178Result.nb_dim=2;
179Result.constant_pixcm=0;%no linear correspondance with images
180Result.absolut_time_T0=time;%absolute time of the field
181Result.hart=0;
182Result.dt=dt;%time interval for image correlation (put  by default)
183% cte.title='grid';
184Result.civ=0;%not a civ file (no direct correspondance with an image)
185% Result.ListDimName={'nb_vectors'}
186% Result.DimValue=length(U);
187Result.ListVarName={'vec_X','vec_Y','vec_U','vec_V','vec_W','vec_E'};
188Result.VarDimName={'nb_vectors','nb_vectors','nb_vectors','nb_vectors','nb_vectors','nb_vectors'}
189Result.vec_X= grid_phys1(ind_error,1);
190Result.vec_Y= grid_phys1(ind_error,2);
191Result.vec_U=U/dt;
192Result.vec_V=V/dt;
193Result.vec_W=W/dt;
194Result.vec_E=error;
195% error=write_netcdf(file_st,cte,fieldlabels,grid_phys);
196error=struct2nc(file_st,Result);
197display([file_st ' written'])
198
199
200
201%'pxcm_tsai': find differentials of the Tsai calibration
202function [A11,A12,A13,A21,A22,A23]=pxcm_tsai(a,var_phys)
203R=(a.R)';
204
205x=var_phys(:,1);
206y=var_phys(:,2);
207
208if isfield(a,'PlanePos')
209    prompt={'Plane 1 Index','Plane 2 Index'};
210    Rep=inputdlg(prompt,'Target displacement test');
211    Z1=str2double(Rep(1));
212    Z2=str2double(Rep(2));
213    z=(a.PlanePos(Z2,3)+a.PlanePos(Z1,3))/2
214else
215    z=0;
216end
217
218%transform coeff for differentiels
219a.C11=R(1)*R(8)-R(2)*R(7);
220a.C12=R(2)*R(7)-R(1)*R(8);
221a.C21=R(4)*R(8)-R(5)*R(7);
222a.C22=R(5)*R(7)-R(4)*R(8);
223a.C1x=R(3)*R(7)-R(9)*R(1);
224a.C1y=R(3)*R(8)-R(9)*R(2);
225a.C2x=R(6)*R(7)-R(9)*R(4);
226a.C2y=R(6)*R(8)-R(9)*R(5);
227
228% %dependence in x,y
229% denom=(R(7)*x+R(8)*y+R(9)*z+a.Tz).*(R(7)*x+R(8)*y+R(9)*z+a.Tz);
230% A11=(a.f*a.sx*(a.C11*y-a.C1x*z+R(1)*a.Tz-R(7)*a.Tx)./denom)/a.dpx;
231% A12=(a.f*a.sx*(a.C12*x-a.C1y*z+R(2)*a.Tz-R(8)*a.Tx)./denom)/a.dpx;
232% A21=(a.f*a.sx*(a.C21*y-a.C2x*z+R(4)*a.Tz-R(7)*a.Ty)./denom)/a.dpy;
233% A22=(a.f*(a.C22*x-a.C2y*z+R(5)*a.Tz-R(8)*a.Ty)./denom)/a.dpy;
234% A13=(a.f*(a.C1x*x+a.C1y*y+R(3)*a.Tz-R(9)*a.Tx)./denom)/a.dpx;
235% A23=(a.f*(a.C2x*x+a.C2y*y+R(6)*a.Tz-R(9)*a.Ty)./denom)/a.dpy;
236
237%dependence in x,y
238denom=(R(7)*x+R(8)*y+R(9)*z+a.Tx_Ty_Tz(3)).*(R(7)*x+R(8)*y+R(9)*z+a.Tx_Ty_Tz(3));
239A11=(a.fx_fy(1)*(a.C11*y-a.C1x*z+R(1)*a.Tx_Ty_Tz(3)-R(7)*a.Tx_Ty_Tz(1))./denom);
240A12=(a.fx_fy(1)*(a.C12*x-a.C1y*z+R(2)*a.Tx_Ty_Tz(3)-R(8)*a.Tx_Ty_Tz(1))./denom);
241A21=(a.fx_fy(1)*(a.C21*y-a.C2x*z+R(4)*a.Tx_Ty_Tz(3)-R(7)*a.Tx_Ty_Tz(2))./denom);
242A22=(a.fx_fy(2)*(a.C22*x-a.C2y*z+R(5)*a.Tx_Ty_Tz(3)-R(8)*a.Tx_Ty_Tz(2))./denom);
243A13=(a.fx_fy(2)*(a.C1x*x+a.C1y*y+R(3)*a.Tx_Ty_Tz(3)-R(9)*a.Tx_Ty_Tz(1))./denom);
244A23=(a.fx_fy(2)*(a.C2x*x+a.C2y*y+R(6)*a.Tx_Ty_Tz(3)-R(9)*a.Tx_Ty_Tz(2))./denom);
245
246
247
248
249
250
251
252
Note: See TracBrowser for help on using the repository browser.