专栏地址:『youcans 的 OpenCV 例程 300篇 - 总目录』

【第 7 章:图像复原与重建】
110. 投影和雷登变换
111. 雷登变换反投影重建图像
112. 滤波反投影重建图像

【youcans 的 OpenCV 例程 300 篇】112. 滤波反投影重建图像

7. 投影重建图像

图像重建的基本思想,就是通过探测物体的投影数据,重建物体的实际内部构造。

7.3 滤波反投影重建图像 (Filtered back projection)

直接由正弦图得到反投影图像,会存在严重的模糊,这是早期 CT 系统所存在的问题。

傅立叶中心切片定理表明,投影的一维傅立叶变换是得到投影区域的二维傅立叶变换的切片。滤波反投影重建算法在反投影前将每一个采集投影角度下的投影进行卷积处理,从而改善点扩散函数引起的形状伪影,有效地改善了重建的图像质量。

以 f(x,y)f(x,y)f(x,y) 表示需要重建的图像,F(u,v)F(u,v)F(u,v) 的二维傅里叶反变换是:
f(x,y)=∫−∞∞∫−∞∞F(u,v)ej2π(ux+vy)dudvf(x,y) = \int^{\infty}_{-\infty} \int^{\infty}_{-\infty} F(u,v) e^{j 2 \pi (ux+vy)} dudv f(x,y)=∫−∞∞​∫−∞∞​F(u,v)ej2π(ux+vy)dudv
利用傅里叶切片定理,可以得到:
f(x,y)=∫0π[∫−∞∞∣ω∣G(ω,θ)ej2πωρdω]dθf(x,y) = \int^{\pi}_{0} \big[ \int^{\infty}_{-\infty} |\omega|G(\omega,\theta) e^{j 2 \pi \omega \rho} d\omega \big] d\theta f(x,y)=∫0π​[∫−∞∞​∣ω∣G(ω,θ)ej2πωρdω]dθ
括号 [] 内部是一个一维傅里叶反变换,可以认为这是一个一维滤波器的传递函数。由于 ∣ω∣|\omega|∣ω∣ 是一个不可积的斜坡函数(Slope function),可以通过对斜坡加窗进行限制,典型地如汉明窗(Hamming window)、韩窗(Hann window)。

该式也可以使用空间卷积来实现:
f(x,y)=∫0π[∫−∞∞∣ω∣G(ω,θ)ej2πωρdω]dθ=∫0π[∫−∞∞g(ρ,θ)s(xcosθ+ysinθ−ρ)dρ]dθf(x,y) = \int^{\pi}_{0} \big[ \int^{\infty}_{-\infty} |\omega|G(\omega,\theta) e^{j 2 \pi \omega \rho} d\omega \big] d\theta \\ = \int^{\pi}_{0} \big[ \int^{\infty}_{-\infty} g(\rho,\theta) s(xcos \theta + ysin \theta - \rho) d\rho \big] d\theta \\ f(x,y)=∫0π​[∫−∞∞​∣ω∣G(ω,θ)ej2πωρdω]dθ=∫0π​[∫−∞∞​g(ρ,θ)s(xcosθ+ysinθ−ρ)dρ]dθ
这表明,将对应的投影 g(ρ,θ)g(\rho, \theta)g(ρ,θ) 与斜坡滤波器传递函数 s(ρ)s(\rho)s(ρ) 的傅里叶反变换进行卷积,可以得到角度 θ\thetaθ 的各个反投影,整个反投影图像可以通过对所有反投影图像积分得到。

例程 9.25:滤波反投影重建图像

