source: trunk/src/series/sub_background.m @ 89

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

many bug corrections and cleaning. Activation of the BW option in uvmat. Improvement of the interaction of get_field with uvmat.

File size: 15.0 KB
Line 
1%----------------------------------------------------------------------
2% --- substract background to the images: rank the images by luminosity at each point and substracts to the images
3%----------------------------------------------------------------------
4% Method:
5    %calculate the background image by sorting the luminosity of each point
6    % over a sliding sub-sequence of 'nbaver_ima' images.
7    % The luminosity value of rank 'rank' is selected as the
8    % 'background'. rank=nbimages/2 gives the median value.  Smaller values are appropriate
9    % for a dense set of particles. The extrem value rank=1 gives the true minimum
10    % luminosity, but it can be polluted by noise.
11% Organization of image indices:
12    % The program is working on a series of images, labelled by two indices i and j, given
13    % by the input matlab vectors num_i1 and num_j1 respectively. In the list, j is the fastest increasing index.
14    % The processing can be done in slices (number nbslice), with bursts of
15    % nbfield2 successive images for a given slice (mode 'multilevel')
16    % In the mode 'volume', nbfield2=1 (1 image at each level), and
17    % nbslice=
18%INPUT:
19% num_i1: matrix of image indices i
20% num_j1: matrix of image indices j, must be the same size as num_i1
21% num_i2 and num_j2: not used for a function acting on images
22% Series: matlab structure containing parameters, as defined by the interface UVMAT/series
23%       Series.RootPath: path to the image series
24%       Series.RootFile: root file name
25%       Series.FileExt: image file extension
26%       Series.NomType: nomenclature type for file indexing
27%       Series.NbSlice: %number of slices defined on the interface
28
29function GUI_input=sub_background (num_i1,num_i2,num_j1,num_j2,Series)
30
31%------------------------------------------------------------------------
32%requests for the visibility of input windows in the GUI series  (activated directly by the selection in the menu ACTION)
33if ~exist('num_i1','var')
34    GUI_input={'RootPath';'on';...
35        'SubDir';'off';... % subdirectory of derived files (PIV fields), ('on' by default)
36        'RootFile';'on';... %root input file name ('on' by default)
37        'FileExt';'on';... %inputf file extension ('on' by default)
38        'NomType';'on';...%type of file indexing ('on' by default)
39        'NbSlice';'on'; ...%nbre of slices ('off' by default)
40        %'VelTypeMenu';'on';...% menu for selecting the velocity type (civ1,..)('off' by default)
41        %'FieldMenu';'on';...% menu for selecting the velocity field (s) in the input file ('off' by default)
42        %'VelTypeMenu_1';'on';...% menu for selecting the velocity type (civ1,..)('off' by default)
43        %'FieldMenu_1';'on';...% menu for selecting the velocity field (s) in the input file ('off' by default)
44        %'CoordType';...%can use a transform function
45        %'GetObject';...;%can use projection object
46        %'GetMask';...;%can use mask option 
47        'PARAMETER';'NbSliding';...
48        'PARAMETER';'VolumeScan';...
49        'PARAMETER';'RankBrightness';...
50               ''};
51    return %exit the function
52end
53
54%----------------------------------------------------------------
55% initiate the waitbar
56hseries=guidata(Series.hseries);%handles of the GUI series
57WaitbarPos=get(hseries.waitbar_frame,'Position');
58%-----------------------------------------------------------------
59if iscell(Series.RootPath)
60    msgbox_uvmat('ERROR','This function use only one input image series')
61    return
62end
63
64%determine input image type
65FileType=[];%default
66MovieObject=[];
67FileExt=Series.FileExt;
68
69if isequal(lower(FileExt),'.avi')
70    hhh=which('mmreader');
71    if ~isequal(hhh,'')&& mmreader.isPlatformSupported()
72        MovieObject=mmreader(fullfile(RootPath,[RootFile FileExt]));
73        FileType='movie';
74    else
75        FileType='avi';
76    end
77elseif isequal(lower(FileExt),'.vol')
78    FileType='vol';
79else
80   form=imformats(FileExt(2:end));
81   if ~isempty(form)% if the extension corresponds to an image format recognized by Matlab
82       if isequal(Series.NomType,'*');
83           FileType='multimage';
84       else
85           FileType='image';
86       end
87   end
88end
89if isempty(FileType)
90    msgbox_uvmat('ERROR',['invalid file extension ' FileExt ': this function only accepts image or movie input'])
91    return
92end
93
94nbslice_i=Series.NbSlice; %number of slices
95siz=size(num_i1);
96nbaver_init=23;%approximate number of images used for the sliding background: to be adjusted later to include an integer number of bursts
97
98%adjust the proposed number of images in the sliding average to include an integer number of bursts
99if siz(2)~=1
100    nbaver=floor(nbaver_init/siz(1)); % number of bursts used for the sliding background,
101    if isequal(floor(nbaver/2),nbaver)
102        nbaver=nbaver+1;%put the number of burst to an odd number (so the middle burst is defined)
103    end
104    nbaver_init=nbaver*siz(1);%propose by default an integer number of bursts
105end
106
107filebase=fullfile(Series.RootPath,Series.RootFile);
108dir_images=Series.RootPath;
109nom_type=Series.NomType;
110
111%create dir of the new images
112[dir_images,namebase]=fileparts(filebase);
113[path,subdir_ima]=fileparts(dir_images);
114curdir=pwd;
115cd(path);
116mkdir([subdir_ima '_b']);
117cd(curdir);
118filebase_b=fullfile(path,[subdir_ima '_b'],namebase);
119
120prompt = {'Number of images for the sliding background';'The number of positions (laser slices)';'volume scan mode (Yes/No)';...
121        'the luminosity rank chosen to define the background (0.1=for dense particle seeding, 0.5 (median) for sparse particles'};
122dlg_title = ['get (slice by slice) a sliding background and substract to each image, result in subdir ' subdir_ima '_b'];
123num_lines= 3;
124def     = { num2str(nbaver_init);num2str(nbslice_i);'No';'0.1'};
125answer = inputdlg(prompt,dlg_title,num_lines,def);
126set(hseries.ParamVal,'String',answer([1 [3:4]]))
127set(hseries.ParamVal,'Visible','on')
128
129nbaver_ima=str2num(answer{1});%number of images for the sliding background
130nbaver=ceil(nbaver_ima/siz(1))%number of bursts for the sliding background
131if isequal(floor(nbaver/2),nbaver)
132   nbaver=nbaver+1%put the number of burst to an odd number (so the middle burst is defined)
133end
134% if isequal(nbaver,round(nbaver))
135step=siz(1);%case of bursts: the sliding background is shifted by one burst
136% else
137%    step=1;
138% end
139vol_test=answer{3};
140if isequal(vol_test,'Yes')
141    nbfield2=1;%case of volume: no consecutive series at a given level
142    nbslice_i=siz(1);%number of slices
143else
144    nbfield2=siz(1); %nb of consecutive images at each level(burst)
145    if siz(2)>1
146       nbslice_i=str2num(answer{2})/(num_i1(1,2)-num_i1(1,1));% number of slices
147    else
148        nbslice_i=1;
149    end
150    if ~isequal(floor(nbslice_i),nbslice_i)
151        msgbox_uvmat('ERROR','the number of slices must be a multiple of the i increment')
152        return
153    end
154end
155% nbaver=floor(nbaver_init/nbfield2); % number of bursts used for the sliding background,
156% if isequal(floor(nbaver/2),nbaver)
157%     nbaver=nbaver+1;%put the number of burst to an odd number
158% end
159%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
160%nbaver_ima=nbaver*nbfield2;% adjust the number of sliding images A  REMETRE
161% if ~isequal(nbaver_ima,nbaver_init)
162%     hwarn=warndlg(['number of images in the sliding average adjusted to ' num2str(nbaver_ima)]);
163%     set(hwarn,'Units','normalized')
164%     set(hwarn,'Position',[0.3 0.3 0.4 0.1])
165% end
166%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
167rank=floor(str2num(answer{4})*nbaver_ima);
168if rank==0
169    rank=1;%rank selected in the sorted image series
170end
171lengthtot=siz(1)*siz(2);
172nbfield=floor(lengthtot/(nbfield2*nbslice_i));%total number of i indexes (adjusted to an integer number of slices)
173nbfield_slice=nbfield*nbfield2;% number of fields per slice
174% test_plot=isequal(answer{5},'Yes'); %=1 to display background images
175if nbaver_ima > nbfield*nbfield2
176    errordlg('number of images in a slice smaller than the proposed number of images for the sliding average')
177    return
178end
179nbfirst=(ceil(nbaver/2))*step;
180if nbfirst>nbaver_ima
181    nbfirst=ceil(nbaver_ima/2)
182    step=1;
183    nbaver=nbaver_ima;
184end
185
186%copy the xml file
187if exist([filebase '.xml'],'file')
188    copyfile([filebase '.xml'],[filebase_b '.xml']);% copy the .civ file
189    t=xmltree([filebase_b '.xml']);
190   
191    %update information on the first image name in the series
192    uid_Heading=find(t,'ImaDoc/Heading');
193    if isempty(uid_Heading)
194        [t,uid_Heading]=add(t,1,'element','Heading');
195    end   
196    uid_ImageName=find(t,'ImaDoc/Heading/ImageName');
197    ImageName=name_generator(filebase_b,num_i1(1),num_j1(1),'.png',Series.NomType);
198    [pth,ImageName]=fileparts(ImageName);
199    ImageName=[ImageName '.png']
200    if isempty(uid_ImageName)
201       [t,uid_ImageName]=add(t,uid_Heading,'element','ImageName');
202    end
203    uid_value=children(t,uid_ImageName);
204    if isempty(uid_value)
205        t=add(t,uid_ImageName,'chardata',ImageName)%indicate  name of the first image, with ;png extension
206    else
207        t=set(t,uid_value(1),'value',ImageName)%indicate  name of the first image, with ;png extension
208    end 
209
210    %add information about image transform
211    [t,new_uid]=add(t,1,'element','ImageTransform');
212    [t,NameFunction_uid]=add(t,new_uid,'element','NameFunction');
213    [t]=add(t,NameFunction_uid,'chardata','sub_background');     
214    [t,NbSlice_uid]=add(t,new_uid,'element','NbSlice');
215    [t]=add(t,new_uid,'chardata',num2str(nbslice_i));
216    [t,NbSlidingImages_uid]=add(t,new_uid,'element','NbSlidingImages');
217    [t]=add(t,NbSlidingImages_uid,'chardata',num2str(nbaver));
218    [t,LuminosityRank_uid]=add(t,new_uid,'element','RankBackground');
219    [t]=add(t,LuminosityRank_uid,'chardata',num2str(rank));% luminosity rank almong the nbaver sliding images
220    save(t,[filebase_b '.xml'])
221elseif exist([filebase '.civ'],'file')
222    copyfile([filebase '.civ'],[filebase_b '.civ']);% copy the .civ file
223end
224%copy the mask
225if exist([filebase '_1mask_1'],'file')
226     copyfile([filebase '_1mask_1'],[filebase_b '_1mask_1']);% copy the mask file
227end
228
229%MAIN LOOP ON SLICES
230for islice=1:nbslice_i
231    %select the series of image indices at the level islice
232    for ifield=1:nbfield
233        for iburst=1:nbfield2
234            indselect(iburst,ifield)=((ifield-1)*nbslice_i+(islice-1))*nbfield2+iburst;
235        end
236    end 
237    %read the first series of nbaver_ima images and sort by luminosity at each pixel
238    for ifield = 1:nbaver_ima
239        ifile=indselect(ifield);
240        filename=name_generator(filebase,num_i1(ifile),num_j1(ifile),Series.FileExt,Series.NomType);
241        Aread=read_image(filename,FileType,num_i1(ifile),MovieObject);
242        Ak(:,:,ifield)=Aread;           
243    end
244    Asort=sort(Ak,3);%sort the luminosity of images at each point
245    B=Asort(:,:,rank);%background image
246%
247%     namemean=name_generator([filebase '_back'],islice,[],'.png','_i');% makes the file name
248%     imwrite(B,namemean,'BitDepth',16); % save the first background image
249%     ['background image for slice ' num2str(islice) ' saved in ' namemean]
250    %substract the background from each of the first images and save the new images
251%     for ifield=1:floor(nbaver_ima/2)+1
252    'first background image will be substracted'
253
254    for ifield=1:nbfirst
255            Acor=double(Ak(:,:,ifield))-double(B);%substract background to the current image
256            Acor=(Acor>0).*Acor; % put to 0 the negative elements in Acor
257            C=uint16(Acor);% set to integer 16 bits
258            ifile=indselect(ifield);
259            newname=name_generator(filebase_b,num_i1(ifile),num_j1(ifile),'.png',nom_type)% makes the new file name
260            imwrite(C,newname,'BitDepth',16); % save the new image
261    end
262    %repeat the operation on a sliding series of nbaver*nbfield2 images
263    'sliding background image will be substracted'
264    if nbfield_slice > nbaver_ima
265%         for ifield = floor(nbaver_ima/2)+2:step:nbfield_slice-floor(nbaver_ima/2)
266        for ifield = step*ceil(nbaver/2)+1:step:nbfield_slice-step*floor(nbaver/2)
267            stopstate=get(hseries.RUN,'BusyAction');
268            if isequal(stopstate,'queue')% enable STOP command
269                update_waitbar(hseries.waitbar,WaitbarPos,(ifield+(islice-1)*nbfield_slice)/(nbfield_slice*nbslice_i))
270                (ifield+(islice-1)*nbfield_slice)/(nbfield_slice*nbslice_i)
271                Ak(:,:,[1:nbaver_ima-step])=Ak(:,:,[1+step:nbaver_ima]);% shift the current image series by one burst (step)
272                %incorporate next burst in the current image series
273                for iburst=1:step
274                    ifile=indselect(ifield+step*floor(nbaver/2)+iburst-1);
275                    filename=name_generator(filebase,num_i1(ifile),num_j1(ifile),Series.FileExt,Series.NomType);
276                    Aread=read_image(filename,FileType,num_i1(ifile),MovieObject);
277                    Ak(:,:,nbaver_ima-step+iburst)=Aread;
278                end
279                Asort=sort(Ak,3);%sort the new current image series by luminosity
280                B=Asort(:,:,rank);%current background image
281                for iburst=1:step
282%                     Acor=double(Ak(:,:,floor(nbaver_ima/2)+iburst-1))-double(B);
283                    index=step*floor(nbaver/2)+iburst;
284                    Acor=double(Ak(:,:,index))-double(B);
285                    Acor=(Acor>0).*Acor; % put to 0 the negative elements in Acor
286                    C=uint16(Acor);
287                    ifile=indselect(ifield+iburst-1);
288                    [newname]=...
289                       name_generator(filebase_b,num_i1(ifile),num_j1(ifile),'.png',Series.NomType)
290%                     newname=name_generator(filebase_b,num_i1(indselect(ifield+iburst-1)),num_j1(indselect(ifield+iburst-1)),'.png',nom_type)% makes the new file name
291                    imwrite(C,newname,'BitDepth',16); % save the new image
292                end 
293            else
294                return
295            end
296        end
297    end
298
299%substract the background from the last images
300%     for ifield=nbfield_slice-floor(nbaver_ima/2)+1:nbfield_slice
301     'last background image will be substracted'
302     ifield=nbfield_slice-(step*ceil(nbaver/2))+1:nbfield_slice;
303    for ifield=nbfield_slice-(step*floor(nbaver/2))+1:nbfield_slice 
304        index=ifield-nbfield_slice+step*(2*floor(nbaver/2)+1);
305        Acor=double(Ak(:,:,index))-double(B);
306        Acor=(Acor>0).*Acor; % put to 0 the negative elements in Acor
307        C=uint16(Acor);
308        ifile=indselect(ifield);
309        newname=name_generator(filebase_b,num_i1(ifile),num_j1(ifile),'.png',nom_type)% makes the new file name
310        imwrite(C,newname,'BitDepth',16); % save the new image
311    end
312end
313
314%finish the waitbar
315update_waitbar(hseries.waitbar,WaitbarPos,1)
316
317
318%------------------------------------------------------------------------
319%--read images and convert them to the uint16 format used for PIV
320function A=read_image(filename,type_ima,num,MovieObject)
321%------------------------------------------------------------------------
322%num is the view number needed for an avi movie
323switch type_ima
324    case 'movie'
325        A=read(MovieObject,num);
326    case 'avi'
327        mov=aviread(filename,num);
328        A=frame2im(mov(1));
329    case 'multimage'
330        A=imread(filename,num);
331    case 'image'   
332        A=imread(filename);
333end
334siz=size(A);
335if length(siz)==3;%color images
336    A=sum(double(A),3);
337end
338   
Note: See TracBrowser for help on using the repository browser.