拉东变换及其应用

这篇具有很好参考价值的文章主要介绍了拉东变换及其应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 算法背景

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

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
拉东变换,算法,python

故拉东变换可以采用下面的表示方式:
R L μ = R μ ( s , θ ) = ∬ μ ( x 1 , x 2 ) δ ( s − x 1 c o s θ − x 2 s i n θ ) d x 1 d x 2 s ∈ ( − ∞ , ∞ ) , θ ∈ ( 0 , π ) R_{L\mu}=R\mu(s, \theta)=\iint \mu(x_1,x_2)\delta(s-x_1cos\theta-x_2sin\theta)dx_1dx_2 \\s\in (-\infty, \infty),\theta\in(0, \pi) R=Rμ(s,θ)=μ(x1,x2)δ(sx1cosθx2sinθ)dx1dx2s(,),θ(0,π)

3 应用

CT成像:在医学图像成像时,是通过x射线穿过人体来实现的,射线穿过人体后会衰减,然后被仪器测量到,也就是说我们已经知道了拉东变换的结果,需要通过这个结果还原出射线穿过的人体剖面,即拉东逆变换。
拉东变换,算法,python

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)的二维傅里叶变换沿探测器平行方向过原点的片段,如下图:
拉东变换,算法,python
证明如下,在角度 θ \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
中心切片定理一般不用于投影重建。通过下图可知:拉东变换,算法,python
当往 w x − w y w_x-w_y wxwy平面一条一条地添加“中心片段”时,中心片段在 w x − w y w_x-w_y wxwy平面的原点密度高于远离原点区域的密度。这就意味着高频区域的大片面积是没有中心片段覆盖的,但这些没被覆盖的地方只能通过插值数据。但凡是进行插值,一定会引入大量误差,因此用中心切片定理重建图像时,往往图像的质量不好。

3.1.2 直接反投影

直接反投影即将投影值均匀回抹,然后将不同角度的回抹值叠加得到重建图像。
拉东变换,算法,python
拉东变换,算法,python
反投影图是离散叠加的,显然在中心处信号集中,边缘处信号稀疏,因此在最后需要在空缺的地方进行插值,才能得到最终的原图像。

3.1.3 滤波反投影(FBP)

当前主流的反投影重建算法主要有滤波反投(FBP)和迭代重建算法。滤波反投影的主要缺点是噪声大,信噪比低,但由于处理数据较少所以重建速度快。迭代重建主要是计算量特别大,重建速度慢,但是图像信噪比较高,图像质量相对较好。
滤波反投影算法的步骤:

拉东变换,算法,python

  1. 计算每一个投影的一维傅里叶变换;

  2. 用滤波函数乘以每一个傅里叶变换;

  3. 得到每一个滤波后的变换的一维反傅里叶变换;

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

下面为采用R-L滤波器的结果:
拉东变换,算法,python

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(error**2)):.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.pi**2.0 * d**2.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()

测试图像:
拉东变换,算法,python文章来源地址https://www.toymoban.com/news/detail-720647.html

到了这里,关于拉东变换及其应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第七章,相似矩阵及其应用,3-二次型、合同矩阵与合同变换

    玩转线性代数(38)二次型概念、合同矩阵与合同变换的笔记,相关证明以及例子见原文 含有n个变量 x 1 , x 2 , . . . x n x_1,x_2,...x_n x 1 ​ , x 2 ​ , ... x n ​ 的二次齐次函数: f ( x 1 , x 2 , . . . x n ) = a 11 x 1 2 + a 22 x 2 2 + . . . + a n n x n 2 + 2 a 12 x 1 x 2 + 2 a 13 x 1 x 3 + . . . + 2 a n − 1 , n x

    2024年02月11日
    浏览(55)
  • 计算机视觉--距离变换算法的实战应用

    前言: Hello大家好,我是Dream。 计算机视觉CV是人工智能一个非常重要的领域 。 在本次的距离变换任务中,我们将使用 D4距离度量方法 来对图像进行处理。通过这次实验,我们可以更好地理解距离度量在计算机视觉中的应用。希望大家对计算机视觉和图像处理有了更深入的

    2024年02月15日
    浏览(54)
  • 算法提高-图论-floyd算法及其扩展应用

    离散化 (只要用到200个点,但是题目给的点编号是1-1000)+ 倍增(快速幂)+ flyod变式(将递推公式改变了) 能用快速幂的原因是递推公式里面的两端路径两两之间相互独立,用结合律就可以用快速幂。矩阵乘法能用快速幂的原因也是矩阵乘法中两两矩阵之间具有结合律 帮助

    2024年02月09日
    浏览(50)
  • 【快速排序算法思想及其应用】

    本文主要介绍Java中快速排序(Quick Sort)算法的基本原理、实现方式以及使用场景。快速排序是一种高效的排序算法,通过选取一个基准元素并将待排序序列划分为小于基准元素和大于基准元素的两部分来实现排序。本文将深入剖析快速排序的思想及其在实际应用中的价值。

    2024年02月07日
    浏览(47)
  • 【计数排序算法思想及其应用】

    本文主要介绍Java中计数排序(Counting Sort)算法的基本原理、实现方式以及使用场景。计数排序是一种线性时间复杂度的非比较排序算法,通过计数数组来统计输入数据中每个元素出现的次数,然后按照数组下标顺序输出排序后的结果。本文将深入剖析计数排序的思想及其在

    2024年02月07日
    浏览(54)
  • FDTD算法及其应用

    一、电磁场问题数值计算方法         有许多的数值计算方法用于解决电磁场问题。其中,一些最常用的方法包括:         1.有限元法(Finite Element Method,FEM):这种方法将连续的求解域离散化为有限个小的单元,对每个单元进行数值求解,然后将所有单元的解组

    2024年01月25日
    浏览(34)
  • SPFA 算法:实现原理及其应用

    SPFA算法,全称为Shortest Path Faster Algorithm,是求解单源最短路径问题的一种常用算法,它可以处理有向图或者无向图,边权可以是正数、负数,但是不能有负环。 1、SPFA算法的基本流程 1. 初始化 首先我们需要起点s到其他顶点的距离初始化为一个很大的值(比如9999999,像是

    2024年02月08日
    浏览(86)
  • C++实现数字翻转算法及其应用

    C++实现数字翻转算法及其应用 数字翻转是指将一个整数的各个数字顺序颠倒,例如将 12345 翻转为 54321。C++实现数字翻转算法是比较简单的,下面我们详细介绍一下。 算法描述 对于任意一个正整数A,我们可以通过反复进行以下几步操作,将其翻转: 将A的末位取出,加到结果

    2024年02月07日
    浏览(39)
  • 【算法日志】图论 并查集及其简单应用

    并查集是一种算法设计思想,通过判断两个元素是否在同一个集合里,常用来解决一些和图相关的连通性问题。 并查集主要有以下两个功能: 将两个元素添加到一个集合中。 判断两个元素是否是在一个集合之中(这一功能够有效判断是否成环)。 主要思想: 通过创建一个数组

    2024年01月23日
    浏览(47)
  • 聊聊日志聚类算法及其应用场景

    随着AI模型的普及应用与高速发展,主要的云厂商与AI大厂提供了对应的服务支持,使得业务的应用可以轻松对接AI算法,使其在实际项目中落地。 我个人也是极度推崇在项目中应用AI算法更轻松更数智化的兑现功能。 虽然AI门槛很高,但随着时间的推移与AI模型的发展,我相

    2024年02月16日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包