当前位置:   article > 正文

CT图像重建算法——迭代算法ART_art算法步骤

art算法步骤

迭代图像重建的方法可分为迭代迭代法和统计迭代法,代数迭代法以代数重建算法(Algebraic Reconstruction Technique,ART)为代表。ART适合于不完全投影数据的图像重建,其抗噪声干扰能力强,另外可以结合一些先验知识进行求解,ART最大的缺点是计算量大,重建速度慢。

代数重建算法(ART)是由Kaczmarz于1937年在求解相容线性方程组时提出的,随后得到 Tanabe 的进一步阐明。ART先假设一幅初始图像,通过“正向投影”得到一个计算的投影,然后将计算的投影与实际测量投影相比较,基于比较的差值来估计修正值,将修正值均匀地分配给射线经过的那些像素上,逐条射线地执行这一过程,直到满足要求。

  1. clc;
  2. clear all;
  3. close all;
  4. N=180;
  5. N2=N^2;
  6. I=phantom(N);
  7. theta=linspace(0,180,61);
  8. theta=theta(1:60);%投影角度
  9. %产生投影数据%
  10. P_num=260;%探测器通道个数
  11. % P=ParallelBFP(theta,N,P_num);%解析法产生投影数据
  12. P=radon(I,theta);
  13. %获取投影矩阵%
  14. delta=1;%网格大小
  15. [W_ind,W_dat]=SystemMatrixV2(theta,N,P_num,delta);
  16. %进行ART迭代
  17. F=zeros(N2,1);
  18. lambda=0.25;
  19. c=0;
  20. irt_num=10;
  21. while (c<irt_num)
  22. for j=1:length(theta)
  23. for i=1:1:P_num
  24. %取得一条射线所穿过的网格编号和长度
  25. u=W_ind((j-1)*P_num+i,:);%编号
  26. v=W_dat((j-1)*P_num+i,:);%长度
  27. %如果射线不经过任何像素,不作计算
  28. if any(u)==0
  29. continue;
  30. end
  31. %恢复投影矩阵中与这一条射线对应的行向量w
  32. w=zeros(1,N2);
  33. ind=find(u>0);
  34. w(u(ind))=v(ind);
  35. PP=w*F;
  36. error=P(i,j)-PP;
  37. C=error/sum(w.^2).*w';
  38. F=F+lambda*C;
  39. end
  40. end
  41. F(F<0)=0;%小于0的像素值置为0;
  42. c=c+1;
  43. end
  44. F=reshape(F,N,N)';
  45. figure(1);
  46. imshow(I);xlabel('(a)180*180头模型图像');
  47. figure(2);
  48. imshow(F);xlabel('(b)ART算法重建的图像');
  49. %计算投影矩阵
  50. function [W_ind,W_dat]=SystemMatrixV2(theta,N,P_num,delta)
  51. %P_num:每个投影角度下的射线条数(探测器通道个数)
  52. %delta:网格大小
  53. %W_ind:存储投影射线所穿过的网格的编号的矩阵,M行,2*N列
  54. %W_dat:存储投影射线所穿过的网格的长度的矩阵,M行,2*N列
  55. %%用于验证的一小段程序
  56. % theta=45;
  57. % N=10;
  58. % P_num=15;
  59. % delta=1;
  60. %------
  61. N2=N^2;
  62. M=length(theta)*P_num;%投影射线的总条数
  63. W_ind=zeros(M,2*N);
  64. W_dat=zeros(M,2*N);
  65. % t_max=sqrt(2)*N*delta;
  66. % t=linspace(-t_max/2,t_max/2,P_num);
  67. t=(-(P_num-1)/2:(P_num-1)/2+1);
  68. %t=(-(P_num-1)/2:(P_num-1)/2)*delta;%探测器坐标
  69. for jj=1:length(theta)
  70. th=theta(jj);
  71. for ii=1:1:P_num
  72. %完成一条射线权因子向量的计算
  73. u=zeros(1,2*N);
  74. v=zeros(1,2*N);
  75. if th==0
  76. %如果超出网格范围,计算下一条
  77. if (t(ii)>=N/2*delta) || (t(ii)<=-N/2*delta)
  78. continue
  79. end
  80. kin=ceil(N/2+t(ii)/delta);
  81. kk=kin:N:(kin+N*(N-1));
  82. u(1:N)=kk;
  83. v(1:N)=ones(1,N)*delta;
  84. elseif th==90
  85. %如果超出网格范围,计算下一条
  86. if (t(ii)>=N/2*delta) || (t(ii)<=-N/2*delta)
  87. continue
  88. end
  89. kout=N*ceil(N/2-t(ii)/delta);
  90. kk=(kout-(N-1)):kout;
  91. u(1:N)=kk;
  92. v(1:N)=ones(1,N)*delta;
  93. %%投影角度等于0时%%
  94. else
  95. if th>90
  96. th_temp=th-90;
  97. elseif th<90
  98. th_temp=90-th;
  99. end
  100. th_temp=th_temp*pi/180;
  101. %确定射线y=mx+b的m和b
  102. b=t/cos(th_temp);
  103. m=tan(th_temp);
  104. y1d=(-N/2)*delta*m+b(ii);
  105. y2d=(N/2)*delta*m+b(ii);
  106. if (y1d<-N/2*delta && y2d<-N/2*delta)||(y1d>N/2*delta && y2d>N/2*delta)
  107. continue
  108. end
  109. %%确定入射点(xin,yin)、出射点(xout,yout)及参数d1%
  110. if y1d<=N/2*delta && y1d>=-N/2*delta && y2d>N/2*delta
  111. yin=y1d;
  112. yout=N/2*delta;
  113. xout=(yout-b(ii))/m;
  114. kin=N*floor(N/2-yin/delta)+1;
  115. kout=ceil(xout/delta)+N/2;
  116. d1=yin-floor(yin/delta)*delta;
  117. elseif y1d<=N/2*delta && y1d>=-N/2*delta && y2d>=-N/2*delta && y2d<N/2*delta
  118. yin=y1d;
  119. yout=y2d;
  120. kin=N*floor(N/2-yin/delta)+1;
  121. kout=N*floor(N/2-yout/delta)+N;
  122. d1=yin-floor(yin/delta)*delta;
  123. elseif y1d<-N/2*delta && y2d>N/2*delta
  124. yin=-N/2*delta;
  125. yout=N/2*delta;
  126. xin=(yin-b(ii))/m;
  127. xout=(yout-b(ii))/m;
  128. kin=N*(N-1)+N/2+ceil(xin/delta);
  129. kout=ceil(xout/delta)+N/2;
  130. d1=N/2*delta+(floor(xin/delta)*delta*m+b(ii));
  131. elseif y1d<-N/2*delta && y2d>=-N/2*delta && y2d<N/2*delta
  132. yin=-N/2*delta;
  133. yout=y2d;
  134. xin=(yin-b(ii))/m;
  135. kin=N*(N-1)+N/2+ceil(xin/delta);
  136. kout=N*floor(N/2-yout/delta)+N;
  137. d1=N/2*delta+(floor(xin/delta)*delta*m+b(ii));
  138. else
  139. continue
  140. end
  141. %计算射线i穿过像素的编号和长度%
  142. k=kin;
  143. c=0;
  144. d2=d1+m*delta;
  145. while k>=1 && k<=N2
  146. c=c+1;
  147. if d1 >=0 && d2>delta
  148. u(c)=k;
  149. v(c)=(delta-d1)*sqrt(m^2+1)/m;
  150. if k>N && k~=kout
  151. k=k-N;
  152. d1=d1-delta;
  153. d2=d1+m*delta;
  154. else
  155. break;
  156. end
  157. elseif d1>=0 && d2==delta
  158. u(c)=k;
  159. v(c)=delta*sqrt(m^2+1);
  160. if k>N && k~=kout
  161. k=k-N-1;
  162. d1=0;
  163. d2=d1+m*delta;
  164. else
  165. break
  166. end
  167. elseif d1>=0 && d2<delta
  168. u(c)=k;
  169. v(c)=delta*sqrt(m^2+1);
  170. if k~=kout
  171. k=k+1;
  172. d1=d2;
  173. d2=d1+m*delta;
  174. else
  175. break
  176. end
  177. elseif d1<=0 && d2>=0 && d2<=delta
  178. u(c)=k;
  179. v(c)=d2*sqrt(m^2+1)/m;
  180. if k~=kout
  181. k=k+1;
  182. d1=d2;
  183. d2=d1+m*delta;
  184. else
  185. break
  186. end
  187. elseif d1<=0 && d2>delta
  188. u(c)=k;
  189. v(c)=delta*sqrt(m^2+1)/m;
  190. if k>N && k~=kout
  191. k=k-N;
  192. d1=d1-delta;
  193. d2=d1+m*delta;
  194. else
  195. break
  196. end
  197. elseif d1<=0 && d2==delta
  198. u(c)=k;
  199. v(c)=delta*sqrt(m^2+1)/m;
  200. if k>N && k~=kout
  201. k=k-N-1;
  202. d1=0;
  203. d2=m*delta;
  204. else
  205. break
  206. end
  207. end
  208. end
  209. %如果投影角度小于90,还需要利用投影射线关于y轴的对称性计算出权因子向量
  210. if th<90
  211. u_temp=zeros(1,2*N);
  212. if any(u)==0
  213. continue;
  214. end
  215. ind=find(u>0);
  216. for k=1:length(u(ind))
  217. r=rem(u(k),N);
  218. if r==0
  219. u_temp(k)=u(k)-N+1;
  220. else
  221. u_temp(k)=u(k)-2*r+N+1;
  222. end
  223. end
  224. u=u_temp;
  225. end
  226. end
  227. W_ind((jj-1)*P_num+ii,:)=u;
  228. W_dat((jj-1)*P_num+ii,:)=v;
  229. end
  230. end
  231. function P=ParalleBFP(theta,N,N_d)
  232. shep=[1 .69 .92 0 0 0
  233. -.8 .6624 .8740 0 -.0184 0
  234. -.2 .1100 .3100 .22 0 -18
  235. -.2 .1600 .4100 -.22 0 18
  236. .1 .2100 .2500 0 .35 0
  237. .1 .0460 .0460 0 .1 0
  238. .1 .0460 .0460 0 -.1 0
  239. .1 .0460 .0230 -.08 -.605 0
  240. .1 .0230 .0230 0 -.606 0
  241. .1 .0230 .0460 .06 -.605 0];
  242. theta_num=length(theta);
  243. P=zeros(N_d,theta_num); %存放投影数据
  244. rho=shep(:,1); %椭圆对应密度
  245. ae=0.5*N*shep(:,2);%椭圆短半轴
  246. be=0.5*N*shep(:,3);%椭圆长半轴
  247. xe=0.5*N*shep(:,4);%椭圆中心x坐标
  248. ye=0.5*N*shep(:,5);%椭圆中心y坐标
  249. alpha=shep(:,6);%椭圆旋转角度
  250. alpha=alpha*pi/180;
  251. theta=theta*pi/180;%角度换算弧度
  252. TT=-(N_d-1)/2:(N_d-1)/2;%探测器坐标
  253. for k1=1:theta_num
  254. P_theta=zeros(1,N_d);
  255. for k2=1:max(size(xe))
  256. a =(ae(k2)*cos(theta(k1)-alpha(k2)))^2+(be(k2)*sin(theta(k1)-alpha(k2)))^2;
  257. temp=a-(TT-xe(k2)*cos(theta(k1))-ye(k2)*sin(theta(k1))).^2;
  258. ind=temp>0;%根号内值需为非负
  259. P_theta(ind)=P_theta(ind)+rho(k2)*(2*ae(k2)*be(k2)*sqrt(temp(ind)))./a;
  260. end
  261. P(:,k1)=P_theta;
  262. end

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号