PageRenderTime 66ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/code/DTCWTregistration/estshhemm24.m

http://sparse-mri-reconstruction.googlecode.com/
MATLAB | 728 lines | 438 code | 74 blank | 216 comment | 41 complexity | ce9f3fd54091236e3a5534f419de6dc2 MD5 | raw file
  1. function [shift1, shift2, shift_common,del1, del2, del_common,av1,av2,av_common, ...
  2. av1_s,av2_s,av_common_s,qvecs1,cond1,cond2,cond_common] = estshhemm24(refl, refh, prevl, prevh, ...
  3. w, nit, levelsel, search, debug, mode, qscale, avlevel, sizeqfilt, mask)
  4. %TDR attempts to perform registration in both directions, ensuring that the
  5. %error (optical flow) and error (data) is minimized.
  6. % function [shift,delta,av,qvecs] = estshhemm22(refl, refh, prevl, prevh, ...
  7. % w, nit, levelsel, search, debug, mode, qscale, avlevel, sizeqfilt, mask)
  8. %
  9. % Estimate the shift between elements of the reference lowpass and
  10. % highpass subimages, refl and refh, and the previous subimages,
  11. % prevl and prevh, at given levels of the dual-tree CWT.
  12. % This version used Magnus Hemmendorf's affine vector field model
  13. % from his 2002 Trans Med Imaging paper: 'Phase-based multi-dim volume
  14. % registration'.
  15. %
  16. % refl and prevl are real lowpass subimages oversampled 2:1 each way.
  17. % refh and prevh are cells of sets of 6 complex bandpass subimages in 3-D arrays.
  18. % w(1:2) contains the expected phase rotations per sample
  19. % for the low and high band 1-D filters (in radians).
  20. % nit is the number of iterations of the algorithm.
  21. % levelsel selects the range of CWT levels used at each iteration:
  22. % such that levelsel(iter,1:2) are the coarsest and finest levels
  23. % used at iteration iter.
  24. % The default nit = 1.
  25. % search defines which offsets from the zero shift point will be tested
  26. % in the initial search phase of the algorithm. It is a column vector
  27. % of complex elements representing the shift offsets.
  28. %
  29. % debug is an m x 2 matrix, specifying that element(s) debug(:,1),debug(:,2)
  30. % in the subimages should be printed out for debugging.
  31. %
  32. % shift is a complex matrix with 1+1j representing the lower right
  33. % corner of a unit square (since vertical distances are measured
  34. % downwards in images). The shift vector points from a sampling
  35. % point in ref to the equivalent point in prev.
  36. % delta is a matrix giving the height of the error surface minimum
  37. % at each point.
  38. % av(:,:,1:6) is a 3-D array of affine vectors at each point.
  39. % qvecs(:,:,1:28) is a 3-D array of q-vectors at each point.
  40. %
  41. % mode(1)>0 causes a single affine vector to be used for the whole image
  42. % for iterations up to mode(1).
  43. % mode(2)=1 removes the constraints for the outer edge of avecs
  44. % mode(2)=2 removes the constraints for the outer edge of avecs on only the
  45. % subbands which are not normal to the edge of the image.
  46. % mode(3)=1 removes constraints from bands 2 and 5 everywhere.
  47. % mode(4)=0 for pure affine model, 1 for (affine + xy) model, 2 for
  48. % (affine + linear zoom) model, 3 for 10-term affine + linear zoom model,
  49. % TDR 4 for translation-only model
  50. % mode(5)=0.5 for modified zoom (1.0 otherwise).
  51. % qscale defines the scale factor for the quiver plots, and equals 1 by default.
  52. % avlevel is the level of the DTCWT subbands which have the same resolution
  53. % as the avec matrix.
  54. % sizeqfilt is the size of the Q matrix smoothing filter
  55. % (no. of taps = 2*sizeqfilt + 1).
  56. % mask is a gain matrix for scaling the contraint vectors. It should be
  57. % the size of the coarsest subbands - 1. It allows parts of the image to be ignored
  58. % where mask = 0, and is usually = 1 elsewhere.
  59. %
  60. % esthemmm2 uses constraints2 for a more dense constraint vector field.
  61. % The July 2004 version allows the avec field to be at finer resolution
  62. % than the coarsest DT CWT subband resolution.
  63. %
  64. % Nick Kingsbury, Cambridge University, July 2004.
  65. if nargin < 14, mask = 1; end
  66. if nargin < 13, sizeqfilt = 2; end
  67. if nargin < 12, avlevel = length(refh); end
  68. if nargin < 11, qscale = 1; end
  69. if nargin < 10, mode = 0; end
  70. if length(mode) < 5, mode = [mode 0 0 0 0]; end
  71. if nargin < 9, debug = []; end
  72. if nargin < 8, search = 0; end
  73. fig = gcf + 1;
  74. plot_disp=0; %turns plotting of shift vectors on/off
  75. % Check matrix sizes.
  76. slo = size(refl);
  77. shi = size(refh{end});
  78. if any(size(prevl)~=slo | slo~=2*shi(1:2)) | any(size(prevh{end})~=shi) | (shi(3)~=6),
  79. error('Input matrices not correct sizes.');
  80. end
  81. % Mask matrix should be size of coarsest high bands - 1.
  82. if length(mask)==1, mask = mask*ones(shi(1:2)-1); end
  83. % Subimages are listed in order of increasing angle of rotation
  84. % from 0 to pi, starting at 15 deg anticlockwise from a horizontal edge,
  85. % and increasing by 30 deg each time.
  86. nd = size(debug,1);
  87. if nd > 0, di = debug(:,1) + (debug(:,2) - 1) * sc;
  88. else di = [];
  89. end
  90. % mat2scr([debug di],'%8d','ESTSHIFT debug at pel:')
  91. % mat2scr(r6(di,:),'%8.2f','r6:')
  92. % p6 = prevh;
  93. % Calc the expected horiz and vert phase shifts for each subband.
  94. w6 = [w(1) w(2); w(2) w(2); w(2) w(1); w(2) -w(1); w(2) -w(2); w(1) -w(2)];
  95. nsch = length(search);
  96. %affine vector cell arrays for multiple shifts
  97. av1_s=cell(nsch,1);
  98. av2_s=cell(nsch,1);
  99. av_common_s=cell(nsch,1);
  100. if mode(4) == 0, lenavec = 6;
  101. elseif mode(4) == 3, lenavec = 10;
  102. elseif mode(4) == 4, lenavec = 2;
  103. else lenavec = 8;
  104. end
  105. % Loop for each search offset.
  106. for sch = 1:nsch,
  107. srefh = size(refh{avlevel});
  108. sc = srefh(1);
  109. sr = srefh(2);
  110. % Initialise affine vector to search offset.
  111. av1 = zeros(sc-1,sr-1,lenavec);
  112. av1(:,:,2) = real(search(sch));
  113. av1(:,:,1) = imag(search(sch));
  114. av2 = zeros(sc-1,sr-1,lenavec);
  115. av2(:,:,2) = -real(search(sch));
  116. av2(:,:,1) = -imag(search(sch));
  117. av_common = zeros(sc-1,sr-1,lenavec);
  118. av_common(:,:,2) = real(search(sch));
  119. av_common(:,:,1) = imag(search(sch));
  120. delta1 = [];
  121. % Perform nit iterations on shift and del so that del is more accurate.
  122. for it = 1:nit,
  123. levels = levelsel(min(it,size(levelsel,1)),:);
  124. qvecsum1 = 0;
  125. qvecsum2 = 0;
  126. qvecsum_common = 0;
  127. % Loop for each level at the current iteration.
  128. for lev = levels(1):-1:levels(2)
  129. % Calc. size of bandpass subimages in pels.
  130. srefh = size(refh{lev});
  131. sc = srefh(1);
  132. sr = srefh(2);
  133. ss = sc * sr;
  134. sh1 = affineshift2(av1,[sc sr],mode);
  135. sh1 = affineshift2(av1,[sc sr],mode);
  136. sh2 = affineshift2(av2,[sc sr],mode);
  137. sh2 = affineshift2(av2,[sc sr],mode);
  138. sh_common = affineshift2(av_common,[sc sr],mode);
  139. sh_common = affineshift2(av_common,[sc sr],mode);
  140. % Use sh (adjusted for pel units instead of half-image units) to shift prevh.
  141. if lev <= 1, method = 'lin'; else method = 'cub'; end
  142. prevhsh = shift_cwt_bands2(prevh{lev},real(sh1)*(sr/2) + imag(sh1)*(sqrt(-1)*sc/2),method,0);
  143. refhsh = shift_cwt_bands2(refh{lev},real(sh2)*(sr/2) + imag(sh2)*(sqrt(-1)*sc/2),method,0);
  144. % if real(search(sch))==0 && imag(search(sch))==0
  145. % disp('stopped here')
  146. % sh1
  147. % sh2
  148. % prevhsh-refhsh
  149. %
  150. % 1+1
  151. % end
  152. % prevhsh-prevh{lev}
  153. % refhsh-refh{lev}
  154. % Calculate motion constraints at each point.
  155. % cvecs is a 4-D array in (y,x,band,cvec element).
  156. cvecs1 = zeros(sc-1,sr-1,6,lenavec+1);
  157. cvecs1(:,:,:,[1 2 lenavec+1]) = constraints2(refh{lev},prevhsh,w6,mode,mask);
  158. cvecs2 = zeros(sc-1,sr-1,6,lenavec+1);
  159. cvecs2(:,:,:,[1 2 lenavec+1]) = constraints2(prevh{lev},refhsh,w6,mode,mask);
  160. % cvecs
  161. % Add extra components which are equivalent to multiplying
  162. % the constraint vectors cvecs by K.' matrices:
  163. % K = [1 0 y 0 x 0 xy 0 0; 0 1 0 y 0 x 0 xy 0; 0 0 0 0 0 0 0 0 1]
  164. % for 2-D affine transform with extra xy terms.
  165. % yi and xi go from -1 to +1 across the image.
  166. % For the linear zoom model, columns 7 and 8 of K (the xy cols) are
  167. % replaced by terms in [xy x^2 0]' and [y^2 xy 0]' .
  168. s2 = sc - 1;
  169. for k=1:s2,
  170. yi = (2*k-sc) / sc;
  171. if mode(4)<=3 %TDR
  172. cvecs1(k,:,:,[3 4]) = cvecs1(k,:,:,[1 2]) * yi;
  173. cvecs2(k,:,:,[3 4]) = cvecs2(k,:,:,[1 2]) * yi;
  174. end
  175. if mode(4) == 3,
  176. cvecs1(k,:,:,10) = cvecs1(k,:,:,3) * yi;
  177. cvecs2(k,:,:,10) = cvecs2(k,:,:,3) * yi;
  178. elseif mode(4) == 2,
  179. cvecs1(k,:,:,8) = cvecs1(k,:,:,3) * (mode(5)*yi);
  180. cvecs2(k,:,:,8) = cvecs2(k,:,:,3) * (mode(5)*yi);
  181. end
  182. end
  183. s2 = sr - 1;
  184. for k=1:s2,
  185. xi = (2*k-sr) / sr;
  186. if mode(4)<=3 %TDR
  187. cvecs1(:,k,:,[5 6]) = cvecs2(:,k,:,[1 2]) * xi;
  188. cvecs2(:,k,:,[5 6]) = cvecs2(:,k,:,[1 2]) * xi;
  189. end
  190. if mode(4) == 3, % Linear zoom with separate x^2 and y^2 terms.
  191. cvecs1(:,k,:,7) = cvecs1(:,k,:,3) * xi;
  192. cvecs1(:,k,:,8) = cvecs1(:,k,:,4) * xi;
  193. cvecs1(:,k,:,9) = cvecs1(:,k,:,6) * xi;
  194. cvecs2(:,k,:,7) = cvecs2(:,k,:,3) * xi;
  195. cvecs2(:,k,:,8) = cvecs2(:,k,:,4) * xi;
  196. cvecs2(:,k,:,9) = cvecs2(:,k,:,6) * xi;
  197. elseif mode(4) == 2, % Linear zoom
  198. cvecs1(:,k,:,7) = cvecs1(:,k,:,3) * xi + cvecs1(:,k,:,6) * (mode(5)*xi);
  199. cvecs1(:,k,:,8) = cvecs1(:,k,:,4) * xi + cvecs1(:,k,:,8);
  200. cvecs2(:,k,:,7) = cvecs2(:,k,:,3) * xi + cvecs2(:,k,:,6) * (mode(5)*xi);
  201. cvecs2(:,k,:,8) = cvecs2(:,k,:,4) * xi + cvecs2(:,k,:,8);
  202. elseif mode(4) == 1,
  203. cvecs1(:,k,:,[7 8]) = cvecs1(:,k,:,[3 4]) * xi;
  204. cvecs2(:,k,:,[7 8]) = cvecs2(:,k,:,[3 4]) * xi;
  205. end
  206. end
  207. % cvecs now contains the terms K' * c .
  208. %cvecs
  209. % Form the Q-matrices as vectors of the lower left half
  210. % of the symmetric Q-matrix. Q = (K'*c*c'*K)
  211. % Combine all the constraints (subbands) at each location, ie all 6 directions.
  212. scv = size(cvecs1);
  213. c4 = scv(4);
  214. qvecs1 = zeros([scv(1:2) c4*(c4+1)/2]);
  215. qvecs2 = zeros([scv(1:2) c4*(c4+1)/2]);
  216. qvecs_common = zeros([scv(1:2) c4*(c4+1)/2]);
  217. iQ = zeros(c4,c4);
  218. k = 1;
  219. for k1 = 1:c4
  220. for k2 = k1:c4
  221. qvecs1(:,:,k) = sum(cvecs1(:,:,:,k1) .* cvecs1(:,:,:,k2),3); % Sum over all 6 directions.
  222. qvecs2(:,:,k) = sum(cvecs2(:,:,:,k1) .* cvecs2(:,:,:,k2),3); % Sum over all 6 directions.
  223. iQ(k1,k2) = k; iQ(k2,k1) = k; % indices for Q matrix and q vector.
  224. k = k + 1;
  225. end
  226. end
  227. %TDR extract first q matrix
  228. iQmat1 = iQ(1:(end-1),1:(end-1)); % Indices to convert qvec to Q.
  229. iqv1 = iQ(1:(end-1),end); % Indices to convert qvec to q.
  230. iq01 = iQ(end,end); % Index to convert qvec to q0.
  231. %TDR Extract second q matrix
  232. iQmat2 = iQ(1:(end-1),1:(end-1)); % Indices to convert qvec to Q.
  233. iqv2 = iQ(1:(end-1),end); % Indices to convert qvec to q.
  234. iq02 = iQ(end,end); % Index to convert qvec to q0.
  235. % Change the sample rate of qvecs, back to that of av, remembering
  236. % that the sizes are always odd and one less than the subband sizes.
  237. if lev < avlevel,
  238. % Reduce the sample rate.
  239. for k = lev:(avlevel-1)
  240. % First reduce no of rows, using [0.5 1 0.5] filter.
  241. t1 = 2:2:(size(qvecs1,1)-1);
  242. qvecs1 = 0.5*qvecs1(t1-1,:,:) + qvecs1(t1,:,:) + 0.5*qvecs1(t1+1,:,:);
  243. qvecs2 = 0.5*qvecs2(t1-1,:,:) + qvecs2(t1,:,:) + 0.5*qvecs2(t1+1,:,:);
  244. % Now reduce no of columns.
  245. t2 = 2:2:(size(qvecs1,2)-1);
  246. qvecs1 = 0.5*qvecs1(:,t2-1,:,:) + qvecs1(:,t2,:) + 0.5*qvecs1(:,t2+1,:);
  247. qvecs2 = 0.5*qvecs2(:,t2-1,:,:) + qvecs2(:,t2,:) + 0.5*qvecs2(:,t2+1,:);
  248. end
  249. elseif lev > avlevel,
  250. for k = (avlevel+1):lev
  251. % First increase no of rows, using [0.5 1 0.5] filter.
  252. sc = size(qvecs1,1);
  253. qv1 = [];
  254. qv2 = [];
  255. qv1([0:sc]*2+1,:,:) = 0.5 * (qvecs1([1 1:sc],:,:) + qvecs1([1:sc sc],:,:));
  256. qv1([1:sc]*2,:,:) = qvecs1;
  257. qvecs1 = qv1;
  258. qv2([0:sc]*2+1,:,:) = 0.5 * (qvecs2([1 1:sc],:,:) + qvecs2([1:sc sc],:,:));
  259. qv2([1:sc]*2,:,:) = qvecs2;
  260. qvecs2 = qv2;
  261. % Now increase no of columns.
  262. sr = size(qvecs1,2);
  263. qv1 = [];
  264. qv2 = [];
  265. qv1(:,[0:sr]*2+1,:) = 0.5 * (qvecs1(:,[1 1:sr],:) + qvecs1(:,[1:sr sr],:));
  266. qv1(:,[1:sr]*2,:) = qvecs1;
  267. qvecs1 = qv1;
  268. qv2(:,[0:sr]*2+1,:) = 0.5 * (qvecs2(:,[1 1:sr],:) + qvecs2(:,[1:sr sr],:));
  269. qv2(:,[1:sr]*2,:) = qvecs2;
  270. qvecs2 = qv2;
  271. end
  272. end
  273. %TDR added this to attempt fixing bad estimates from coarse to fine
  274. sqv1 = size(qvecs1);
  275. sqv2 = size(qvecs2);
  276. qvecs_common=zeros(sqv1);
  277. if 0
  278. qf1 = zeros(sqv1(3),1);
  279. qf2 = zeros(sqv2(3),1);
  280. for row=1:sqv1(2)
  281. for col=1:sqv1(1)
  282. qf1(:) = qvecs1(col,row,:);
  283. Qmat1 = qf1(iQmat1);
  284. %TDR try masking bad Qmatrices from qvec accumulation
  285. % if cond(-Qmat1)>1E3
  286. % qvecs1(col,row,:);
  287. % qvecs1(col,row,:)=zeros(size(qvecs1,3),1);
  288. % % disp('bad condition here:qvec1');
  289. %
  290. % end
  291. qv1 = qf1(iqv1);
  292. q01 = qf1(iq01);
  293. qf2(:) = qvecs2(col,row,:);
  294. Qmat2 = qf2(iQmat2);
  295. %TDR try masking bad Qmatrices from qvec accumulation
  296. % if cond(-Qmat2)>1E3
  297. % qvecs2(col,row,:);
  298. % qvecs2(col,row,:)=zeros(size(qvecs2,3),1);
  299. % % disp('bad condition here:qvec2');
  300. % end
  301. %
  302. qv2 = qf2(iqv2);
  303. q02 = qf2(iq02);
  304. a1 = -Qmat1 \ qv1;
  305. avec1(col,row,:) = a1;
  306. a2 = -Qmat2 \ qv2;
  307. avec2(col,row,:) = a2;
  308. % a_common = -(Qmat1 + Qmat2) \ (qv1 - qv2);
  309. % avec_common(col,row,:) = a_common;
  310. end
  311. end
  312. avec1(find(isnan(avec1)))=0;
  313. avec2(find(isnan(avec2)))=0;
  314. % avec_common(find(isnan(avec_common)))=0;
  315. perform_reg_interp=1;
  316. bandlimreg=0;
  317. maxlevel=length(prevh);
  318. dtcwtparams=struct('filter','near_sym_b','qshift','qshift_d','leveldepth',maxlevel);
  319. [Ylf Yhf]= shift_cwt_bands_from_avec(prevl,prevh,perform_reg_interp,avec1,mode,bandlimreg);
  320. [Ylb Yhb]= shift_cwt_bands_from_avec(refl,refh,perform_reg_interp,-avec1,mode,bandlimreg);
  321. Yf=dtwaveifm2(Ylf,Yhf,dtcwtparams.filter,dtcwtparams.qshift);
  322. Yb=dtwaveifm2(Ylb,Yhb,dtcwtparams.filter,dtcwtparams.qshift);
  323. % error_surf1=abs(Yhf{avlevel}-Yhb{avlevel}).^2;
  324. error_surf1=(Yf-Yb).^2;
  325. error_surf_sum1=error_surf1;
  326. % for d=1:6
  327. % if d==1
  328. % error_surf_sum1=error_surf1(:,:,d);
  329. % else
  330. % error_surf_sum1=error_surf_sum1+error_surf1(:,:,d);
  331. % end
  332. % end
  333. error_surf_sum1=refit_matrix(avec1,error_surf_sum1);
  334. [Ylf Yhf]= shift_cwt_bands_from_avec(prevl,prevh,perform_reg_interp,-avec2,mode,bandlimreg);
  335. [Ylb Yhb]= shift_cwt_bands_from_avec(refl,refh,perform_reg_interp,avec2,mode,bandlimreg);
  336. Yf=dtwaveifm2(Ylf,Yhf,dtcwtparams.filter,dtcwtparams.qshift);
  337. Yb=dtwaveifm2(Ylb,Yhb,dtcwtparams.filter,dtcwtparams.qshift);
  338. % error_surf2=abs(Yhf{avlevel}-Yhb{avlevel}).^2;
  339. error_surf2=(Yf-Yb).^2;
  340. error_surf_sum2=error_surf2;
  341. % for d=1:6
  342. % if d==1
  343. % error_surf_sum2=error_surf2(:,:,d);
  344. % else
  345. % error_surf_sum2=error_surf_sum2+error_surf2(:,:,d);
  346. % end
  347. % end
  348. error_surf_sum2=refit_matrix(avec2,error_surf_sum2);
  349. % error_surf3=abs(refh{avlevel}-prevh{avlevel}).^2;
  350. Yf=dtwaveifm2(prevl,prevh,dtcwtparams.filter,dtcwtparams.qshift);
  351. Yb=dtwaveifm2(refl,refh,dtcwtparams.filter,dtcwtparams.qshift);
  352. error_surf3=(Yf-Yb).^2;
  353. error_surf_sum3=error_surf3;
  354. % for d=1:6
  355. % if d==1
  356. % error_surf_sum3=error_surf3(:,:,d);
  357. % else
  358. % error_surf_sum3=error_surf_sum3+error_surf3(:,:,d);
  359. % end
  360. % end
  361. error_surf_sum3=refit_matrix(avec2,error_surf_sum3);
  362. for row=1:sqv1(2)
  363. for col=1:sqv1(1)
  364. %make sure we've moved in the right direction at least...
  365. if 1%error_surf_sum3(col,row)>=error_surf_sum1(col,row) || error_surf_sum3(col,row)>=error_surf_sum2(col,row)
  366. %pick the least data-erronious q-vec for each chi
  367. if error_surf_sum1(col,row)<=error_surf_sum2(col,row)
  368. qvecs_common(col,row,:)=qvecs1(col,row,:);
  369. else
  370. % qvecs_common(col,row,:)=-qvecs2(col,row,:);
  371. qf2(:) = qvecs2(col,row,:);
  372. Qmat2 = qf2(iQmat2);
  373. qv2 = qf2(iqv2);
  374. q02 = qf2(iq02);
  375. a2 = -Qmat2 \ qv2;
  376. if any(isnan(a2))
  377. a2=zeros(size(a2,1),1);
  378. else
  379. a2=-a2;
  380. end
  381. %come-up with what qvecsum2(col,row,:) should be
  382. %now
  383. qv2=-Qmat2*a2;
  384. qf2(iqv2)=qv2;
  385. qvecs_common(col,row,:)=qf2(:);
  386. % qvecs1(col,row,:)-qvecs_common(col,row,:)
  387. end
  388. else
  389. %bad initial direction. hopefully the next level picks
  390. %a good direction
  391. % disp('bad estimate at coarse level here');
  392. qvecs_common(col,row,:)=zeros(size(qvecs_common,3),1);
  393. end
  394. end
  395. end
  396. end
  397. qvecsum_common = qvecsum_common + qvecs_common;
  398. qvecsum1 = qvecsum1 + qvecs1; % Accumulate qvecs across levels of CWT.#
  399. qvecsum2 = qvecsum2 + qvecs2; % Accumulate qvecs across levels of CWT.
  400. end % End of loop for each level of CWT.
  401. % As a simple test, combine all qvecs into a single vector.
  402. qtot1 = squeeze(sum(sum(qvecsum1)));
  403. qtot2 = squeeze(sum(sum(qvecsum2)));
  404. qtot_common = squeeze(sum(sum(qvecsum_common)));
  405. % Filter the q vectors with a linear ramp filter.
  406. % Set up the 1-D filter impulse response.
  407. %TDR option to remove Q filter
  408. % if sizeqfilt(1)<=1
  409. % %do nothing to the q
  410. % else
  411. shq = sizeqfilt(min(it,end)) + 1; %
  412. hq = [1:shq (shq-1):-1:1].';
  413. hq = hq/sum(hq);
  414. for k=1:size(qvecsum1,3),
  415. qvecsum1(:,:,k) = colfilter(colfilter(qvecsum1(:,:,k),hq).',hq).';
  416. qvecsum2(:,:,k) = colfilter(colfilter(qvecsum2(:,:,k),hq).',hq).';
  417. qvecsum_common(:,:,k) = colfilter(colfilter(qvecsum_common(:,:,k),hq).',hq).';
  418. % qvecsum(:,:,k) = conv2(hqc,hqr,squeeze(qvecsum(:,:,k)),'same');
  419. if mode(1) >= it,
  420. qvecsum1(:,:,k) = qtot1(k); % Include this to use single Q matrix.
  421. qvecsum2(:,:,k) = qtot2(k); % Include this to use single Q matrix.
  422. qvecsum_common(:,:,k) = qtot_common(k); % Include this to use single Q matrix.
  423. end
  424. end
  425. % end
  426. % Now extract Q matrix, q vector and q0 scalar from each qvec vector, and
  427. % solve for the affine vector, a, which minimises the constraint error energy.
  428. iQmat1 = iQ(1:(end-1),1:(end-1)); % Indices to convert qvec to Q.
  429. iqv1 = iQ(1:(end-1),end); % Indices to convert qvec to q.
  430. iq01 = iQ(end,end); % Index to convert qvec to q0.
  431. sqv1 = size(qvecsum1);
  432. del1 = zeros(sqv1(1:2));
  433. avec1 = zeros([sqv1(1:2) lenavec]);
  434. avec2 = zeros([sqv1(1:2) lenavec]);
  435. avec_common = zeros([sqv1(1:2) lenavec]);
  436. qf1 = zeros(sqv1(3),1);
  437. %TDR Extract second q matrix
  438. iQmat2 = iQ(1:(end-1),1:(end-1)); % Indices to convert qvec to Q.
  439. iqv2 = iQ(1:(end-1),end); % Indices to convert qvec to q.
  440. iq02 = iQ(end,end); % Index to convert qvec to q0.
  441. sqv2 = size(qvecsum2);
  442. del2 = zeros(sqv2(1:2));
  443. avec2 = zeros([sqv2(1:2) lenavec]);
  444. qf2 = zeros(sqv2(3),1);
  445. iQmat_common = iQ(1:(end-1),1:(end-1)); % Indices to convert qvec to Q.
  446. iqv_common = iQ(1:(end-1),end); % Indices to convert qvec to q.
  447. iq0_common = iQ(end,end); % Index to convert qvec to q0.
  448. sqv_common = size(qvecsum_common);
  449. del_common = zeros(sqv_common(1:2));
  450. avec_common = zeros([sqv_common(1:2) lenavec]);
  451. qf_common = zeros(sqv_common(3),1);
  452. % Loops for each Q matrix locality.
  453. % zero_q_matrix_count=0; %count the numer of times a '0' constraint vector
  454. %causes poor conditioning of Q matrix
  455. cond_count1=0;
  456. cond_count2=0;
  457. cond_count3=0;
  458. scond=[size(avec1,1) size(avec1,2)];
  459. cond1=zeros(scond);
  460. cond2=zeros(scond);
  461. cond_common=zeros(scond);
  462. for row = 1:sqv1(2)
  463. for col = 1:sqv1(1)
  464. % Extract Q, q and q0.
  465. qf1(:) = qvecsum1(col,row,:);
  466. Qmat1 = qf1(iQmat1);
  467. qv1 = qf1(iqv1);
  468. q01 = qf1(iq01);
  469. qf2(:) = qvecsum2(col,row,:);
  470. Qmat2 = qf2(iQmat2);
  471. qv2 = qf2(iqv2);
  472. q02 = qf2(iq02);
  473. qf_common(:) = qvecsum_common(col,row,:);
  474. Qmat_common = qf_common(iQmat_common);
  475. qv_common = qf_common(iqv_common);
  476. q0_common = qf_common(iq0_common);
  477. % Solve for a_min:
  478. %TDR
  479. %a = -Qmat \ qv;
  480. %if (cond(Qmat)>1E3)
  481. % if any(isnan(a))
  482. % cond(-Qmat)
  483. % poor_condition_count=poor_condition_count+1;
  484. % if sum(Qmat(:))<=1
  485. % zero_q_matrix_count=zero_q_matrix_count+1;
  486. % end
  487. % end
  488. %make sure matrix inversion is possible first..
  489. if cond(-Qmat1)>1E3
  490. a1=zeros(size(qv1));
  491. % poor_condition_count=poor_condition_count+1;
  492. else
  493. a1 = -Qmat1 \ qv1;
  494. end
  495. % a1 = -Qmat1 \ qv1;
  496. cond_count1=cond_count1+(cond(-Qmat1)>1E2);
  497. avec1(col,row,:) = a1;
  498. if cond(-Qmat2)>1E3
  499. a2=zeros(size(qv2));
  500. % poor_condition_count=poor_condition_count+1;
  501. else
  502. a2 = -Qmat2 \ qv2;
  503. end
  504. % a2 = -Qmat2 \ qv2;
  505. cond_count2=cond_count2+(cond(-Qmat2)>1E2);
  506. avec2(col,row,:) = a2;
  507. if cond(-Qmat_common)>1E3
  508. a_common=zeros(size(qv_common));
  509. % poor_condition_count=poor_condition_count+1;
  510. else
  511. a_common = -Qmat_common \ qv_common;
  512. end
  513. % a_common = -Qmat_common \ qv_common;
  514. cond_count3=cond_count3+(cond(-(Qmat_common))>1E2);
  515. %assumption of "exact-same forwards and reverse displacement
  516. %field"
  517. % a_common = -(Qmat1 + Qmat2) \ (qv1 - qv2);
  518. % cond_count3=cond_count3+(cond(-(Qmat1+Qmat2))>1E10);
  519. avec_common(col,row,:) = a_common;
  520. cond1(col,row)=cond(-Qmat1);
  521. cond2(col,row)=cond(-Qmat2);
  522. cond_common(col,row)=cond(-Qmat_common);
  523. % cond_common(col,row)=cond(-(Qmat1+Qmat2));
  524. % Calculate the error energy:
  525. del1(col,row) = a1.'*Qmat1*a1 + 2*qv1.'*a1 + q01;
  526. del2(col,row) = a2.'*Qmat2*a2 + 2*qv1.'*a2 + q02;
  527. del_common(col,row) = a_common.'*(Qmat_common)*a_common + 2*(qv_common).'*a_common+ (q0_common);
  528. % del_common(col,row) = a_common.'*(Qmat1+Qmat2)*a_common + 2*(qv1+qv2).'*a_common+ (q01+q02);
  529. end
  530. end
  531. %TDR display poor conditioning percentage
  532. % disp('percentage bad Q matrix from 0-constraint vector...');
  533. % poor_condition_count/(row*col)
  534. % zero_q_matrix_count/poor_condition_count
  535. % Update av.
  536. disp(['level: ' num2str(lev)]);
  537. disp(['ill-condition: 1 ' num2str(cond_count1)]);
  538. disp(['ill-condition: 2 ' num2str(cond_count2)]);
  539. disp(['ill-condition: 3 ' num2str(cond_count3)]);
  540. av1 = av1 + avec1;
  541. av2 = av2 + avec2;
  542. av_common = av_common + avec_common;
  543. % Create shift vector at same resolution as av.
  544. sav1 = size(av1) + [1 1 0];
  545. sh11 = affineshift2(avec1,sav1,mode);
  546. maxsh11 = max(abs(sh11(:))); % Display max extra shift on this iteration.
  547. sav2 = size(av2) + [1 1 0];
  548. sh12 = affineshift2(avec2,sav2,mode);
  549. maxsh12 = max(abs(sh12(:))); % Display max extra shift on this iteration.
  550. sav_common = size(av_common) + [1 1 0];
  551. sh1_common = affineshift2(avec_common,sav_common,mode);
  552. maxsh1_common = max(abs(sh1_common(:))); % Display max extra shift on this iteration.
  553. % Update shift.
  554. sh1 = affineshift2(av1,sav1,mode);
  555. sh2 = affineshift2(av2,sav2,mode);
  556. sh_common = affineshift2(av_common,sav_common,mode);
  557. % Plot shift vectors.
  558. if (plot_disp)
  559. figure(fig); set(gcf,'DefaultLineLineWidth',1.5);
  560. quiver(-real(sh)*sav(2)/2*qscale,-imag(sh)*sav(1)/2*qscale,0);
  561. set(gcf,'position',[700 30 500 672]);
  562. set(gca,'position',[0.01 0.01 .98 .98]);
  563. axis equal;
  564. axis ij;
  565. axis([-1 sav(2)+2 -1 sav(1)+2]);
  566. settitle(sprintf('%d iteration, output shift vectors',it));
  567. drawnow
  568. fig = fig + 1;
  569. end
  570. % Monitor the mean squared error and the mean affine vector (in pels).
  571. delta11(it)=mean(del1(:));
  572. avec11=squeeze(mean(mean(av1,1),2));
  573. avec11(1:2:end) = avec11(1:2:end)*size(refh{1},1);
  574. avec11(2:2:end) = avec11(2:2:end)*size(refh{1},2);
  575. delta12(it)=mean(del2(:));
  576. avec12=squeeze(mean(mean(av2,1),2));
  577. avec12(1:2:end) = avec12(1:2:end)*size(refh{1},1);
  578. avec12(2:2:end) = avec12(2:2:end)*size(refh{1},2);
  579. delta1_common(it)=mean(del_common(:));
  580. avec1_common=squeeze(mean(mean(av_common,1),2));
  581. avec1_common(1:2:end) = avec1_common(1:2:end)*size(refh{1},1);
  582. avec1_common(2:2:end) = avec1_common(2:2:end)*size(refh{1},2);
  583. % levels,delta1(it),avec1
  584. % Debug info:
  585. % mat2scr([real(sh(di))*16 imag(sh(di))*16 del(di)],'%10.4f',...
  586. % 're(sh)*16 im(sh)*16 del:')
  587. %
  588. end % End of iterations.
  589. % for k=1:6,
  590. % t=[28:29 36:37];
  591. % k,[r6(t,k) p6i(t,k) p61(t,k)]
  592. % end
  593. % Update shift, curv and delta at points where del < delta and sh is
  594. % close enough to shi.
  595. av1_s{sch}=avec1;
  596. av2_s{sch}=avec2;
  597. av_common_s{sch}=avec_common;
  598. % if sch == 1,
  599. shift1 = sh1;
  600. delta1 = del1;
  601. shift2 = sh2;
  602. delta2 = del2;
  603. shift_common = sh_common;
  604. delta_common = del_common;
  605. % else
  606. % if rem(mode,2) == 1,
  607. % dmin1 = find(del1./(sum(esurf(:,1:2)')'+1e-6) < ...
  608. % (delta1(:)./(sum(curv(:,1:2)')'+1e-6)-1e-5) & absl1(sh1(:) - shi(:)) < 0.6);
  609. % dmin2 = find(del2./(sum(esurf(:,1:2)')'+1e-6) < ...
  610. % (delta2(:)./(sum(curv(:,1:2)')'+1e-6)-1e-5) & absl1(sh2(:) - shi(:)) < 0.6);
  611. % dmin_common = find(del_common./(sum(esurf(:,1:2)')'+1e-6) < ...
  612. % (delta_common(:)./(sum(curv(:,1:2)')'+1e-6)-1e-5) & absl1(sh_common(:) - shi(:)) < 0.6);
  613. % else
  614. % dmin1 = find(del1 < (delta1(:) - 1e-2) & absl1(sh1(:) - shi(:)) < 0.6);
  615. % dmin2 = find(del2 < (delta2(:) - 1e-2) & absl1(sh2(:) - shi(:)) < 0.6);
  616. % dmin_common = find(del_common < (delta_common(:) - 1e-2) & absl1(sh_common(:) - shi(:)) < 0.6);
  617. % end
  618. % % if ~isempty(dmin),
  619. % % s=search(sch)
  620. % % [dmin(:) shift(dmin)*16 sh(dmin)*16]
  621. % % [dmin(:) delta(dmin) del(dmin)]
  622. % % end
  623. % shift1(dmin1) = sh1(dmin1);
  624. % delta1(dmin1) = del1(dmin1);
  625. %
  626. % shift2(dmin2) = sh2(dmin2);
  627. % delta2(dmin2) = del2(dmin2);
  628. %
  629. % shift_common(dmin_common) = sh_common(dmin_common);
  630. % delta_common(dmin_common) = del_common(dmin_common);
  631. % end
  632. % mat2scr([real(shift(di))*16 imag(shift(di))*16 delta(di)],'%10.4f',...
  633. % 'After min, re(shift)*16 im(shift)*16 delta:')
  634. %
  635. end % End of search offsets
  636. % keyboard
  637. % r6a=r6(28,:).';p6a=p6(4,[4:8:48]).';[r6a p6a r6a.*conj(p6a)/10]
  638. % Uncomment next line to plot mean value of delta vs iteration.
  639. % figure; semilogy(delta1); grid on; pause(0.1)
  640. return