#作者:CSDN用户“宋体的微软雅黑(hsyxxyg)”
#时间:2020年6月18日
#脚本任务:生成投影系统矩阵,并利用此矩阵进行ART重建。
import numpy as np
import pandas as pd
from scipy import ndimage
import imageio
import matplotlib.pyplot as plt
def CalSystemMatrix(theta, pictureSize, projectionNum, delta):
squareChannels = np.power(pictureSize, 2)
totalPorjectionNum = len(theta) * projectionNum
gridNum = np.zeros((totalPorjectionNum, 2 * pictureSize))
gridLen = np.zeros((totalPorjectionNum, 2 * pictureSize))
t = np.arange(-(pictureSize - 1) / 2, (pictureSize - 1) / 2+1)
for loop1 in range(len(theta)):
for loop2 in range(pictureSize):
u = np.zeros((2 * pictureSize))
v = np.zeros((2 * pictureSize))
th = theta[loop1]
if th == 90:
#如果计算的结果超出了网格的范围,则立刻开始计算下一个射束
if ((t[loop2] >= pictureSize / 2 * delta) or (t[loop2] <= - pictureSize / 2 * delta)):
continue
kout = pictureSize * np.ceil(pictureSize/2 - t[loop2]/delta)
kk = np.arange(kout - (pictureSize -1 ), kout+1)
u[0:pictureSize] = kk
v[0:pictureSize] = np.ones(pictureSize) * delta
elif th==0:
if (t[loop2] >= pictureSize / 2 * delta) or (t[loop2] <= -pictureSize / 2 * delta):
continue
kin = np.ceil(pictureSize/2 + t[loop2] / delta)
kk = np.arange(kin, (kin + pictureSize * pictureSize), step=pictureSize)
u[0:pictureSize] = kk
v[0:pictureSize] = np.ones(pictureSize) * delta
else:
if th>90:
th_temp = th - 90
elif th<90:
th_temp = 90 - th
th_temp = th_temp * np.pi / 180
#计算束线的斜率和截距
b = t / np.cos(th_temp)
m = np.tan(th_temp)
y1d = -(pictureSize / 2) * delta * m + b[loop2]
y2d = (pictureSize / 2) * delta * m + b[loop2]
#if (y1d < -pictureSize / 2 * delta and y2d < -pictureSize/2 * delta) or (y1d > pictureSize / 2 * delta and y2d > -pictureSize / 2 * delta):
if (y1d < -pictureSize / 2 * delta and y2d < -pictureSize/2 * delta) or (y1d > pictureSize / 2 * delta and y2d > pictureSize / 2 * delta):
continue
if (y1d <= pictureSize / 2 * delta and y1d >= -pictureSize/2 * delta and y2d > pictureSize / 2 * delta):
yin = y1d
d1 = yin - np.floor(yin / delta) * delta
kin = pictureSize * np.floor(pictureSize / 2 - yin / delta) + 1
yout = pictureSize / 2 * delta
xout = (yout - b[loop2]) / m
kout = np.ceil(xout / delta) + pictureSize / 2
elif (y1d <= pictureSize/2 * delta and y1d >= -pictureSize/2 * delta and y2d >= -pictureSize/2 * delta and y2d < pictureSize/2 * delta):
yin = y1d
d1 = yin - np.floor(yin/delta) * delta
kin = pictureSize * np.floor(pictureSize / 2 - yin / delta) + 1
yout = y2d
#1:
#2:xout = (yout - b[loop2]) / m
kout = pictureSize * np.floor(pictureSize/2 - yout/delta) + pictureSize
elif (y1d < - pictureSize / 2 * delta and y2d > pictureSize / 2 * delta):
yin = - pictureSize / 2 * delta
xin = (yin - b[loop2]) / m
d1 = pictureSize / 2 * delta + np.floor(xin / delta) * delta * m + b[loop2]
kin = pictureSize * (pictureSize - 1) + pictureSize / 2 + np.ceil(xin / delta)
yout = pictureSize / 2 * delta
#error: xout = (yout / b[loop2])/m
xout = (yout - b[loop2]) / m
kout = np.ceil(xout / delta) + pictureSize / 2
elif (y1d < - pictureSize / 2 * delta and y2d >= -pictureSize / 2 * delta and y2d < pictureSize / 2 * delta):
yin = -pictureSize / 2 * delta
xin = (yin - b[loop2]) / m
d1 = pictureSize / 2 * delta + np.floor(xin / delta) * delta * m + b[loop2]
kin = pictureSize * (pictureSize - 1) + pictureSize / 2 + np.ceil(xin / delta)
yout = y2d
kout = pictureSize * np.floor(pictureSize / 2 - yout / delta) + pictureSize
else:
continue
#计算第i条射束穿过的像素的编号和长度
k = kin
c = 0
d2 = d1 + m * delta
while k >= 1 and k <= squareChannels:
if d1 >= 0 and d2 > delta:
u[c] = k
v[c] = (delta - d1) * np.sqrt(np.power(m, 2) + 1) / m
if k > pictureSize and k != kout:
k = k - pictureSize
d1 = d1 - delta
d2 = d1 + m * delta
else:
break
elif d1 >= 0 and d2 == delta:
u[c] = k
v[c] = delta * np.sqrt(np.power(m, 2) + 1)
if k>pictureSize and k != kout:
k = k - pictureSize + 1
d1 = 0
d2 = d1 + m * delta
else:
break
elif d1 >= 0 and d2 < delta:
u[c] = k
v[c] = delta * np.sqrt(np.power(m, 2) + 1)
if k!=kout:
k = k + 1
d1 = d2
d2 = d1 + m * delta
else:
break
elif d1 <= 0 and d2 >= 0 and d2 <= delta:
u[c] = k
v[c] = d2 * np.sqrt(np.power(m, 2) + 1) / m
if k != kout:
k = k + 1
d1 = d2
d2 = d1 + m * delta
else:
break
elif d1 <= 0 and d2 > delta:
u[c] = k
v[c] = delta * np.sqrt(np.power(m, 2) + 1) / m
if k > pictureSize and k != kout:
k = k - pictureSize
#k = k + 1
d1 = -delta + d1
d2 = d1 + m * delta
else:
break
else:
print(d1, d2, "error!!!")
c = c + 1
#如果投影角度小于90度,应该利用投影射线关于y轴的对称性计算出权重因子向量。
if th < 90:
u_temp = np.zeros(2 * pictureSize)
if u.any() == 0:
continue
indexULTZero = np.where(u>0)
for innerloop in range(len(u[indexULTZero])):
r = np.mod(u[innerloop], pictureSize)
if r == 0:
u_temp[innerloop] = u[innerloop] - pictureSize
else:
u_temp[innerloop] = u[innerloop] - 2 * r + pictureSize
u = u_temp
gridNum[loop1 * projectionNum + l
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
CT重建算法,迭代重建算法,ART算法的实现(亲测可运行) ART(Algebra Reconstruction Technique, ART),即代数重建法。 在图像重建方法中,迭代重建法的经典方法是Gorden R.等提出的代数重建法(Algebra Reconstruction Technique, ART),及Gilbert P.提出的联合迭代重建算法(Simultaneous Iterative Reconstruction Technique, SIRT)。 (1) 联合代数重建方法(SART) 代数重建算法在迭代过程中,每次投影计算的修正值并不是完全相同,穿过同一像素网格时,图像的模糊误差修正将会引起重建区域的严重噪声,且算法需要较多的迭代次数才能得到较好的重建结果,重建效率不高。针对这些问题Anderson和Kak于1984年提出了联合代数重建算法。该算法对于每个像素是同一投影角度内通过该像素的所有射线误差值之累加,其实质就是对ART中的噪声进行了平滑,因此可以获得较为理想的重建结果。 (2) 乘型代数重建方法(Multiplicative ATR ,MATR) 上面所
资源推荐
资源详情
资源评论
收起资源包目录
ART.rar (13个子文件)
ART
shepplogan.jpg 6KB
gridLen.csv 95.23MB
gridNum.csv 47.22MB
.idea
misc.xml 188B
.name 6B
modules.xml 265B
workspace.xml 6KB
.gitignore 184B
inspectionProfiles
profiles_settings.xml 174B
ART.iml 291B
try.py 124B
ART.py 11KB
modify90Sample.png 85KB
共 13 条
- 1
资源评论
- 陈熙昊2023-07-24这个文件的实现方法相当中肯,没有过多的主观判断,非常实用。
- thebestuzi2023-07-24作者在实现上没有太多花哨的设计,更注重算法的本质,使得代码简单而易懂。
- 莉雯Liwen2023-07-24这个文件提供了关于CT重建算法、迭代重建算法和ART算法的实现,对于想深入理解这些算法的人来说非常有帮助。
- 图像车间2023-07-24这份文件的实现代码经过亲测可运行,为研究这些算法的人提供了一个可靠的参考。
- 创业青年骁哥2023-07-24对于对CT重建算法、迭代重建算法和ART算法感兴趣的人来说,这个文件提供了一个很好的入门教程,值得一看。
拉姆哥的小屋
- 粉丝: 6114
- 资源: 132
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功