SL 滤波器是使用 Sinc 函数对斜坡滤波器进行截断产生,其离散形式为:
hSL(nδ)=−2π2δ2(4∗n2−1),n=0,±1,±2,...h_{SL}(n \delta) = - \frac{2}{\pi ^2 \delta ^2 (4*n^2 -1)}, \ n=0,\pm 1,\pm 2,... hSL​(nδ)=−π2δ2(4∗n2−1)2​, n=0,±1,±2,...
利用投影值和 SL 滤波器进行卷积,然后再进行反投影,就可以实现图像重建。

   # 9.25: 滤波反投影重建图像from scipy import ndimagedef discreteRadonTransform(image, steps):  # 离散雷登变换channels = image.shape[0]resRadon = np.zeros((channels, channels), dtype=np.float32)for s in range(steps):rotation = ndimage.rotate(image, -s * 180/steps, reshape=False).astype(np.float32)resRadon[:, s] = sum(rotation)return resRadondef inverseRadonTransform(image, steps):  # 雷登变换反投影重建图像channels = image.shape[0]backproject = np.zeros((steps, channels, channels))for s in range(steps):expandDims = np.expand_dims(image[:, s], axis=0)repeat = expandDims.repeat(channels, axis=0)backproject[s] = ndimage.rotate(repeat, s * 180/steps, reshape=False).astype(np.float32)invRadon = np.sum(backproject, axis=0)return invRadondef SLFilter(N, d):  # SL 滤波器, Sinc 函数对斜坡滤波器进行截断filterSL = np.zeros((N,))for i in range(N):filterSL[i] = - 2 / (np.pi**2 * d**2 * (4 * (i-N/2)**2 - 1))return filterSLdef filterInvRadonTransform(image, steps):  # 滤波反投影重建图像channels = len(image[0])backproject = np.zeros((steps, channels, channels))  # 反投影filter = SLFilter(channels, 1)  # SL 滤波器for s in range(steps):value = image[:, s]  # 投影值valueFiltered = np.convolve(filter, value, "same")  # 投影值和 SL 滤波器进行卷积filterExpandDims = np.expand_dims(valueFiltered, axis=0)filterRepeat = filterExpandDims.repeat(channels, axis=0)backproject[s] = ndimage.rotate(filterRepeat, s * 180/steps, reshape=False).astype(np.float32)filterInvRadon = np.sum(backproject, axis=0)return filterInvRadon# 读取原始图像img1 = cv2.imread("../images/Fig0534a.tif", 0)  # flags=0 读取为灰度图像img2 = cv2.imread("../images/Fig0534c.tif", 0)# 雷登变换imgRadon1 = discreteRadonTransform(img1, img1.shape[0])  # Radon 变换imgRadon2 = discreteRadonTransform(img2, img2.shape[0])# 雷登变换反投影重建图像imgInvRadon1 = inverseRadonTransform(imgRadon1, imgRadon1.shape[0])imgInvRadon2 = inverseRadonTransform(imgRadon2, imgRadon2.shape[0])# 滤波反投影重建图像imgFilterInvRadon1 = filterInvRadonTransform(imgRadon1, imgRadon1.shape[0])imgFilterInvRadon2 = filterInvRadonTransform(imgRadon2, imgRadon2.shape[0])plt.figure(figsize=(9, 7))plt.subplot(231), plt.axis('off'), plt.title("origin image"), plt.imshow(img1, 'gray')  # 绘制原始图像plt.subplot(232), plt.axis('off'), plt.title("inverse Radon trans"), plt.imshow(imgInvRadon1, 'gray')plt.subplot(233), plt.axis('off'), plt.title("filter inv-Radon trans"), plt.imshow(imgFilterInvRadon1, 'gray')plt.subplot(234), plt.axis('off'), plt.title("origin image"), plt.imshow(img2, 'gray')plt.subplot(235), plt.axis('off'), plt.title("inverse Radon trans"), plt.imshow(imgInvRadon2, 'gray')plt.subplot(236), plt.axis('off'), plt.title("filter inv-Radon trans"), plt.imshow(imgFilterInvRadon2, 'gray')plt.tight_layout()plt.show()

(本节完)


版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/123088438)
Copyright 2022 youcans, XUPT
Crated:2022-2-28

