为什么我的输出是一张空白图片?

5

以下是我编写的代码,用于显示图像的幅度频谱:

orig_imdata = imread('Original_Image.png'); 
spec_orig = fft2(double(orig_imdata));
spec_orig2 = abs(spec_orig); 
spec_img = fftshift(spec_orig2);
imshow(spec_img); 

当我注释掉使用abs的部分并仅对图像使用fftshift时,我得到了一张图像,尽管有相位和幅度。如果我在使用fftshift之后立即应用abs函数,则imshow会返回一个空白结果。我需要一张图像来显示我图像的频谱分析的幅度。

有人知道这里出了什么问题吗?

1个回答

8
这张图片一点也不是“空白”的。 imshow 的设计原则是,任何小于0的double精度值都会显示为黑色,而大于1的值则会显示为白色。当计算图像的幅度分量时,您在代码中生成了double精度图像。
因此,我高度怀疑因为大多数组件(如果不是全部)都大于1,这给您提供了一个完全是白色的“空白”图像的可视化效果。现在我们已经找到了问题,但您还没有彻底解决。仅仅将组件缩放使其适合[0,1]范围内也无济于事。如果这样做,幅度谱的直流分量可能会非常大,以至于它压倒了图像中其余的幅度分量。因此,您只会看到中间一个白点,其余部分都是黑色的。

常见做法是对幅度谱应用log操作以进行显示,然后重新调整值使其适合于[0,1]范围内:

%// Your code
orig_imdata = imread('Original_Image.png'); 
spec_orig = fft2(double(orig_imdata));
spec_orig2 = abs(spec_orig); 
spec_img = fftshift(spec_orig2);

%// New code
spec_img_log = log(1 + spec_img);
imshow(spec_img_log,[]); 

log操作中,由于数值的巨大动态范围被压缩到一个较小的范围内,特别是当数值变得更大时,因此自然地将这个压缩范围缩放到[0,1]会给您带来更好的视觉效果。
每个分量都加1然后取log的原因是避免log(0)操作。如果任何幅度分量为零,这将计算为log(1),它将变为0。一旦你这样做了,你可以使用imshow(...,[])重新调整显示,使得log频谱的最小幅度分量为0,最大幅度分量为1。请注意,我没有修改原始频谱,因此您可以在该频谱上进行处理。另外,imshow所做的重新缩放完全是在调用内部完成的。它不对数据进行任何重新缩放 - 它仅用于显示,就是这样。

试一下,看看效果如何。


好的,这个解决方案可行,一旦我完成我需要做的事情,我会回来仔细阅读为什么它能够工作。非常详细的答案!赞! - SDG
@SharanDuggirala 我在你接受后添加了更多的编辑 :) ... 特别是这个缩放是如何工作的。不客气。祝好运!顺便说一句,看看代码后面具体的段落。它告诉你它为什么能工作。 - rayryeng
我认为,稍后我能够澄清关于这个答案的任何进一步问题吗?再次感谢这个回答! - SDG
@SharanDuggirala 当然可以。在这里给我留言就好了。不用谢。祝你好运! - rayryeng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接