source: trunk/src/pivlab.m @ 233

Last change on this file since 233 was 233, checked in by sommeria, 13 years ago

small bug corrections, and improved display of image correlations (Testcvi1)

File size: 8.4 KB
Line 
1% 'pivlab': function piv.m adapted from PIVlab http://pivlab.blogspot.com/
2%--------------------------------------------------------------------------
3% function [xtable ytable utable vtable typevector] = pivlab (image1,image2,ibx,iby step, subpixfinder, mask, roi)
4%
5% OUTPUT:
6% xtable: set of x coordinates
7% ytable: set of y coordiantes
8% utable: set of u displacements (along x)
9% vtable: set of v displacements (along y)
10% ctable: max image correlation for each vector
11% typevector: set of flags, =1 for good, =0 for NaN vectors
12%
13%INPUT:
14% image1:first image (matrix)
15% image2: second image (matrix)
16% ibx,iby: size of the correlation box along x and y (in px)
17% step: mesh of the measurement points (in px)
18% subpixfinder=1 or 2 controls the curve fitting of the image correlation
19% mask: =[] for no mask
20% roi: 4 element vector defining a region of interest: x position, y position, width, height, (in image indices), for the whole image, roi=[];
21function [xtable ytable utable vtable ctable typevector result_conv errormsg] = pivlab (image1,image2,ibx2,iby2,isx2,isy2,shiftx,shifty, GridIndices, subpixfinder,mask)
22%this funtion performs the DCC PIV analysis. Recent window-deformation
23%methods perform better and will maybe be implemented in the future.
24errormsg='';
25warning off %MATLAB:log:logOfZero
26[npy_ima npx_ima]=size(image1);
27if ~isequal(size(image1),size(image2))
28    errormsg='image pair with unequal size';
29    return
30end
31    xroi=0;
32    yroi=0;
33    image1_roi=double(image1);
34    image2_roi=double(image2);
35if numel(mask)>0
36    cellmask=mask;
37    mask=zeros(size(image1));
38    for i=1:size(cellmask,1);
39        masklayerx=cellmask{i,1};
40        masklayery=cellmask{i,2};
41        mask = mask + poly2mask(masklayerx-xroi,masklayery-yroi,npy_ima,npx_ima); %kleineres eingangsbild und maske geshiftet
42    end
43else
44    mask=zeros(size(image1));
45end
46mask(mask>1)=1;
47
48% ibx=2*ibx2-1;%ibx and iby odd, reduced by 1 if even
49% iby=2*iby2-1;
50% miniy=1+iby2
51% minix=1+ibx2
52% maxiy=step*(floor(size(image1_roi,1)/step))-(iby-1)+iby2 %statt size deltax von ROI nehmen
53% maxix=step*(floor(size(image1_roi,2)/step))-(ibx-1)+ibx2
54% numelementsy=floor((maxiy-miniy)/step+1);
55% numelementsx=floor((maxix-minix)/step+1);
56%
57% LAy=miniy;
58% LAx=minix;
59% LUy=size(image1_roi,1)-maxiy;
60% LUx=size(image1_roi,2)-maxix;
61% shift4centery=round((LUy-LAy)/2);
62% shift4centerx=round((LUx-LAx)/2);
63% if shift4centery<0 %shift4center will be negative if in the unshifted case the left border is bigger than the right border. the vectormatrix is hence not centered on the image. the matrix cannot be shifted more towards the left border because then image2_crop would have a negative index. The only way to center the matrix would be to remove a column of vectors on the right side. but then we weould have less data....
64%     shift4centery=0;
65% end
66% if shift4centerx<0 %shift4center will be negative if in the unshifted case the left border is bigger than the right border. the vectormatrix is hence not centered on the image. the matrix cannot be shifted more towards the left border because then image2_crop would have a negative index. The only way to center the matrix would be to remove a column of vectors on the right side. but then we weould have less data....
67%     shift4centerx=0;
68% end
69% miniy=miniy+shift4centery;
70% minix=minix+shift4centerx;
71% maxix=maxix+shift4centerx;
72% maxiy=maxiy+shift4centery;
73
74image1_roi=padarray(image1_roi,[iby2 ibx2], min(min(image1_roi)));%add a border around the image with minimum image value
75image2_roi=padarray(image2_roi,[iby2 ibx2], min(min(image1_roi)));
76mask=padarray(mask,[iby2 ibx2],0);
77%SubPixOffset=0.5;%odd values chosen for ibx and iby
78
79nbvec=size(GridIndices,1);
80xtable=zeros(nbvec,1);
81ytable=xtable;
82utable=xtable;
83vtable=xtable;
84u2table=xtable;
85v2table=xtable;
86s2n=xtable;
87typevector=ones(size(xtable));
88
89nrx=0;
90nrxreal=0;
91nry=0;
92increments=0;
93
94%% MAINLOOP
95for ivec=1:nbvec
96    iref=GridIndices(ivec,1);
97    jref=GridIndices(ivec,2);
98    %jref=npy_ima-PointCoord(ivec,2)+1;
99    image1_crop=image1_roi(jref-iby2:jref+iby2,iref-ibx2:iref+ibx2);
100    image2_crop=image2_roi(jref+shifty-isy2:jref+shifty+isy2,iref+shiftx-isx2:iref+shiftx+isx2);
101    image1_crop=image1_crop-mean(mean(image1_crop));
102    image2_crop=image2_crop-mean(mean(image2_crop));
103        if mask(jref,iref)==0
104           %reference: Oliver Pust, PIV: Direct Cross-Correlation
105           % image2_crop: sub image with the size of the search area in image 2
106           % image1_crop: sub image of the correlation box in image 1
107           % %image2_crop is bigger than image1_crop. Zeropading is therefore not
108            result_conv= conv2(image2_crop,rot90(image1_crop,2),'valid');         
109            %necessary. 'Valid' makes sure that no zero padded content is returned.
110            corrmax= max(max(result_conv));
111            result_conv=(result_conv/corrmax)*255; %normalize, peak=always 255
112           % result_conv=flipdim(result_conv,2);%reverse x direction
113            %Find the 255 peak
114            [y,x] = find(result_conv==255);
115            if isnan(y)==0 & isnan(x)==0
116                try
117                    if subpixfinder==1
118                        [vector] = SUBPIXGAUSS (result_conv,x,y);
119                    elseif subpixfinder==2
120                        [vector] = SUBPIX2DGAUSS (result_conv,x,y);
121                    end
122                catch ME
123                    errormsg=ME.message
124                    vector=[0 0]; %if something goes wrong with cross correlation.....
125                end
126            else
127                vector=[0 0]; %if something goes wrong with cross correlation.....
128            end
129        else %if mask was not 0 then
130            vector=[0 0];
131            typevector(ivec)=0;
132        end
133
134        %Create the vector matrix x, y, u, v
135        xtable(ivec)=GridIndices(ivec,1);
136        ytable(ivec)=GridIndices(ivec,2);
137        utable(ivec)=vector(1);
138        vtable(ivec)=vector(2);
139        sum_square=sum(sum(image1_crop.*image1_crop));
140        ctable(ivec)=corrmax/sum_square;
141end
142result_conv=result_conv/255;
143
144
145function [vector] = SUBPIXGAUSS (result_conv,x,y)
146
147if size(x,1)>1 %if there are more than 1 peaks just take the first
148    x=x(1:1);
149end
150if size(y,1)>1 %if there are more than 1 peaks just take the first
151    y=y(1:1);
152end
153if (x <= (size(result_conv,1)-1)) && (y <= (size(result_conv,1)-1)) && (x >= 1) && (y >= 1)
154    %the following 8 lines are copyright (c) 1998, Uri Shavit, Roi Gurka, Alex Liberzon, Technion – Israel Institute of Technology
155    %http://urapiv.wordpress.com
156    f0 = log(result_conv(y,x));
157    f1 = log(result_conv(y-1,x));
158    f2 = log(result_conv(y+1,x));
159    peaky = y+ (f1-f2)/(2*f1-4*f0+2*f2);
160    f0 = log(result_conv(y,x));
161    f1 = log(result_conv(y,x-1));
162    f2 = log(result_conv(y,x+1));
163    peakx = x+ (f1-f2)/(2*f1-4*f0+2*f2);
164    [npy,npx]=size(result_conv);
165    vector=[peakx-floor(npx/2)-1 peaky-floor(npy/2)-1];
166else
167    vector=[NaN NaN];
168end
169
170function [vector] = SUBPIX2DGAUSS (result_conv,x,y)
171if size(x,1)>1 %if there are more than 1 peaks just take the first
172    x=x(1:1);
173end
174if size(y,1)>1 %if there are more than 1 peaks just take the first
175    y=y(1:1);
176end
177if (x <= (size(result_conv,1)-1)) && (y <= (size(result_conv,1)-1)) && (x >= 1) && (y >= 1)
178    for i=-1:1
179        for j=-1:1
180            %following 15 lines based on
181            %H. Nobach Æ M. Honkanen (2005)
182            %Two-dimensional Gaussian regression for sub-pixel displacement
183            %estimation in particle image velocimetry or particle position
184            %estimation in particle tracking velocimetry
185            %Experiments in Fluids (2005) 38: 511–515
186            c10(j+2,i+2)=i*log(result_conv(y+j, x+i));
187            c01(j+2,i+2)=j*log(result_conv(y+j, x+i));
188            c11(j+2,i+2)=i*j*log(result_conv(y+j, x+i));
189            c20(j+2,i+2)=(3*i^2-2)*log(result_conv(y+j, x+i));
190            c02(j+2,i+2)=(3*j^2-2)*log(result_conv(y+j, x+i));
191            %c00(j+2,i+2)=(5-3*i^2-3*j^2)*log(result_conv_norm(maxY+j, maxX+i));
192        end
193    end
194    c10=(1/6)*sum(sum(c10));
195    c01=(1/6)*sum(sum(c01));
196    c11=(1/4)*sum(sum(c11));
197    c20=(1/6)*sum(sum(c20));
198    c02=(1/6)*sum(sum(c02));
199    deltax=(c11*c01-2*c10*c02)/(4*c20*c02-c11^2);
200    deltay=(c11*c10-2*c01*c20)/(4*c20*c02-c11^2);
201    peakx=x+deltax;
202    peaky=y+deltay;
203   
204    [npy,npx]=size(result_conv);
205    vector=[peakx-floor(npx/2)-1 peaky-floor(npy/2)-1];
206%     SubpixelX=peakx-(ibx/2)-SubPixOffset;
207%     SubpixelY=peaky-(iby/2)-SubPixOffset;
208%     vector=[SubpixelX, SubpixelY];
209else
210    vector=[NaN NaN];
211end
Note: See TracBrowser for help on using the repository browser.