CT的一种直接反投影重建
用一个例子来解释有关CT的一种直接反投影重建算法的方法。按照计算可以很好的重建的,但是在MATLAB上跑出来的重建效果比MATLAB自带的iradon()差。。。。4×4矩阵[1 2;3 4]从0、45、90、145投影。那么对于1这个点,在四次投影完之后,就是 (衰减系数值) * 4(角度数)+其它的值(2,3,4)μ_1^’=μ_1×4+μ_2+μ_3+μ_4=1×4+2+3+4=13同样的道
用一个例子来解释有关CT(平行束)的一种直接反投影重建算法的方法。是对一种算法的基数取值进行计算。按照计算可以很好的重建的,但是在MATLAB上跑出来的重建效果比MATLAB自带的iradon()差。。。。
4×4矩阵,从0°、45°、90°、145°投影。(正上方为0°)
[1234] \begin{bmatrix} 1&2 \\ 3&4 \end{bmatrix} [1324]
那么对于1这个点,在四次投影完之后,就是 (衰减系数值)×4(角度数)+其它的值(2,3,4)
μ1′=μ1×4+μ2+μ3+μ4=1×4+2+3+4=13 μ_{1}'=μ_{1}×4+μ_{2}+μ_{3}+μ_{4}=1×4+2+3+4=13 μ1′=μ1×4+μ2+μ3+μ4=1×4+2+3+4=13
同样的道理,对于2这个点
μ2′=μ2×4+μ1+μ3+μ4=2×4+1+3+4=16 μ_{2}'=μ_{2}×4+μ_{1}+μ_{3}+μ_{4}=2×4+1+3+4=16 μ2′=μ2×4+μ1+μ3+μ4=2×4+1+3+4=16
对于3为19、4为22.
[13161922] \begin{bmatrix} 13&16 \\ 19&22 \end{bmatrix} [13191622]
然后就可以发现:
μ1′=μ1×3+μ1+μ2+μ3+μ4=μ1×3+μsum=13 μ_{1}'=μ_{1}×3+μ_{1}+μ_{2}+μ_{3}+μ_{4}\\=μ_{1}×3+μ_{sum}=13 μ1′=μ1×3+μ1+μ2+μ3+μ4=μ1×3+μsum=13
μsumμ_{sum}μsum是原图像所有体素的总和,但是我们就是需要重建它所以得不到。
但是,当我们把各个投影值相加我们可以得到
μ1′+μ2′+μ3′+μ4′=(μ1+μ2+μ3+μ4)×3+μsum×4=70 μ_{1}'+μ_{2}'+μ_{3}'+μ_{4}'\\=(μ_{1}+μ_{2}+μ_{3}+μ_{4})×3+μ_{sum}×4=70 μ1′+μ2′+μ3′+μ4′=(μ1+μ2+μ3+μ4)×3+μsum×4=70
所以很容易发现μsumμ_{sum}μsum就是基数;
而这个4就是像素数2×2;而这个3不难发现就是角度数减1.
但是这存在一个问题,在我们投影的时候是不会建立如[4 4;6 6]这样的矩阵的。我们只能得到四个一维数组,分别如下。
[4,6][3,5,2][7,3][4,5,1] [4,6][3,5,2][7,3][4,5,1] [4,6][3,5,2][7,3][4,5,1]
可以这么理解,就是光绕着中心做了4个投影,那么每一个数组的求和值就是原图像所有体素的总和,也就是μsumμ_{sum}μsum,我们的基数。所以这种情况下,四个数组求和值的求和与μsumμ_{sum}μsum的关系仅仅和我们的角度数有关。
4+6+3+5+2+7+3+4+5+1=40;40/4=10; 4+6+3+5+2+7+3+4+5+1=40;\\ 40/4=10; 4+6+3+5+2+7+3+4+5+1=40;40/4=10;
虽然这能更简便算出基数,但是[13 16;19 22]这个矩阵依旧得不到,我采用了旋转相加的方式,但是这就会存在误差。
现在,假设我们有了,[13 16;19 22],也通过上面的方法计算出了基数10;那么减去基数就能得到矩阵[3 6;9 12],就可以进行乘除、获得图像了。
总结,基数就是各个方向投影值的总和减投影角度数
计算[1 3;5 7] ;从0、45、90、145投影。
对于256*256的头模型,进行0~179角度投影重建。可以发现重建的存在伪迹、并且不如iradon,可能就是采用了旋转相加的方法得到矩阵和。也可能是数学上的问题。。
星状伪迹,矩阵
[0000000000001000000000000] \begin{bmatrix} 0&0&0&0&0 \\ 0&0&0&0&0 \\ 0&0&1&0&0 \\ 0&0&0&0&0 \\ 0&0&0&0&0 \\ \end{bmatrix} ⎣⎢⎢⎢⎢⎡0000000000001000000000000⎦⎥⎥⎥⎥⎤
clear;clc;
n =45; % 步进的角度值
% P = phantom();
P = [1 3;5 7];
% P = [5 2 ; 1 0];
% P = [0 0 0 0 0;0 0 0 0 0;0 0 1 0 0;0 0 0 0 0;0 0 0 0 0;];
subplot(131);imshow(P,[]);title('原图像');
theta = 0:n:180-n;
dtheta = theta(2) - theta(1);
angles_num = numel(theta); %角度的数量
[R1,xp] = radon(P,theta);
% 首先我们可以得到各个方向上的一维数组(2*2->7)(256*256->367)
% 不知道为什么会是7,理论上2*根号2足够了
R2 = R1';
R = zeros(length(R2(1,:)),length(R2(1,:)));
for theta = 0:n:180-n
i = theta / dtheta + 1;
Expand = repmat(R2(i,:),[length(R2(1,:)),1]);
% 然后将这些数组还原成一维数组长宽的矩阵
Spin = imrotate(Expand,theta,'crop');
%矩阵旋转(伪迹形成的主要原因)
R = R+Spin;
% 矩阵相加
end
% R = [4 6 ;4 6] + [5 2;3 5] + [3 3;7 7] + [1 5;5 4];
% R = [6 2 ;6 2] + [5 2;1 5] + [7 7;1 1] + [5 2;1 0];
% 计算基数
% Pixels = numel(P); %图像的像素值
% angles_num = numel(theta);
base = sum(sum(radon(P,theta)))/angles_num;
% 重建后的矩阵
I = ((R - base))-0.19./0.19.*1000;
subplot(132);imshow(I,[]);title('自己重建');
% 直接反投影
I2 = iradon(R1,dtheta,'None');
subplot(133);imshow(I2,[]);title('iradon');
最后我发现基数取其它的值,重建的效果与计算出来的没差????
更多推荐



所有评论(0)