PageRenderTime 40ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/code/3D image registration/dtcwt3dCL_xa_modified.m

http://sparse-mri-reconstruction.googlecode.com/
Objective C | 313 lines | 281 code | 32 blank | 0 comment | 73 complexity | 61aa28bdfacacbeb30ec7c690a9aa36d MD5 | raw file
  1. function dtcwt3dCL_xa_modified(level,ext_mode)
  2. % function dtcwt3dCL_xa(level,ext_mode)
  3. % Perform the 3-dimensional Dual-Tree Complex Wavelet Transform (DT CWT)
  4. % or its inverse on dataset xa, using quarter-sample orthonormal filters at levels >= 2.
  5. % xa is originally taken as the input to the DT CWT. After the transform,
  6. % xa is the LoLoLo band at the highest level, and ya contains the DTCWT
  7. % coefs at each level.
  8. %
  9. % Forward transforms:
  10. % Top level: level = 1
  11. % Levels >= 2: level >= 2
  12. %
  13. % Inverse transforms:
  14. % Top level: level = -1
  15. % Levels >= 2: level <= -2
  16. %
  17. % There are two values for ext_mode, either 4 or 8.
  18. % If ext_mode = 4, check whether 1st level is divisible by 2 (if not we
  19. % give an error msg). Also check whether from 2nd level onwards, the coefs can
  20. % be divided by 4. If any dimension size is not a multiple of 4, append
  21. % extra coefs by repeating the edges.
  22. % If ext_mode = 8, check whether 1st level is divisible by 4 (if not we
  23. % give an error msg). Also check whether from 2nd level onwards, the coefs can
  24. % be divided by 8. If any dimension size is not a multiple of 8, append
  25. % extra coefs by repeating the edges twice.
  26. %
  27. % Nick Kingsbury, Cambridge University, July 1999.
  28. % This version modified to use column filtering, Nov 2003.
  29. % ext_mode added by Huizhong Chen, Jan 2009
  30. % To test use:
  31. % global xa h0o h1o g0o g1o h0a h1a g0a g1a
  32. % load3d_xa('sphere'); % Load a dataset.
  33. % dtcwt3dCL_xa(1, ext_mode); for k=2:3; dtcwt3dCL_xa(k,ext_mode); oct_cplx_xa(k); end % Do 3 levels of forward transform
  34. % for k= -3:-2; oct_cplx_xa(k); dtcwt3dCL_xa(k,ext_mode); end; dtcwt3dCL_xa(-1,ext_mode); % Do 3 levels of inverse transform
  35. % sxa=size(xa)/2; xa=xa(1:sxa(1),1:sxa(2),1:sxa(3)); add3d_xa('sphere',-1);
  36. % max(abs(xa(:)));
  37. % Final answer should be negligibly small, thus showing near-perfect reconstruction, apart from loss of
  38. % level 1 high band components.
  39. global h0o h1o g0o g1o h0a h1a g0a g1a
  40. global xa % xa is updated by the LLL_band at every level before next level transform
  41. global ya % ya is used to store the DTCWT coefs of xa.
  42. % ya is in the format of ya{level}{band 1:7}, level starts
  43. % from 2 because the 1st level has only LLL_band.
  44. % e.g. ya{3}{1} means the 'HLL' band at level 3.
  45. % 1 => HLL, 2 => LHL, 3 => HHL,
  46. % 4 => LLH, 5 => HLH, 6 => LHH, 7 => HHH
  47. global original_size % original_size is the original input image size
  48. if nargin < 2, ext_mode = 4; end % default ext_mode is 4
  49. % Check whether ext_mode has been given a correct value
  50. if ext_mode~=4 && ext_mode~=8
  51. error('In dtcwt3dCL, ext_mode must be either 4 or 8');
  52. end
  53. % Define the top level filters.
  54. if isempty(h0o),
  55. disp('Generating level 1 filters.')
  56. [h0o,h1o,g0o,g1o] = wavegen('near-sym',[3.5 3/16 0]);
  57. % [h0o,h1o,g0o,g1o] = wavegen('Antonini');
  58. % [h0o,h1o,g0o,g1o] = wavegen('LeGall');
  59. end
  60. % Define the main orthogonal Qshift filters.
  61. if isempty(h0a),
  62. disp('Generating level 2+ filters.')
  63. [h0a,h1a,g0a,g1a] = wavegen('Qshift',[14 0.36]);
  64. % [h0a,h1a,g0a,g1a] = wavegen('Qshift',8);
  65. % These filters have unity gain at zero or fs/2.
  66. % Normalise analysis filter gains to preserve energy in xfm and give PR.
  67. hscale = 1 / sqrt(sum(h0a .* h0a));
  68. h0a = h0a * hscale;
  69. h1a = h1a * hscale;
  70. g0a = g0a * hscale;
  71. g1a = g1a * hscale;
  72. end
  73. h0b = rev(h0a);
  74. h1b = rev(h1a);
  75. g0b = rev(g0a);
  76. g1b = rev(g1a);
  77. fprintf(1,'Level %d: ',level);
  78. tic
  79. if level == 1,
  80. original_size = size(xa);
  81. if ext_mode == 4
  82. if any(rem(original_size,2))
  83. warning('Image size should have even samples in each direction'); %#ok<WNTAG>
  84. return;
  85. end
  86. elseif ext_mode ==8
  87. if any(rem(original_size,4))
  88. warning('Image size should be divisible by 4 in each direction'); %#ok<WNTAG>
  89. return;
  90. end
  91. end
  92. sxa = size(xa);
  93. sxa = 2*sxa; % Compensate for lack of high bands at level 1.
  94. sr = sxa/2;
  95. s1 = 1:sr(1); s2 = 1:sr(2); s3 = 1:sr(3);
  96. s1b = s1 + sr(1); s2b = s2 + sr(2); s3b = s3 + sr(3);
  97. % Loop for each slice, incrementing 2nd dimension.
  98. % (Use the 2nd dim as it is faster to leave the 1st dim as the
  99. % matrix column index.)
  100. for f = s2,
  101. y = reshape(xa(s1,f,s3),sr([1 3])).';
  102. % Do odd top-level filters on 3rd dim.
  103. xa(s1,f,s3) = colfilter(y,h0o).';
  104. xa(s1,f,s3b) = colfilter(y,h1o).';
  105. end
  106. % Loop for each frame, incrementing 3rd dimension.
  107. for f = s3,
  108. % Do odd top-level filters on rows.
  109. y = xa(s1,s2,f).';
  110. y2 = colfilter(xa(s1,s2,f).',h0o).';
  111. % Do odd top-level filters on columns.
  112. xa(s1,s2,f) = colfilter(y2,h0o);
  113. xa(s1b,s2,f) = colfilter(y2,h1o);
  114. end
  115. elseif level >= 2,
  116. % Check if the LoLoLo band is divisable by 4 in each direction. If
  117. % not, we aim to extend the LoLoLo band to make its size divisable by
  118. % 4.
  119. LLL_band_size = size(xa);
  120. if ext_mode == 4
  121. if any(rem(LLL_band_size(1),4)), % sr is the size of the LoLoLo band
  122. % Extend by 2 rows for each of the octal bands, if no. of rows of LoLoLo is not divisable by 4.
  123. xa = cat(1,xa(1,:,:),xa,xa(end,:,:));
  124. end
  125. if any(rem(LLL_band_size(2),4)), % sr is the size of the LoLoLo band
  126. % Extend by 2 columns for each of the octal bands, if no. of columns of
  127. % LoLoLo is not divisable by 4.
  128. xa = cat(2,xa(:,1,:),xa,xa(:,end,:));
  129. end
  130. if any(rem(LLL_band_size(3),4)), % sr is the size of the LoLoLo band
  131. % Extend by 2 columns for each of the octal bands, if no. of columns of
  132. % LoLoLo is not divisable by 4.
  133. xa = cat(3,xa(:,:,1),xa,xa(:,:,end));
  134. end
  135. elseif ext_mode == 8
  136. if any(rem(LLL_band_size(1),8)), % sr is the size of the LoLoLo band
  137. % Extend by 2 rows for each of the octal bands, if no. of rows of LoLoLo is not divisable by 8.
  138. xa = cat(1,xa(1,:,:),xa(1,:,:),xa,xa(end,:,:),xa(end,:,:));
  139. end
  140. if any(rem(LLL_band_size(2),8)), % sr is the size of the LoLoLo band
  141. % Extend by 2 columns for each of the octal bands, if no. of columns of
  142. % LoLoLo is not divisable by 8.
  143. xa = cat(2,xa(:,1,:),xa(:,1,:),xa,xa(:,end,:),xa(:,end,:));
  144. end
  145. if any(rem(LLL_band_size(3),8)), % sr is the size of the LoLoLo band
  146. % Extend by 2 columns for each of the octal bands, if no. of columns of
  147. % LoLoLo is not divisable by 8.
  148. xa = cat(3,xa(:,:,1),xa(:,:,1),xa,xa(:,:,end),xa(:,:,end));
  149. end
  150. end
  151. % Now LLL_band is guaranteed to be divisable by ext_mode
  152. extended_LLL_band_size = size(xa);
  153. t1 = 1:extended_LLL_band_size(1); t2 = 1:extended_LLL_band_size(2); t3 = 1:extended_LLL_band_size(3);
  154. s1 = 1:extended_LLL_band_size(1)/2; s2 = 1:extended_LLL_band_size(2)/2; s3 = 1:extended_LLL_band_size(3)/2;
  155. s1b = s1 + extended_LLL_band_size(1)/2; s2b = s2 + extended_LLL_band_size(2)/2; s3b = s3 + extended_LLL_band_size(3)/2;
  156. for band = 1:7
  157. % Initialise ya
  158. ya{level}{band} = zeros(extended_LLL_band_size/2); % Size of each of the octal bands must be extended_LLL_band_size/2
  159. end
  160. % Loop for each slice, incrementing 2nd dimension.
  161. for f = t2,
  162. y = reshape(xa(t1,f,t3),extended_LLL_band_size([1 3])).';
  163. % Do even Qshift filters on 3rd dim.
  164. xa(t1,f,s3) = coldfilt(y,h0b,h0a).';
  165. xa(t1,f,s3b) = coldfilt(y,h1b,h1a).';
  166. end
  167. % Loop for each frame, incrementing 3rd dimension.
  168. for f = t3,
  169. % Do even Qshift filters on rows.
  170. y = xa(t1,t2,f).';
  171. y2 = [coldfilt(y,h0b,h0a); coldfilt(y,h1b,h1a)].';
  172. % Do even Qshift filters on columns.
  173. xa(s1,t2,f) = coldfilt(y2,h0b,h0a);
  174. xa(s1b,t2,f) = coldfilt(y2,h1b,h1a);
  175. end
  176. % Now record ya{level}{band 1:7} and update LLL_band
  177. ya{level}{1} = xa(s1,s2b,s3); % HLL
  178. ya{level}{2} = xa(s1b,s2,s3); % LHL
  179. ya{level}{3} = xa(s1b,s2b,s3); % HHL
  180. ya{level}{4} = xa(s1,s2,s3b); % LLH
  181. ya{level}{5} = xa(s1,s2b,s3b); % HLH
  182. ya{level}{6} = xa(s1b,s2,s3b); % LHH
  183. ya{level}{7} = xa(s1b,s2b,s3b); % HHH
  184. xa = xa(s1,s2,s3); % LLL
  185. elseif level == -1,
  186. extended_LLL_band_size = size(xa);
  187. s1 = 1:extended_LLL_band_size(1); s2 = 1:extended_LLL_band_size(2); s3 = 1:extended_LLL_band_size(3);
  188. for f = s3,
  189. % Do odd top-level filters on rows.
  190. y = colfilter(xa(s1,s2,f).',g0o);
  191. % Do odd top-level filters on columns.
  192. xa(s1,s2,f) = colfilter(y(:,s1).',g0o);
  193. end
  194. for f = s2,
  195. % Do odd top-level filters on 3rd dim.
  196. y = reshape(xa(s1,f,s3),extended_LLL_band_size(1),extended_LLL_band_size(3)).';
  197. xa(s1,f,s3) = colfilter(y(s3,:),g0o).';
  198. end
  199. elseif level <= -2,
  200. extended_LLL_band_size = size(xa);
  201. t1 = 1:2*extended_LLL_band_size(1); t2 = 1:2*extended_LLL_band_size(2); t3 = 1:2*extended_LLL_band_size(3);
  202. s1 = 1:extended_LLL_band_size(1); s2 = 1:extended_LLL_band_size(2); s3 = 1:extended_LLL_band_size(3);
  203. s1b = s1 + extended_LLL_band_size(1); s2b = s2 + extended_LLL_band_size(2); s3b = s3 + extended_LLL_band_size(3);
  204. % Now define a temporary variable which is used to combine the highpass
  205. % bands with the LLL band
  206. for k=1:3; xa=cat(k,xa,0*xa); end
  207. xa(s1,s2b,s3) = ya{abs(level)}{1};
  208. xa(s1b,s2,s3) = ya{abs(level)}{2};
  209. xa(s1b,s2b,s3) = ya{abs(level)}{3};
  210. xa(s1,s2,s3b) = ya{abs(level)}{4};
  211. xa(s1,s2b,s3b) = ya{abs(level)}{5};
  212. xa(s1b,s2,s3b) = ya{abs(level)}{6};
  213. xa(s1b,s2b,s3b) = ya{abs(level)}{7};
  214. for f = t3,
  215. % Do even Qshift filters on rows.
  216. y = colifilt(xa(t1,s2,f).',g0b,g0a) + colifilt(xa(t1,s2b,f).',g1b,g1a);
  217. % Do even Qshift filters on columns.
  218. xa(t1,t2,f) = colifilt(y(:,s1).',g0b,g0a) + colifilt(y(:,s1b).',g1b,g1a);
  219. end
  220. for f = t2,
  221. y = reshape(xa(t1,f,t3),2*extended_LLL_band_size([1 3])).';
  222. % Do even Qshift filters on 3rd dim.
  223. xa(t1,f,t3) = (colifilt(y(s3,:),g0b,g0a) + colifilt(y(s3b,:),g1b,g1a)).';
  224. end
  225. % Now check if the size of the previous level is exactly twice the size
  226. % of the current level. If YES, this means we have not done the
  227. % extension in the previous level. If NO, then we have to remove the
  228. % appended row / column / frame from the previous level DTCWT coefs.
  229. size_curr_level = size(ya{abs(level)}{1});
  230. if(level<=-3)
  231. size_prev_level = size(ya{abs(level)-1}{1});
  232. if ext_mode == 4,
  233. if size_prev_level(1)/size_curr_level(1) ~= 2
  234. xa = xa(2:end-1,:,:); % Disgard the top and bottom rows
  235. end
  236. if size_prev_level(2)/size_curr_level(2) ~= 2
  237. xa = xa(:,2:end-1,:); % Disgard the left and right columns
  238. end
  239. if size_prev_level(3)/size_curr_level(3) ~= 2
  240. xa = xa(:,:,2:end-1); % Disgard the left and right columns
  241. end
  242. elseif ext_mode == 8,
  243. if size_prev_level(1)/size_curr_level(1) ~= 2
  244. xa = xa(3:end-2,:,:); % Disgard the top and bottom rows
  245. end
  246. if size_prev_level(2)/size_curr_level(2) ~= 2
  247. xa = xa(:,3:end-2,:); % Disgard the left and right columns
  248. end
  249. if size_prev_level(3)/size_curr_level(3) ~= 2
  250. xa = xa(:,:,3:end-2); % Disgard the left and right columns
  251. end
  252. end
  253. else %when level=-2
  254. if ext_mode == 4,
  255. if original_size(1) / size_curr_level(1) ~= 2
  256. xa = xa(2:end-1,:,:); % Disgard the top and bottom rows
  257. end
  258. if original_size(2)/size_curr_level(2) ~= 2
  259. xa = xa(:,2:end-1,:); % Disgard the left and right columns
  260. end
  261. if original_size(3)/size_curr_level(3) ~= 2
  262. xa = xa(:,:,2:end-1); % Disgard the top and bottom frames
  263. end
  264. elseif ext_mode == 8,
  265. if original_size(1) / size_curr_level(1) ~= 2
  266. xa = xa(3:end-2,:,:); % Disgard the top and bottom rows
  267. end
  268. if original_size(2)/size_curr_level(2) ~= 2
  269. xa = xa(:,3:end-2,:); % Disgard the left and right columns
  270. end
  271. if original_size(3)/size_curr_level(3) ~= 2
  272. xa = xa(:,:,3:end-2); % Disgard the top and bottom frames
  273. end
  274. end
  275. end
  276. else
  277. disp('Illegal level');
  278. end
  279. tk = toc;
  280. fprintf(1,'toc = %.2f sec\n',tk);
  281. return;