拉东变换及其应用

拉东变换及其应用拉东变换是一种积分变换 常用于 CT 成像中 通过投影数据重构二维图像

大家好,欢迎来到IT知识分享网。

1 算法背景

拉东变换是由奥地利数学家约翰·拉东于1917年提出,目前被广泛的应用在断层扫描,其反变换可以从断层扫描的剖面图重建出投影前的函数。在数学上,拉东变换本质是一种积分变换,这个变换将二维平面函数 f 变换成一个定义在二维空间上的一个线性函数 R f R_f Rf R f R_f Rf的值为对函数 f f f沿着直线 A A A做积分的值,以下图为例:在这里插入图片描述

2 算法原理

2.1 拉东变换

令密度函数 μ = μ ( x 1 , x 2 ) μ=μ(x_1, x_2) μ=μ(x1,x2),其定义域为 R 2 R^2 R2,令 R R R为拉东变换的算子,则 Ɍ L μ ( x 1 , x 2 ) Ɍ_{Lμ(x1,x2)} Ɍ(x1,x2)表示沿着直线L对 μ μ μ的积分:
R L μ = ∫ L μ ( x 1 , x 2 ) d x 1 d x 2 R_{L\mu}=\int\limits_{L}^{} \mu(x_1,x_2)dx_1dx_2 R=Lμ(x1,x2)dx1dx2
一般会将直线通过法线式来表示: x 1 c o s θ + x 2 s i n θ − s = 0 x_1cos\theta+x_2sin\theta-s=0 x1cosθ+x2sinθs=0
在这里插入图片描述


3 应用

3.1 逆拉东变换

3.1.1 中心切片定理

中心切片定理为拉东逆变换提供了数学上证明:可以根据投影值完全可以重建原始图像。该定理可以表示为密度函数 μ ( x 1 , x 2 ) \mu(x_1, x_2) μ(x1,x2) 沿某个方向的投影函数 ρ ( s , θ ) \rho(s,\theta) ρ(s,θ) 的傅里叶变换等于函数 μ ( x 1 , x 2 ) \mu(x_1, x_2) μ(x1,x2)的二维傅里叶变换沿探测器平行方向过原点的片段,如下图:
在这里插入图片描述
证明如下,在角度 θ \theta θ已知的情况下对 p ( s , θ ) p(s,\theta) p(s,θ)进行傅里叶变换: F ( p ( s , θ ) ) = ∫ − ∞ ∞ p ( s , θ ) e − j w s d s F(p(s,\theta))=\int_{-\infty}^{\infty}p(s,\theta)e^{-jws}ds F(p(s,θ))=p(s,θ)ejwsds
在已知 p ( s , θ ) = ∬ μ ( x 1 , x 2 ) δ ( s − x 1 c o s θ − x 2 s i n θ ) d x 1 d x 2 p(s, \theta)=\iint \mu(x_1,x_2)\delta(s-x_1cos\theta-x_2sin\theta)dx_1dx_2 p(s,θ)=μ(x1,x2)δ(sx1cosθx2sinθ)dx1dx2的情况下,可得:
F ( p ( s , θ ) ) = ∫ − ∞ ∞ p ( s , θ ) e − j w s d s = ∫ − ∞ ∞ ( ∬ μ ( x 1 , x 2 ) δ ( s − x 1 c o s θ − x 2 s i n θ ) d x 1 d x 2 ) e − j w s d s = ∬ μ ( x 1 , x 2 ) [ δ ( s − x 1 c o s θ − x 2 s i n θ ) e − j w s d s ] d x 1 d x 2 = ∬ μ ( x 1 , x 2 ) e − j w ( x 1 c o s θ + x 2 s i n θ ) d x 1 d x 2 F(p(s,\theta))=\int_{-\infty}^{\infty}p(s,\theta)e^{-jws}ds=\int_{-\infty}^{\infty}(\iint \mu(x_1,x_2)\delta(s-x_1cos\theta-x_2sin\theta)dx_1dx_2)e^{-jws}ds=\\\iint \mu(x_1,x_2)[\delta(s-x_1cos\theta-x_2sin\theta)e^{-jws}ds]dx_1dx_2=\\\iint \mu(x_1,x_2)e^{-jw(x_1cos\theta+x_2sin\theta)}dx_1dx_2 F(p(s,θ))=p(s,θ)ejwsds=(μ(x1,x2)δ(sx1cosθx2sinθ)dx1dx2)ejwsds=μ(x1,x2)[δ(sx1cosθx2sinθ)ejwsds]dx1dx2=μ(x1,x2)ejw(x1cosθ+x2sinθ)dx1dx2
中心切片定理一般不用于投影重建。通过下图可知:在这里插入图片描述
当往 w x − w y w_x-w_y wxwy平面一条一条地添加“中心片段”时,中心片段在 w x − w y w_x-w_y wxwy平面的原点密度高于远离原点区域的密度。这就意味着高频区域的大片面积是没有中心片段覆盖的,但这些没被覆盖的地方只能通过插值数据。但凡是进行插值,一定会引入大量误差,因此用中心切片定理重建图像时,往往图像的质量不好。