【OpenCV 例程 300 篇】112. 滤波反投影重建图像相关推荐

  1. 【youcans 的 OpenCV 例程 200 篇】112. 滤波反投影重建图像

    欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中 欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中 [youcans 的 OpenCV 例程 2 ...

  2. 【OpenCV 例程 300篇】253. 多帧图像(动图)的读取与保存

    『youcans 的 OpenCV 例程300篇 - 总目录』 [youcans 的 OpenCV 例程 300篇]253. 多帧图像(动图)的读取与保存 1. 多帧图像(动图) 多帧图像是将多幅图像 ...

  3. 【youcans的OpenCV例程300篇】总目录

    版权声明: 转载本系列作品时必须标注以下版权内容: [youcans@qq.com, youcans的OpenCV 例程300篇, https://blog.csdn.net/youcans/cate ...

  4. 【youcans 的 OpenCV 例程200篇】135. 形态学重建之粒度测定

    欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中 欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中 [youcans 的 OpenCV 例程20 ...

  5. 【youcans 的 OpenCV 例程200篇】132. 形态学重建之孔洞填充算法

    欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中 欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中 [youcans 的 OpenCV 例程20 ...

  6. 【OpenCV 例程300篇】01. 图像的读取(cv2.imread)

    专栏地址:『youcans 的 OpenCV 例程300篇 - 总目录』 01. 图像的读取(cv2.imread) 02. 图像的保存(cv2.imwrite) 03. 图像的显示(cv2.imsh ...

  7. 【OpenCV 例程300篇】04. 用 matplotlib 显示图像(plt.imshow)

    专栏地址:『youcans 的 OpenCV 例程300篇 - 总目录』 01. 图像的读取(cv2.imread) 02. 图像的保存(cv2.imwrite) 03. 图像的显示(cv2.imsh ...

  8. 【OpenCV 例程300篇】02. 图像的保存(cv2.imwrite)

    专栏地址:『youcans 的 OpenCV 例程300篇 - 总目录』 01. 图像的读取(cv2.imread) 02. 图像的保存(cv2.imwrite) 03. 图像的显示(cv2.imsh ...

  9. 【OpenCV 例程 300 篇】107. 退化图像的维纳滤波

    专栏地址:『youcans 的 OpenCV 例程 300篇 - 总目录』 [第 7 章:图像复原与重建] 106. 退化图像的逆滤波 107. 退化图像的维纳滤波 108. 约束最小二乘方滤波 10 ...

最新文章

  1. 10.30 linux和windows互传文件,用户配置文件和密码配置文件,用户组管理,用户管理...
  2. python 获取文件列表
  3. 2017-2018-1 20155332实验三 实时系统报告
  4. cisco firewall (ASA Series)
  5. linux如何判断网线插入_斜口钳和网线钳制作网线!
  6. alink的相關資料收集
  7. YBTOJ洛谷P4068:数字配对(网络流)
  8. 闲置服务器装win10系统,求高手帮看一下我这台闲置的老主机还能装win10或者win8.1吗?...
  9. Spring Boot学习总结(22)——如何定制自己的 springboot starter 组件呢?
  10. 过滤器做权限校验以及遇到的坑
  11. linux中 」 、」」 的用法
  12. 元数据管理在数据仓库的实践应用
  13. 手游运营数据监控指标浅谈
  14. Unity 制作伪全息
  15. python函数的四种参数传递方式
  16. JS基礎:Hoisting 變量提升、TDZ 暫時性死區(Temporal Dead Zone)
  17. python基于scrapy爬取京东笔记本电脑数据并进行简单处理和分析
  18. 宽带和流量是分开的吗_中国移动为什么免费送宽带和流量?网友:原来都是“套路”...
  19. STM32MP157驱动开发——Linux RS232/485/GPS 驱动
  20. 名词解释第二十八讲:跨链

热门文章

  1. 2021Q3展锐智能手机芯片全球市占率达10%
  2. 批次级别和批次库存的后台字段
  3. 最强整理:从外包公司到今日头条offer,聪明人已经收藏了!
  4. 分节符、实现文档横竖打印
  5. 3DMax插件开发—可编辑多边形-多顶点统一坐标工具
  6. Bootstrap 一篇就够 快速入门使用(中文文档)
  7. javaswing jtextpane 英文中文自动换行
  8. 旅游网站之数据可视化
  9. 谷歌SEO中PBN外链是否值得做
  10. vue.js:父组件和子组件