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))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章