因为我最近的工作需要用到Radon变换,所以简单地学习了一下相关内容。网上有很多关于Randon变换的介绍,大家可以自行查找,我就不再赘述了,但是很多人都是直接使用的MATLAB中的radon() 函数来完成这个变换的,而我所在的组没有购买MATLAB,因此直接使用MATLAB存在版权风险,所以我只能考虑使用Python进行实现,现在把源码和一些结果贴上来跟大家分享和讨论:
from scipy import ndimage
import numpy as np
import matplotlib.pyplot as plt
import imageio
from cv2 import cv2
def DiscreteRadonTransform(image, steps):
channels = len(image[0])
res = np.zeros((channels, channels), dtype='float64')
for s in range(steps):
rotation = ndimage.rotate(image, -s*180/steps, reshape=False).astype('float64')
#print(sum(rotation).shape)
res[:,s] = sum(rotation)
return res
#读取原始图片
#image = cv2.imread("whiteLineModify.png", cv2.IMREAD_GRAYSCALE)
#image=imageio.imread('shepplogan.jpg').astype(np.float64)
#image = cv2.imread("whitePoint.png", cv2.IMREAD_GRAYSCALE)
image = cv2.imread("shepplogan.jpg", cv2.IMREAD_GRAYSCALE)
radon = DiscreteRadonTransform(image, len(image[0]))
print(radon.shape)
#绘制原始图像和对应的sinogram图
plt.subplot(1, 2, 1)
plt.imshow(image, cmap='gray')
plt.subplot(1, 2, 2)
plt.imshow(radon, cmap='gray')
plt.show()
因为Radon变换常被用于医学影像(CT)和直线检测,所以在检验代码的时候,我使用了两个原始图片:一个是Shepp-Logan模型的图,另一个是仅有一条直线的图。下面是具体的结果:
上面就是我进行测试得到的结果,左侧原始的图片,右侧对应的是对左侧的图像进行Radon变换后得到的结果。据我肉眼观察,得到的结果跟其他人直接使用MATLAB中的radon() 函数得到的结果是一样的。如果有错误的地方,欢迎大家批评指正。
2020年8月12日补充 最近看到有人私信问我使用imageio发生数组尺寸不匹配的问题,产生这个问题的一个可能的原因和你使用的Shepp-Logan图片的色彩模式有关,如果你的图片是RGB模式或者RGBA模式(默认情况下matplotlib生成的图片是这个色彩模式),请使用image = cv2.imread(“whitePoint.png”, cv2.IMREAD_GRAYSCALE),这一语句会把你输入的图片变成灰度图,这样每个像素就只有一个值——灰度了,然后我们就可以使用沿着列求和的方式模拟投影过程了。我把文中的代码改了,把使用imageio那句给注释掉了。