CT正投影

所用知识

Beer-Lambert定律;
线性衰减系数:线性衰减系数 µ 表示光子穿过单位路径与物质发生作用的概率。
量纲是长度的倒数(单位 c m − 1 cm ^{-1} cm1 )。

编写程序,实现特殊几何形状。如圆、椭圆、三角形、正方形等的正投影

夹心圆的正投影

示例图片如下:
θ = 0 \theta=0 θ=0
在这里插入图片描述
θ > 0 \theta>0 θ>0
在这里插入图片描述

其中,大圆半径为4,小圆半径为1;大圆(不包括小圆部分)质量衰减系数为0.5;小圆部分质量衰减系数为1;大圆以外部分质量衰减系数为0;
大圆方程为: x 2 + y 2 = 16 x^2+y^2=16 x2+y2=16
小圆方程为: ( x ) 2 + ( y − 2 ) 2 = 1 (x)^2+(y-2)^2=1 (x)2+(y2)2=1
对每条光线通过物体发生的反应叠加求每个角度下灰度值图像。

数学模型

分段考虑,有两种情况:

  1. 光线经过的路径全部为大圆(0.5);
  2. 光线经过的路径一部分大圆,一部分小圆(0.5+0.5)。
    若为图所示情况,则数学模型中分为三段:
    f ( x ) = { 2 16 − x 2 ∗ 0.5 x ∈ ( − 4 , − 1 ) 2 16 − x 2 ∗ 0.5 + 2 1 − x 2 ∗ 0.5 x ∈ ( − 1 , 1 ) 2 16 − x 2 ∗ 0.5 x ∈ ( 1 , 4 ) f(x)=\left\{ \begin{aligned} 2\sqrt{16-x^2}*0.5&& x\in(-4,-1) \\ 2\sqrt{16-x^2}*0.5+2\sqrt{1-x^2}* 0.5 && x\in(-1,1) \\ 2\sqrt{16-x^2}*0.5&& x\in(1,4) \\ \end{aligned} \right. f(x)=216x2 0.5216x2 0.5+21x2 0.5216x2 0.5x(4,1)x(1,1)x(1,4)

探测器旋转

若探测器旋转,则将坐标轴变换。探测器逆时针旋转,就相当于坐标轴顺时针旋转相应的度数。
关于 θ \theta θ函数如下所示:
f ( x ) = { 2 16 − x 2 ∗ 0.5 x ∈ ( − 4 , 2 s i n θ − 1 ) 2 16 − x 2 ∗ 0.5 + 2 1 − ( 2 s i n θ − 1 ) 2 ∗ 0.5 x ∈ ( 2 s i n θ − 1 , 2 s i n θ + 1 ) 2 16 − x 2 ∗ 0.5 x ∈ ( 2 s i n θ + 1 , 4 ) f(x)=\left\{ \begin{aligned} 2\sqrt{16-x^2}*0.5&& x\in(-4,\sqrt{2sin\theta}-1) \\ 2\sqrt{16-x^2}*0.5+2\sqrt{1-(\sqrt{2sin\theta}-1)^2}* 0.5 && x\in(\sqrt{2sin\theta}-1,\sqrt{2sin\theta}+1) \\ 2\sqrt{16-x^2}*0.5&& x\in(\sqrt{2sin\theta}+1,4) \\ \end{aligned} \right. f(x)=216x2 0.5216x2 0.5+21(2sinθ 1)2 0.5216x2 0.5x(4,2sinθ 1)x(2sinθ 1,2sinθ +1)x(2sinθ +1,4)

代码如下:

import math
import struct
import numpy as np
np.set_printoptions(threshold=np.inf)
import matplotlib.pyplot as plt #plt用于显示图片
#import matplotlib.image as mpimg #mpimg用于读取图片
#p为旋转角度
x = np.linspace(-4,4,2000) 

p = np.linspace(0,2*(math.pi),int((math.pi)*1000))

#a = [[0 for i in range(2000)] for i in range(3141)]
a = np.arange(3141*2000, dtype=np.float64).reshape((3141,2000))
b = np.arange(3141*2000, dtype=np.int32).reshape((3141,2000))#np.int32 表示整数;reshape为二维数组

#print (math.sin(p[3100]))
#matplotlib中没有函数可以将RGB图转换为灰度图,所以我们定义一个
def banfill(x):
    grayvalue=10*(math.sqrt(16-np.power(x,2)))
    return grayvalue

def manfill(x,p):
	b=math.sin(p)
	grayvalue1=10*(np.sqrt(16-np.power(x,2))+np.sqrt(1-np.power(2*b-x,2)))
	#print(grayvalue)
	return grayvalue1


def grayresult(x,p):
    a=math.sin(p)
    if (x>-4 and x<(2*a-1)):
        grayv1=banfill(x)
        return grayv1
    elif(x>(2*a-1) and x<(2*a+1)):
        grayv2=manfill(x,p)
        return grayv2
    elif (x>(2*a+1) and x<4):
        grayv=banfill(x)
        return grayv
for i in range(3141):
    for j in range(2000):
        a[i][j]=grayresult(x[j], p[i])
        
        b[i][j]=np.nan_to_num(a[i][j])##将数组中的值化为整数,方便渲染图像

#print(b)	   #检验b是否正确
        
plt.imshow(b,cmap='gray')

plt.show()


程序结果

在这里插入图片描述

正方形ct正投影

思路

在这里插入图片描述
其中,将x轴分为三部分:
最左边和最右边部分求弦长原理相同,都是使用相似三角形方法;
中间部分无论x值为多少,弦长均相等。

离散图像求正投影

旋转图像(适当扩充),求一条射线经过像素灰度值的和。

import cv2
import matplotlib.pyplot as plt
import numpy as np
import math
from PIL import Image

from time import perf_counter

def sum1(p,image3):
    (h, w) = image3.shape[0:2]
    (cX, cY) = (w/2, h/2)
    M= cv2.getRotationMatrix2D((cX, cY), p, 1.0)
    image1 = cv2.warpAffine(image3, M, (w, h))
    #print(image1.shape)
    m=[0]*724
    for i in range(image1.shape[0]):
        for j in range(image1.shape[1]):
            m[i]=m[i]+image1[i][j]
        m[i]=m[i]/301
    return m

def findmax(x):
    max1=0
    for i in range(len(x)):
        if (x[i]>max1):
            max1=x[i]
    return max1
if __name__ == '__main__':
    t0 = perf_counter()
    img = cv2.imread('lena512gray.png', cv2.IMREAD_GRAYSCALE)
    a=round((724-img.shape[0])/2)
    b=round((722-img.shape[0])/2)
    image = cv2.copyMakeBorder(img,a,a,b,b, cv2.BORDER_CONSTANT,value=[0,0,0])
    theta = np.linspace(0,360,3600)
    grayresult = np.arange(len(theta)*724, dtype=np.float64).reshape((len(theta),724))
    for i in range(len(theta)):
            grayresult[i]=sum1(theta[i],image)
            print(grayresult[i])
    print(grayresult)
    plt.imshow(grayresult,cmap='gray')
    plt.show()
    cv2.imwrite('result.png',grayresult);

输入图像

在这里插入图片描述

输出结果

在这里插入图片描述

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值