/normxcorr/trunk

To get this branch, use:
bzr branch http://darksoft.org/webbzr/normxcorr/trunk
1 by Suren A. Chilingaryan
Initial import
1
function [validx,validy]=automate_image(grid_x,grid_y,filenamelist,validx,validy);
2
3
% Code to start actual image correlation
4
% Programmed by Chris and Rob
5
% Last revision: 09/10/08
6
7
% The automation function is the central function and processes all markers and 
8
% images by the use of the matlab function cpcorr.m. 
9
% Therefore the Current directory in matlab has to be the folder where 
10
%  automate_image.m finds the filenamelist.mat, grid_x.dat and grid_y.dat as well 
11
% as the images specified in filenamelist.mat. Just type automate_image; and 
12
% press ENTER at the command line of matlab. 
13
% At first, automate_image.m will open the first image in the filenamelist.mat and 
14
% plot the grid as green crosses on top. The next step will need some time since 
15
% all markers in that image have to be processed for the first image. After correlating 
16
% image one and two the new raster positions will be plotted as red crosses. On top 
17
% of the image and the green crosses. The next dialog will ask you if you want to 
18
% continue with this correlation or cancel. If you press continue, automate_image.m 
19
% will process all images in the filenamelist.mat. The time it will take to process 
20
% all images will be plotted on the figure but can easily be estimated by knowing the 
21
% raster point processing speed (see processing speed). 
22
% Depending on the number of images and markers you are tracking, this process 
23
% can take between seconds and days. For 100 images and 200 markers a decent 
24
% computer should need 200 seconds. To get a better resolution you can always 
25
% run jobs overnight (e.g. 6000 markers in 1000 images) with higher resolutions. 
26
% Keep in mind that CORRSIZE which you changed in cpcorr.m will limit your 
27
% resolution. If you chose to use the 15 pixel as suggested a marker distance of 
28
% 30 pixel will lead to a full cover of the strain field. Choosing smaller marker 
29
% distances will lead to an interpolation since two neighboring markers share 
30
% pixels. Nevertheless a higher marker density can reduce the noise of the strain field.
31
% When all images are processed, automate_image will write the files validx.mat, 
32
% validy.mat, validx.txt and validy.txt. The text files are meant to store the result in a 
33
% format which can be accessed by other programs also in the future.
34
2 by Suren A. Chilingaryan
Support for different optimization modes
35
% Changed by Suren A. Chilingaryan <csa@dside.dyndns.org> to optimize performance
36
% by tighter integration with Matlab images toolkit (few sources from the toolkit
37
% are moved to the current source tree and adjusted to benefit from knowledge of 
38
% tasks we are solving here. As well CUDA framework, if available, is used to
39
% speed-up core computations using parallel processors of latest NVidia video
40
% cards.
41
% OPTIMIZE parameter is controlling which optimizations should be used. 
42
%  0 - The original version, no optimizations
41 by Suren A. Chilingaryan
Synchronize with Chris version, set precision to 1, initial implementation of labview wrapper
43
%  1 - The modified sources from images toolkit, multicore if 'matlabpool' is executed
44
%  2 - The CUDA matlab plugin is used to compute FFT's (not recomended)
2 by Suren A. Chilingaryan
Support for different optimization modes
45
%  3 - Most of computations are performed on NVidia card
41 by Suren A. Chilingaryan
Synchronize with Chris version, set precision to 1, initial implementation of labview wrapper
46
%  4 - Optimize FFT sizes for better performance (slightly affects precision)
24 by Suren A. Chilingaryan
Optimization mode 5 for matlab: image loading in C code
47
%  5 - Load images in C code
41 by Suren A. Chilingaryan
Synchronize with Chris version, set precision to 1, initial implementation of labview wrapper
48
% You can safely set an optimization level to 3-5. If NVidia card is not available
2 by Suren A. Chilingaryan
Support for different optimization modes
49
% the level will be automatically reduced to 1.
6 by Suren A. Chilingaryan
A little more computations are moved to CUDA
50
%
51
% SAVEDATA controls if data is saved per iteration or at the end
52
% 0 - in the end
53
% 1 - per iteration
2 by Suren A. Chilingaryan
Support for different optimization modes
54
29 by Suren A. Chilingaryan
Implementation of image and fragment modes, support for non-cacheable grids
55
OPTIMIZE = 4;
2 by Suren A. Chilingaryan
Support for different optimization modes
56
CORRSIZE = 15;	
41 by Suren A. Chilingaryan
Synchronize with Chris version, set precision to 1, initial implementation of labview wrapper
57
PRECISION = 1;
4 by Suren A. Chilingaryan
Instead of transfer compute local sums and denormals on board
58
SILENT = 1;
6 by Suren A. Chilingaryan
A little more computations are moved to CUDA
59
SAVEDATA = 0;
2 by Suren A. Chilingaryan
Support for different optimization modes
60
31 by Suren A. Chilingaryan
CUDAfication of real-time module
61
warning off Images:initSize:adjustingMag
62
1 by Suren A. Chilingaryan
Initial import
63
% exist('grid_x')
64
% exist('grid_y')
65
% exist('filenamelist')
66
% exist('validx')
67
% exist('validy')
68
69
if exist('images', 'dir')
70
    imagedir = 'images/';
71
else
72
    imagedir = '';
73
end
74
31 by Suren A. Chilingaryan
CUDAfication of real-time module
75
if exist('data', 'dir')
76
    datadir = 'data/';
77
else
78
    if exist([imagedir, 'grid_x.dat'], 'file')
79
	datadir = imagedir;
80
    else
81
	datadir = '';
82
    end
83
end
84
85
1 by Suren A. Chilingaryan
Initial import
86
% Load necessary files
87
if exist('grid_x')==0
88
    load([datadir, 'grid_x.dat'])              % file with x position, created by grid_generator.m
89
end
90
if exist('grid_y')==0
91
    load([datadir, 'grid_y.dat'])              % file with y position, created by grid_generator.m
92
end
93
if exist('filenamelist')==0
94
    load([datadir, 'filenamelist'])            % file with the list of filenames to be processed
95
end
96
97
98
resume=0;
99
if exist('validx')==1
100
    if exist('validy')==1
101
        resume=1;
102
        [Rasternum Imagenum]=size(validx);
103
    end
104
end
105
106
[r,c]=size(filenamelist);           % this will determine the number of images we have to loop through
107
108
% Open new figure so previous ones (if open) are not overwritten
109
if (~SILENT)
24 by Suren A. Chilingaryan
Optimization mode 5 for matlab: image loading in C code
110
    if OPTIMIZE > 4
111
	OPTIMIZE = 4
112
    end
113
    
1 by Suren A. Chilingaryan
Initial import
114
    h=figure;
115
    imshow([imagedir, filenamelist(1,:)])           % show the first image
116
    title('Initial Grid For Image Correlation (Note green crosses)')        % put a title
117
    hold on
118
    plot(grid_x,grid_y,'g+')            % plot the grid onto the image
119
    hold off
120
121
    % Start image correlation using cpcorr.m
122
    g = waitbar(0,sprintf('Processing images'));        % initialize the waitbar
123
    set(g,'Position',[275,50,275,50])                   % set the position of the waitbar [left bottom width height]
40 by Suren A. Chilingaryan
Few more fixes
124
    
125
    [row,col]=size(grid_x);
1 by Suren A. Chilingaryan
Initial import
126
end
127
128
firstimage=1;
129
130
if resume==1
131
    firstimage=Imagenum+1
132
end
133
134
%Initializing hardware code
135
8 by Suren A. Chilingaryan
Complete elimination of cpcorr
136
ncp = prod(size(grid_x));
1 by Suren A. Chilingaryan
Initial import
137
2 by Suren A. Chilingaryan
Support for different optimization modes
138
if OPTIMIZE > 2
139
    hwid = normxcorr_hw();
4 by Suren A. Chilingaryan
Instead of transfer compute local sums and denormals on board
140
2 by Suren A. Chilingaryan
Support for different optimization modes
141
    if hwid > 0
16 by Suren A. Chilingaryan
Optimize FFT size
142
	err = normxcorr_hw(hwid, 1, ncp, CORRSIZE, PRECISION, OPTIMIZE);
3 by Suren A. Chilingaryan
Add error checking to initialization process
143
	if (err ~= 0)
144
	    normxcorr_hw(1);
145
	    OPTIMIZE = 2;
146
	end
2 by Suren A. Chilingaryan
Support for different optimization modes
147
    else
148
	if hwid < 0
149
	    OPTIMIZE = 1;
150
	else
151
	    OPTIMIZE = 2;
152
	end
153
    end
154
else
155
    hwid = 0;
156
end
1 by Suren A. Chilingaryan
Initial import
157
8 by Suren A. Chilingaryan
Complete elimination of cpcorr
158
% Initialize variables
159
if OPTIMIZE>2
160
    base_points_x=single(grid_x);
161
    base_points_y=single(grid_y);
162
else
163
    base_points_x=grid_x;
164
    base_points_y=grid_y;
165
end
166
167
if resume==1
168
    if OPTIMIZE>2
169
	input_points_x=single(validx(:,Imagenum));
170
	input_points_y=single(validy(:,Imagenum));
171
    else
172
	input_points_x=validx(:,Imagenum);
173
	input_points_y=validy(:,Imagenum);
174
    end
175
    inputpoints=1;
176
else
177
    if OPTIMIZE>2
178
	input_points_x=single(grid_x);
179
	input_points_y=single(grid_y);
180
    else
181
	input_points_x=grid_x;
182
	input_points_y=grid_y;
183
    end
184
end
185
186
187
if OPTIMIZE > 2
188
    normxcorr_hw(hwid, 3, base_points_x, base_points_y);
24 by Suren A. Chilingaryan
Optimization mode 5 for matlab: image loading in C code
189
    if OPTIMIZE > 4
190
	normxcorr_hw(hwid, 4, strcat(imagedir, filenamelist(1,:)));
191
    else
192
	base = uint8(mean(double(imread([imagedir, filenamelist(1,:)])),3));            % read in the base image ( which is always  image number one. You might want to change that to improve correlation results in case the light conditions are changing during the experiment
29 by Suren A. Chilingaryan
Implementation of image and fragment modes, support for non-cacheable grids
193
194
%    	Verification of GPU local sum and denom computations
195
%    	dic_basecorr3(CORRSIZE, PRECISION, OPTIMIZE, hwid, base_points_x, base_points_y, base);
196
24 by Suren A. Chilingaryan
Optimization mode 5 for matlab: image loading in C code
197
	normxcorr_hw(hwid, 4, base);
198
    end	
8 by Suren A. Chilingaryan
Complete elimination of cpcorr
199
else
24 by Suren A. Chilingaryan
Optimization mode 5 for matlab: image loading in C code
200
  base = uint8(mean(double(imread([imagedir, filenamelist(1,:)])),3));            % read in the base image ( which is always  image number one. You might want to change that to improve correlation results in case the light conditions are changing during the experiment
8 by Suren A. Chilingaryan
Complete elimination of cpcorr
201
  base_points_for(:,1)=reshape(base_points_x,[],1);
202
  base_points_for(:,2)=reshape(base_points_y,[],1);
203
204
  %some checks (moved here from cpcorr)
205
  if any(base_points_for(:)<0.5) || any(base_points_for(:,1)>size(base,2)+0.5) || any(base_points_for(:,2)>size(base,1)+0.5)
206
    msg = sprintf('In function %s, Control Points must be in pixel coordinates.',mfilename);
207
    eid = sprintf('Images:%s:cpPointsMustBeInPixCoord',mfilename);
208
    error(eid, msg);
209
  end
210
211
  if OPTIMIZE > 0
212
     data_base = struct;
1 by Suren A. Chilingaryan
Initial import
213
    
8 by Suren A. Chilingaryan
Complete elimination of cpcorr
214
     %moved from normxcorr2
215
     % We can precalculate it here, since near-edge images are dropped and, therefore, A,T always have the same size 
216
     % n is width and height of T, but following computations are done for A
217
     % outsize is sum if widths and heights of T and A - 1 (outsize = size(A) + size(T) - 1)
218
219
     outsize = 6 * CORRSIZE + 1;
220
     n = 2*CORRSIZE + 1;
221
     mn = n*n;
222
223
     rects_base = dic_calc_rects(base_points_for,2*CORRSIZE,base);
224
225
     for icp = 1:ncp
226
	if isequal(rects_base(icp,3:4),[0 0])
227
	    %near edge
228
	    data_base(icp).skip = 1;
229
	    continue
4 by Suren A. Chilingaryan
Instead of transfer compute local sums and denormals on board
230
	end
8 by Suren A. Chilingaryan
Complete elimination of cpcorr
231
232
	sub_base = imcrop(base,rects_base(icp,:));
233
    
234
	data_base(icp).skip = 0;
235
4 by Suren A. Chilingaryan
Instead of transfer compute local sums and denormals on board
236
	double_sub_base = double(sub_base);
237
238
	if (numel(sub_base) < 2) ||  (std(double_sub_base(:)) == 0)
239
	    % This check is moved here for normxcorr2
240
	    eid = sprintf('Images:%s:sameElementsInTemplate',mfilename);
241
	    msg = 'The values of TEMPLATE cannot all be the same.';
242
	    error(eid,'%s',msg);
243
	end
244
245
	local_sum_A = dic_local_sum(double_sub_base,n,n);
246
	local_sum_A2 = dic_local_sum(double_sub_base.*double_sub_base,n,n);
247
248
	% Note: diff_local_sums should be nonnegative, but may have negative
249
	% values due to round off errors. Below, we use max to ensure the
250
	% radicand is nonnegative.
251
	denom_A = sqrt( max(( local_sum_A2 - (local_sum_A.^2)/mn ) / (mn-1), 0) );
252
	i_nonzero = find(denom_A~=0);
253
    
2 by Suren A. Chilingaryan
Support for different optimization modes
254
	data_base(icp).denom_A = denom_A;
255
	data_base(icp).i_nonzero = i_nonzero;
256
257
	data_base(icp).local_sum_A = local_sum_A;
258
	data_base(icp).sub_base = sub_base;
259
	
260
	if (OPTIMIZE > 1)
261
	    data_base(icp).sub_base_fft = fft2_cuda(double_sub_base, outsize, outsize);
262
	else
263
	    data_base(icp).sub_base_fft = fft2(double_sub_base, outsize, outsize);
264
	end
8 by Suren A. Chilingaryan
Complete elimination of cpcorr
265
266
	data_base(icp).base_fractional_offset = base_points_for(icp,:) - round(base_points_for(icp,:)*PRECISION)/PRECISION;
2 by Suren A. Chilingaryan
Support for different optimization modes
267
    end
268
  end
1 by Suren A. Chilingaryan
Initial import
269
end
270
271
%normxcorr_hw(hwid);
272
%return;
273
8 by Suren A. Chilingaryan
Complete elimination of cpcorr
274
if OPTIMIZE > 2
275
    normxcorr_hw(hwid, 12, input_points_x, input_points_y);
276
else
6 by Suren A. Chilingaryan
A little more computations are moved to CUDA
277
    input_correl(:,1)=reshape(input_points_x,[],1);         % we reshape the input points to one row of values since this is the shape cpcorr will accept
278
    input_correl(:,2)=reshape(input_points_y,[],1);
8 by Suren A. Chilingaryan
Complete elimination of cpcorr
279
end
6 by Suren A. Chilingaryan
A little more computations are moved to CUDA
280
1 by Suren A. Chilingaryan
Initial import
281
for i=firstimage:(r-1)               % run through all images
282
    tic             % start the timer
283
284
24 by Suren A. Chilingaryan
Optimization mode 5 for matlab: image loading in C code
285
    if OPTIMIZE > 4
286
	normxcorr_hw(hwid, 13, strcat(imagedir, filenamelist((i+1),:)));
287
	input_correl = normxcorr_hw(hwid, 14);
288
    elseif OPTIMIZE > 2
29 by Suren A. Chilingaryan
Implementation of image and fragment modes, support for non-cacheable grids
289
	input = uint8(mean(double(imread([imagedir, filenamelist((i+1),:)])),3));       % read in the image which has to be correlated
290
8 by Suren A. Chilingaryan
Complete elimination of cpcorr
291
	%Validate findpeak
292
	%dic_cpcorr3(CORRSIZE, PRECISION, OPTIMIZE, hwid, ncp, input);
24 by Suren A. Chilingaryan
Optimization mode 5 for matlab: image loading in C code
293
8 by Suren A. Chilingaryan
Complete elimination of cpcorr
294
	normxcorr_hw(hwid, 13, input)
295
	input_correl = normxcorr_hw(hwid, 14);
6 by Suren A. Chilingaryan
A little more computations are moved to CUDA
296
    elseif OPTIMIZE > 0
24 by Suren A. Chilingaryan
Optimization mode 5 for matlab: image loading in C code
297
	input = uint8(mean(double(imread([imagedir, filenamelist((i+1),:)])),3));       % read in the image which has to be correlated
6 by Suren A. Chilingaryan
A little more computations are moved to CUDA
298
	input_correl(:,:)=dic_cpcorr(CORRSIZE, PRECISION, OPTIMIZE, hwid, data_base, input_correl, input);
2 by Suren A. Chilingaryan
Support for different optimization modes
299
    else
24 by Suren A. Chilingaryan
Optimization mode 5 for matlab: image loading in C code
300
	input = uint8(mean(double(imread([imagedir, filenamelist((i+1),:)])),3));       % read in the image which has to be correlated
6 by Suren A. Chilingaryan
A little more computations are moved to CUDA
301
	input_correl(:,:)=cpcorr(input_correl, base_points_for, input, base);
302
    end
19 by Suren A. Chilingaryan
Provide stand-alone library
303
    
8 by Suren A. Chilingaryan
Complete elimination of cpcorr
304
    %We need to copy
6 by Suren A. Chilingaryan
A little more computations are moved to CUDA
305
    validx(:,i)=double(input_correl(:,1));                                       % the results we get from cpcorr for the x-direction
306
    validy(:,i)=double(input_correl(:,2));                                       % the results we get from cpcorr for the y-direction
307
308
    if (SAVEDATA)    
309
	savelinex=validx(:,i)';
310
	dlmwrite([datadir, 'resultsimcorrx.txt'], savelinex , 'delimiter', '\t', '-append');       % Here we save the result from each image; if you are desperately want to run this function with e.g. matlab 6.5 then you should comment this line out. If you do that the data will be saved at the end of the correlation step - good luck ;-)
311
    
312
	saveliney=validy(:,i)';
313
	dlmwrite([datadir, 'resultsimcorry.txt'], saveliney , 'delimiter', '\t', '-append');
314
    end
1 by Suren A. Chilingaryan
Initial import
315
    
316
    if (~SILENT) 
317
	waitbar(i/(r-1))                                % update the waitbar
318
319
	imshow([imagedir, filenamelist(i+1,:)])                     % update image
320
	hold on
321
	plot(grid_x,grid_y,'g+')                                % plot start position of raster
6 by Suren A. Chilingaryan
A little more computations are moved to CUDA
322
	plot(input_correl(:,1),input_correl(:,2),'r+')        % plot actual postition of raster
1 by Suren A. Chilingaryan
Initial import
323
	hold off
324
	drawnow
325
	time(i)=toc;                                                 % take time
326
	estimatedtime=sum(time)/i*(r-1);            % estimate time to process
327
	title(['# Im.: ', num2str((r-1)),'; Proc. Im. #: ', num2str((i)),'; # Rasterp.:',num2str(row*col), '; Est. Time [s] ', num2str(round(estimatedtime)), ';  Elapsed Time [s] ', num2str(round(sum(time)))]);    % plot a title onto the image
328
	drawnow
329
    end
330
end    
331
2 by Suren A. Chilingaryan
Support for different optimization modes
332
if OPTIMIZE > 2
333
    normxcorr_hw(hwid);
334
end
1 by Suren A. Chilingaryan
Initial import
335
336
if (~SILENT)
337
    close(g)
338
end
339
340
close all
341
342
% save
343
344
if (~SILENT)
345
    save ([datadir,'time.dat'], 'time', '-ascii', '-tabs');
346
end
347
348
save ([datadir,'validx.dat'], 'validx', '-ascii', '-tabs');
349
save ([datadir,'validy.dat'], 'validy', '-ascii', '-tabs');