猿问

通过 NumPy 中的傅立叶相移进行图像转换的伪像

以下代码在通过傅立叶相移移动图像时创建了人工制品:


相移本身的代码是:


def phase_shift(fimage, dx, dy):

    # Shift the phase of the fourier transform of an image

    dims = fimage.shape

    x, y = np.meshgrid(np.arange(-dims[1] / 2, dims[1] / 2), np.arange(-dims[0] / 2, dims[0] / 2))


    kx = -1j * 2 * np.pi * x / dims[1]

    ky = -1j * 2 * np.pi * y / dims[0]


    shifted_fimage = fimage * np.exp(-(kx * dx + ky * dy))


    return shifted_fimage

实际移动图像并获取移动图像的用法:


def translate_by_phase_shift(image, dx, dy):

    # Get the fourier transform

    fimage = np.fft.fftshift(np.fft.fftn(image))

    # Phase shift

    shifted_fimage = phase_shift(fimage, dx, dy)

    # Inverse transform -> translated image

    shifted_image = np.real(np.fft.ifftn(np.fft.ifftshift(shifted_fimage)))


    return shifted_image

工件显示在下面的图像中(图像具有偶数尺寸)。顶行是上下文(整个图像),底行是红色矩形中的特写。左:参考图像。中:与上述代码移位并受制于工件。右图:cv2.warpAffine()使用相同班次时的样子。

我在上面创建这个工件的代码中做错了什么?


[更新] 建议使用的评论之一scipy.ndimage.fourier.fourier_shift()。所以我就是这样做的:


fourier_shifted_image = fourier_shift(np.fft.fftn(image), shift)

shifted_image = np.fft.ifftn(fourier_shifted_image)

并绘制实部 ( shifted_image.real)


事实上,它也会产生完全相同的工件(见下图,右侧),我猜这排除了phase_shift()上面自定义代码中的错误?


茅侃侃
浏览 229回答 2
2回答

慕斯王

这里的问题与图像的显示方式以及图像的欠采样有关。代码是正确的,但不适合图像。1.欠采样图像有一些非常清晰的过渡。有些星星只显示在一个像素中。这是欠采样的标志。在正确采样的图像中,单个光点(无论多小)在图像中显示为艾里斑(在理想镜头的情况下),并且应占据多个像素以防止混叠。我假设成像无法更改,并且已针对应用程序进行了优化。但是,重要的是要注意图像是如何采样的,以便能够选择合适的图像处理工具。在这种情况下,欠采样转换意味着基于傅立叶的插值并不理想。2. 基于傅立叶的插值当通过傅立叶域移动或缩放图像时,使用 sinc 插值器。这是理想的内插器,对应于傅立叶域中的矩形窗口。sinc 插值器无限延伸(或至少延伸到图像的边缘),并以 1/x 衰减,这非常慢。因此在欠采样图像的情况下它不是理想的。由于欠采样图像具有尖锐的过渡,sinc 内插器会导致振铃(与许多其他内插器一样)。并且由于 sinc 函数的缓慢衰减,这种振铃传得很远。例如,该图(蓝色)中的人工急剧转变,当通过傅立叶域(红色)进行插值时,显示出很强的振铃,并且可以传播很远。这个数字与将振铃传送到不同距离的其他内插器形成对比。3.图像显示图像通过非常强烈地拉伸对比度来显示在问题中。这意味着允许观察暗淡的恒星,但也强烈增强了在这些恒星上引起急剧转变的振铃。在上图中,想象一下拉伸和剪切 y 轴,这样您就只能看到区域y=[0,0.01]。铃声看起来像一个黑白图案。4. 替代插值器上图显示了不同插值器对急剧过渡的影响。当应用于移动问题中的图像时,结果如下:对于底行的三种方法,无法观察到振铃,因为它发生在图像显示中完全饱和的区域。在显示器中使用不同范围的灰度值也可能会在此处显示一些振铃。所有这些内插器都被设计为近似理想的 sinc 内插器,但具有更短的空间足迹,因此它们的计算成本更低。因此,它们都在欠采样转换中显示出一些振铃。唯一不会在锐边引起振铃的内插器是线性内插和最近邻内插。这些是否适合您的应用程序取决于应用程序,我不能说。这是我用来制作上面图表的代码:a = double((0:99)<50);b = resample(a,20,0,'ft');c = resample(a,20,0,'3-cubic');d = resample(a,20,0,'lanczos8');a = resample(a,20,0,'nn');plot(a)hold onplot(b)plot(c)plot(d)legend({'input','sinc','cubic','Lanczos (8)'})set(gca,'xlim',[600,1400],'ylim',[-0.2,1.2])set(gca,'fontsize',16)set(gca,'linewidth',1)set(get(gca,'children'),'linewidth',2)set(gca,'Position',[0.07,0.11,0.9,0.815])该函数resample在DIPimage 中,您可以imresize改用,但'ft'方法除外,该方法只是用零填充频域,从而导致 sinc 插值。

LEATH

看看 ndimage.fourier_shift,据我所知,它不会产生任何人工制品。
随时随地看视频慕课网APP

相关分类

Python
我要回答