55% example builds on the 2D Time Reversal Reconstruction For A Line Sensor
66% Example.
77%
8- % author: Ben Cox and Bradley Treeby
8+ % author: Ben Cox, Bradley Treeby and Felix Lucka
99% date: 22nd January 2012
10- % last update: 29th July 2019
10+ % last update: 22nd October 2021
1111%
1212% This function is part of the k-Wave Toolbox (http://www.k-wave.org)
1313% Copyright (C) 2012-2019 Ben Cox and Bradley Treeby
3232% =========================================================================
3333
3434% define literals
35- NUMBER_OF_ITERATIONS = 3 ; % number of iterations
35+ NUMBER_OF_ITERATIONS = 5 ; % number of iterations
3636PML_SIZE = 20 ; % size of the perfectly matched layer in grid points
3737
3838% create the computational grid
6868% set the input arguments: force the PML to be outside the computational
6969% grid, switch off p0 smoothing within kspaceFirstOrder2D
7070input_args = {' PMLInside' , false , ' PMLSize' , PML_SIZE , ' Smooth' , false , ...
71- ' PlotPML' , false , ' PlotSim' , true };
71+ ' PlotPML' , false , ' PlotSim' , false };
7272
7373% run the simulation
7474sensor_data = kspaceFirstOrder2D(kgrid , medium , source , sensor , input_args{: });
7575
7676% =========================================================================
77- % RECONSTRUCT AN IMAGE USING TIME REVERSAL
77+ % RECONSTRUCT AN IMAGE USING ITERATIVE TIME REVERSAL
7878% =========================================================================
7979
80- % remove the initial pressure field used in the simulation
81- source = rmfield( source , ' p0 ' );
80+ % set the initial reconstructed image to be zeros
81+ p0_estimate = zeros( Nx , Ny );
8282
83- % use the sensor points as sources in time reversal
84- source.p_mask = sensor . mask ;
83+ % set the initial model times series to be zero
84+ modelled_time_series = zeros(size( sensor_data )) ;
8585
86- % time reverse and assign the data
87- source.p = fliplr( sensor_data );
86+ % calculate the difference between the measured and modelled data
87+ data_difference = sensor_data - modelled_time_series ;
8888
89- % enforce, rather than add, the time-reversed pressure values
90- source.p_mode = ' dirichlet' ;
91-
92- % set the simulation to record the final image (at t = 0)
93- sensor.record = {' p_final' };
94-
95- % run the time reversal reconstruction
96- p0_estimate = kspaceFirstOrder2D(kgrid , medium , source , sensor , input_args{: });
97-
98- % apply a positivity condition
99- p0_estimate.p_final = p0_estimate .p_final .* (p0_estimate .p_final > 0 );
100-
101- % store the latest image estimate
102- p0_1 = p0_estimate .p_final ;
89+ % track goodness of fit and relative error during the iteration
90+ gof = ones(NUMBER_OF_ITERATIONS + 1 , 1 );
91+ rel_err = ones(NUMBER_OF_ITERATIONS + 1 , 1 );
10392
10493% =========================================================================
10594% ITERATE TO IMPROVE THE IMAGE
10695% =========================================================================
10796
108- for loop = 2 : NUMBER_OF_ITERATIONS
109-
110- % remove the source used in the previous time reversal
111- source = rmfield(source , ' p' );
112-
113- % set the initial pressure to be the latest estimate of p0
114- source.p0 = p0_estimate .p_final ;
115-
116- % set the simulation to record the time series
117- sensor = rmfield(sensor , ' record' );
118-
119- % calculate the time series using the latest estimate of p0
120- sensor_data2 = kspaceFirstOrder2D(kgrid , medium , source , sensor , input_args{: });
121-
122- % calculate the error in the estimated time series
123- data_difference = sensor_data - sensor_data2 ;
97+ for loop = 1 : NUMBER_OF_ITERATIONS
12498
12599 % assign the data_difference as a time-reversal source
126100 source.p_mask = sensor .mask ;
133107
134108 % run the time reversal reconstruction
135109 p0_update = kspaceFirstOrder2D(kgrid , medium , source , sensor , input_args{: });
136-
137- % add the update to the latest image
138- p0_estimate.p_final = p0_estimate . p_final + p0_update .p_final ;
139-
110+
111+ % update the image
112+ p0_estimate = p0_estimate + p0_update .p_final ;
113+
140114 % apply a positivity condition
141- p0_estimate.p_final = p0_estimate . p_final .* (p0_estimate . p_final > 0 );
115+ p0_estimate = p0_estimate .* (p0_estimate >= 0 );
142116
143117 % store the latest image estimate
144- eval([' p0_' num2str(loop ) ' = p0_estimate.p_final;' ]);
118+ p0_iterates{loop } = p0_estimate ;
119+
120+
121+ % remove the source used in the previous time reversal
122+ source = rmfield(source , ' p' );
145123
124+ % set the initial pressure to be the latest estimate of p0
125+ source.p0 = p0_estimate ;
126+
127+ % set the simulation to record the time series
128+ sensor = rmfield(sensor , ' record' );
129+
130+ % calculate the time series using the latest estimate of p0
131+ modelled_time_series = kspaceFirstOrder2D(kgrid , medium , source , sensor , input_args{: });
132+
133+ % calculate the error in the estimated time series
134+ data_difference = sensor_data - modelled_time_series ;
135+
136+ % measure goodness of fit and relative error
137+ gof(loop + 1 ) = norm(data_difference(: ))^2 / norm(sensor_data(: ))^2 ;
138+ rel_err(loop + 1 ) = norm(p0_estimate(: ) - p0(: ))^2 / norm(p0(: ))^2 ;
139+
146140end
147141
148142% =========================================================================
168162
169163% plot the first iteration
170164figure ;
171- imagesc(p0_1 , c_axis );
165+ imagesc(p0_iterates{ 1 } , c_axis );
172166axis image ;
173167set(gca , ' XTick' , [], ' YTick' , []);
174168ylabel(' x-position [mm]' );
184178
185179% plot the 2nd iteration
186180figure ;
187- imagesc(p0_2 , c_axis );
181+ imagesc(p0_iterates{ 2 } , c_axis );
188182axis image ;
189183set(gca , ' XTick' , [], ' YTick' , []);
190184title(' Time Reversal Reconstruction, 2 Iterations' );
196190plot([Ny , 1 ], [1 , 1 ], ' k-' );
197191plot([1 , 1 ], [1 , Nx ], ' k-' );
198192
199- % plot the 3rd iteration
193+ % plot the last iteration
200194figure ;
201- imagesc(p0_3 , c_axis );
195+ imagesc(p0_iterates{ end } , c_axis );
202196axis image ;
203197set(gca , ' XTick' , [], ' YTick' , []);
204- title(' Time Reversal Reconstruction, 3 Iterations' );
198+ title([ ' Time Reversal Reconstruction, ' int2str( NUMBER_OF_ITERATIONS ) ' Iterations' ] );
205199colorbar ;
206200scaleFig(1 , 0.65 );
207201
208202% add lines indicating the sensor mask and 'visible region'
209203hold on ;
210204plot([Ny , 1 ], [1 , 1 ], ' k-' );
211205plot([1 , 1 ], [1 , Nx ], ' k-' );
212- plot([Ny , 1 ], [1 , Nx ], ' k--' );
206+ plot([Ny , 1 ], [1 , Nx ], ' k--' );
207+
208+ % plot gof and relative error
209+ figure();
210+ plot(0 : NUMBER_OF_ITERATIONS , gof , ' DisplayName' , ' goodness of fit' ); hold on
211+ plot(0 : NUMBER_OF_ITERATIONS , rel_err , ' DisplayName' , ' relative error' ); hold on
212+ legend(gca ,' show' );
0 commit comments