CBP(卷积反投影)实现

CBP公式如下:
f(x1,x2)=0πf^(r,ϕ)H(r)r=(x1,x2)ϕdϕf(x_1,x_2)=\int_0^{\pi}\hat{f}(r,\phi)*H(r)|_{r=(x_1,x_2)\cdot{\phi}}d\phi
f(x1,x2)f(x_1,x_2)就简单地分成以下几步:

  1. 求滤波器h(w)对应的卷积核。需要注意的是h(w)在频域有限,在时域就是无穷的,类似一系列冲击函数的叠加。在这里插入图片描述
    函数表示为:在这里插入图片描述
    显示h图像为在这里插入图片描述
  2. 对于每一个ϕ\phi,将f^(r,ϕ)\hat{f}(r,\phi)H(r)H(r)做卷积,取中间(N)个卷积结果在这里插入图片描述
  3. 此时得到图像结果是离散的,也就是对于r=nd取不到的点,所以这时需要对r方向进行线性插值,把r变成连续的,可取值的;
    在这里插入图片描述
    这时我们随便给一个r值,就都有对应的灰度值了
  4. 接下来我们就需要把原图像(x1,x2)(x_1,x_2)的信息提取出来。已知r=(x1,x2)ϕr=(x_1,x_2)\cdot\phi那么x1=rcosϕx_1=rcos\phix2=rsinϕx_2=rsin\phi在这里插入图片描述
    经过上述操作,我们知道了,所谓f(x1,x2)f(x_1,x_2)的值,就是经过这一点的所有射线radon值的叠加。
    射线由标准位置ϕ\phi从0度到180度,r与直线夹角就是π/2ϕ\pi/2-\phi度,那r是很好求的r=x1cos(π/2ϕ)+x2sin(π/2ϕ)r=x_1cos(\pi/2-\phi)+x_2sin(\pi/2-\phi)

具体代码

import shelve
import numpy as np
import math
import matplotlib.pyplot as plt #plt用于显示图片
tuoyuanlist=shelve.open('test')
m=tuoyuanlist['2Dlist']#此时m由二维数组转化为矩阵,好操作,存储了r,phi对应位置的值。


#以下为一些常量定义,d长度为探测器元长度
d=0.02
phi = np.linspace(0.0314,math.pi,500)#将(0,pi)平均分为500份

#首先应该有一个长度为n的h对f做卷积操作
#定义R_L卷积核为:
def R_L(n):
    h=np.zeros(n)
    for i in range(n):
        if(i== (n/2-1)):#n=0时取值
            h[i]=1/(4*pow(d,2))
            print(h[i])
        elif((i-(n/2-1))%2==0):#n为偶数取值
            h[i]=0
        elif((i-(n/2-1))%2==1):#n为奇数取值
            h[i]=-1/(pow(math.pi*(i-(n/2-1))*d,2))
    return h

def shiyu(Array,filter,n):#进行时域滤波,对r做操作,n是phi分的角度
    g=np.zeros((n,2*n-1))#角度
    for i in range(n):
        g[i,:]=np.convolve(Array[i,:],filter,'full')#每一行(每一个phi)进行时域滤波(卷积)
    return g


#线性插值连续化
def Continue_Line(xn, yn):
    def line(x):
        index = -1
        #找出x所在的区间
        for i in range(1, len(xn)):
            if x <= xn[i]:
                index = i-1
                break
            else:
                i += 1
         
        if index == -1:
            return -100
        #插值
        result = (x-xn[index+1])*yn[index]/float((xn[index]-xn[index+1])) + (x-xn[index])*yn[index+1]/float((xn[index+1]-xn[index]))
        return result
    return line

def Continue_Figure(figure,n,phi,xr):#xr是r的取值,phi是取滤波后图像的第几行
    xn = [i for i in range(n)]
    yn = figure[phi,:]
    lin = Continue_Line(xn, yn)
    y=lin(xr+5)#挪一下相对应
    return y

def transport_xy(figure_filtited,a,b,xn,yn,n,phi_n):
    theta=math.pi-phi[phi_n]
    xr=np.linspace(-a,a,xn)
    yr=np.linspace(-b,b,yn)
    value=np.zeros((xn,yn))
    for i in range(xn):
        for j in range(yn):
            r=xr[i]*math.cos(theta)+yr[j]*math.sin(theta)
            value[i][j]=Continue_Figure(figure_filtited,n,phi_n,r)
    return value

def transport_phi(figure_filtited,a,b,xn,yn,n):
    Result_Figure=np.zeros((xn,yn))
    for i in range(n):
        Result_Figure=Result_Figure+transport_xy(figure_filtited,a,b,xn,yn,n,i)
    return Result_Figure

y=R_L(500)#卷积核长度
# # 进行离散化求值
c=shiyu(m,y,500)[:,250:750]
# #求x,y座标下的灰度值

Resultxy=transport_phi(c,6,4,60,40,500)
    # print(Result_Figure[i])
plt.imshow(Resultxy,cmap='gray')
plt.axis('off')
plt.show()
# print(Continue_Figure(c,500,0,-1))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章