3.1.2 直接反投影

3.1.3 滤波反投影(FBP)

在这里插入图片描述

  1. 计算每一个投影的一维傅里叶变换;
  2. 用滤波函数乘以每一个傅里叶变换;
  3. 得到每一个滤波后的变换的一维反傅里叶变换;
  4. 对步骤3得到的所以一维反变换积分(求和)
    可以通过在频域对投影函数乘上一个高通滤波器 ∣ w ∣ |w| w的方式来抵消直接反投影算法带来的误差。但这是一个理想滤波器,没办法实现,因此需要考虑其他能够实现并且能够使得到的图像更加接近原始图像的滤波器。
    R-L滤波器是使用窗函数对斜坡滤波器进行截断产生的。如下图所示:
    在这里插入图片描述
    离散化的函数表达式如下:
    在这里插入图片描述




4 测试代码

4.1 使用skimage自带的接口

from cgitb import grey import cv2 as cv import numpy as np import matplotlib.pyplot as plt from skimage import transform from skimage.transform import radon from skimage import io image = io.imread('test.jpg', as_gray=grey) image = transform.resize(image, (image.shape[0], image.shape[0])) 将图像转换为正方形,方便后续滤波计算 # 图像坐标转换为(theta,p) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4.5)) ax1.set_title("Original") ax1.imshow(image, cmap=plt.cm.Greys_r) theta = np.linspace(0., 180., max(image.shape), endpoint=False) sinogram = radon(image, theta=theta) print(np.shape(sinogram)) dx, dy = 0.5 * 180.0 / max(image.shape), 0.5 / sinogram.shape[0] ax2.set_title("Radon transform\n(Sinogram)") ax2.set_xlabel("Projection angle (deg)") ax2.set_ylabel("Projection position (pixels)") ax2.imshow(sinogram, cmap=plt.cm.Greys_r, extent=(-dx, 180.0 + dx, -dy, sinogram.shape[0] + dy), aspect='auto') fig.tight_layout() plt.show() cv.imwrite("ladon_sinogram.jpg", sinogram) #反变化结果 from skimage.transform import iradon size = np.shape(image) reconstruction_fbp = iradon(sinogram, theta=theta, filter_name='cosine') error = reconstruction_fbp - image print(f'FBP rms reconstruction error: { 
     np.sqrt(np.mean(error2)):.3g}') imkwargs = dict(vmin=-0.2, vmax=0.2) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4.5), sharex=True, sharey=True) ax1.set_title("Reconstruction\nFiltered back projection") ax1.imshow(reconstruction_fbp, cmap=plt.cm.Greys_r) ax2.set_title("Reconstruction error\nFiltered back projection") ax2.imshow(reconstruction_fbp - image, cmap=plt.cm.Greys_r, imkwargs) plt.show() 

4.2 使用理论编写

import numpy as np from scipy import ndimage from scipy.signal import convolve import matplotlib.pyplot as plt import imageio import cv2 #两种滤波器的实现 def RLFilter(N, d): filterRL = np.zeros((N,)) for i in range(N): filterRL[i] = - 1.0 / np.power((i - N / 2) * np.pi * d, 2.0) if np.mod(i - N / 2, 2) == 0: filterRL[i] = 0 filterRL[int(N/2)] = 1 / (4 * np.power(d, 2.0)) return filterRL def SLFilter(N, d): filterSL = np.zeros((N,)) for i in range(N): #filterSL[i] = - 2 / (np.power(np.pi, 2.0) * np.power(d, 2.0) * (np.power((4 * (i - N / 2)), 2.0) - 1)) filterSL[i] = - 2 / (np.pi2.0 * d2.0 * (4 * (i - N / 2)2.0 - 1)) return filterSL def IRandonTransform(image, steps): #定义用于存储重建后的图像的数组 channels = len(image[0]) origin = np.zeros((steps, channels, channels)) filter = RLFilter(channels, 1) # filter = SLFilter(channels, 1) for i in range(steps): projectionValue = image[:, i] projectionValueFiltered = convolve(filter, projectionValue, "same") projectionValueExpandDim = np.expand_dims(projectionValueFiltered, axis=0) projectionValueRepat = projectionValueExpandDim.repeat(channels, axis=0) origin[i] = ndimage.rotate(projectionValueRepat, i*180/steps, reshape=False).astype(np.float64) iradon = np.sum(origin, axis=0) return iradon #读取图片 #image = cv2.imread('straightLine.png', cv2.IMREAD_GRAYSCALE) image = cv2.imread("radon.jpg", cv2.IMREAD_GRAYSCALE) iradon = IRandonTransform(image, len(image[0])) #绘制原始图像和对应的sinogram图 plt.subplot(1, 2, 1) plt.imshow(image, cmap='gray') plt.subplot(1, 2, 2) plt.imshow(iradon, cmap='gray') plt.show() 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/117775.html

(0)
上一篇 2025-11-18 12:33
下一篇 2025-11-18 13:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信