ImageMagick 示例 -
傅里叶变换
- 索引
-
ImageMagick 示例 前言与索引
-
简介
-
傅里叶变换
-
ImageMagick 中的 FFT/IFT
-
傅里叶变换的性质
-
实用应用
-
高级应用
-
FFT 乘法与除法 (低级示例 - 子页面)
简介
图像处理中最难理解的概念之一就是傅里叶变换。造成这种情况的原因有两个。首先,它在数学上很复杂,其次,得到的图像不像是原始图像,很难解释。然而,利用傅里叶变换可以提供新的方法来进行熟悉的处理,例如增强亮度和对比度、模糊、锐化和去除噪声。但它还可以提供在普通图像域中无法实现的新功能。这些功能包括对典型相机失真(例如运动模糊和镜头散焦)进行反卷积(也称为去模糊),以及使用归一化互相关进行图像匹配。本页面的目标是尝试解释傅里叶变换的背景和简化数学,并给出使用傅里叶变换可以进行的处理的示例。如果你觉得这太难了,你可以跳过它,只关注属性和示例,从 ImageMagick 中的 FFT/IFT 开始。对于有兴趣的人来说,另一个不错的简单讨论,包括与光学的类比,可以在 直观的傅里叶理论解释 中找到。范德堡大学工程学院的讲义对于那些对数学更感兴趣的人来说也非常有参考价值: 一维和二维傅里叶变换 和 频域滤波。其他数学参考包括维基百科关于 傅里叶变换、 离散傅里叶变换 和 快速傅里叶变换 以及 复数 的页面。感谢 Sean Burke 对原始演示的编码,以及 ImageMagick 的创建者将其集成到 ImageMagick 中。两者都是英勇的努力。 许多示例使用 HDRI 版本的 ImageMagick,这对于保持变换图像的精度是必要的。建议你编译一个个人 HDRI 版本,如果你想充分利用这些技术。傅里叶变换
图像通常由一个“像素”数组组成,每个像素由一组值定义:红色、绿色、蓝色以及有时还会包含透明度。但在这里,为了我们的目的,我们将忽略透明度。因此,每个红色、绿色和蓝色“通道”都包含一组“强度”或“灰度”值。这被称为栅格图像的“空间域”。这只是一个花哨的说法,即图像由每个“位置”或“空间位置”的“强度值”定义。但图像也可以用另一种方式表示,被称为图像的“频率域”。在这个域中,每个图像通道都以正弦波的形式表示。在这样的“频率域”中,每个通道都具有“幅度”值,这些值存储在基于 X,Y “空间”坐标而不是 X,Y “频率”坐标的位置。由于这是一个数字表示,因此频率是“最小”或单位频率的倍数,像素坐标表示这些单位频率的索引或整数倍数。这是由“任何行为良好的函数都可以用正弦波的叠加(组合或求和)来表示”这一原理得出的。换句话说,“频率域”表示只是存储和再现“空间域”图像的另一种方式。但是,图像如何表示为“波”呢?图像即波
好吧,如果我们从任何图像中取一行或一列像素,然后将其绘制出来(使用“gnuplot”并使用脚本“im_profile
”生成),你就会发现它看起来很像一个波形。如果波动在间距和幅度上更加规律,你将得到更类似于波形图案的东西,例如...
magick -size 20x150 gradient: -rotate 90 \ -function sinusoid 3.5,0,.4 wave.gif im_profile -s wave.gif wave_profile.gif |
![[IM Output]](wave.gif)

![[IM Output]](wave_profile.gif)
magick -size 1x150 gradient: -rotate 90 \ -function sinusoid 3.5,0,.25,.25 wave_1.png magick -size 1x150 gradient: -rotate 90 \ -function sinusoid 1.5,-90,.13,.15 wave_2.png magick -size 1x150 gradient: -rotate 90 \ -function sinusoid 0.6,-90,.07,.1 wave_3.png magick wave_1.png wave_2.png wave_3.png \ -evaluate-sequence add added_waves.png |
![[IM Output]](wave_1_pf.gif)

![[IM Output]](wave_2_pf.gif)

![[IM Output]](wave_3_pf.gif)

![[IM Output]](added_waves_pf.gif)
图像中的二维波
上面展示了如何使用多个正弦波来近似图像单行的轮廓的一个示例。然而,图像都是二维的,因此用来在“频率域”中表示图像的波形也需要是二维的。下面是一个这样的二维波形的示例。该波形包含多个组成部分。图像示例在 ImageMagick 中使用 FFT/IFT
实现说明
ImageMagick 使用 FFTW,离散傅里叶变换库,该库要求图像转换为浮点数(复数)并从浮点数转换回来,并且最初是在 IM 版本 6.5.4-3 中实现的。为了使其按人们通常对图像的期望工作,任何非正方形图像或具有奇数维度的图像都将被填充(使用 虚拟像素 成为图像最大宽度或高度的正方形)。为了允许在图像中心正确地对齐“FFT 原点”,图像的维度也必须是偶数(2 的倍数)。其结果是,在应用逆傅里叶变换后,需要将图像裁剪回原始尺寸以去除填充。由于傅里叶变换由“复数”组成,因此变换的结果无法直接可视化。因此,复变换将被分成两个分量图像,以两种形式之一表示。![]() 复数 实部/虚部 |
实部和虚部
“复数”的正常数学和数值表示是一个包含“实部”(a)和“虚部”(b)的浮点数对。不幸的是,这两个数字可能包含负值,因此无法形成可视化的图像。因此,这种表示形式不能在普通版本的 ImageMagick 中使用,因为该版本会裁剪此类图像(参见下面的示例,显示结果效果。但是,在使用 HDRI 版本的 ImageMagick 时,你仍然可以生成、使用甚至保存傅里叶变换图像的这种表示形式。它们可能本身不是有用的或甚至无法作为图像查看,但你仍然可以对它们应用许多数学运算。为了生成这种表示形式,我们使用运算符的“加号”形式,“+fft
”和“+ift
”,并将分别在下面的 FFT 作为实部和虚部 中进行详细介绍。![]() 复极坐标 幅度/相位 |
幅度和相位
“复数”的直接数值表示对于图像处理来说不是很有用。但是,通过将值绘制到二维平面上,你可以将值转化为 极坐标表示形式,它包含“幅度”(r)和“相位”(θ)分量。这种形式在图像处理中非常有用,特别是幅度分量,它本质上指定了构成图像的所有频率。“幅度”分量只包含正值,并且直接映射到图像值。它没有固定的值范围,尽管除了直流或零频率颜色之外,值通常都很小。因此,幅度图像通常看起来非常暗(实际上是黑色)。通常需要通过缩放幅度并对其强度值应用对数变换来突出显示任何视觉细节。得到的“对数变换”幅度图像被称为图像的“频谱”。但是,请记住,应该使用“幅度”图像,而不是“频谱”图像来进行逆变换。出现在图像中心“原点”的直流(代表“直流电”)或“零频率”颜色将是整个图像的平均颜色值。此外,由于输入图像不包含“虚部”,因此直流相位值也将始终为零相位,产生纯灰色颜色。“相位”分量在 -π 到 +π 之间变化。首先将其偏差到 0 到 2π 范围,然后将其缩放到实际图像值,范围为 0 到 QuantumRange(由 编译时内存质量 决定)。因此,零相位将具有纯灰色值(适用于每个通道),而否定相位将具有纯黑色('0
')值。请注意,纯白色('QuantumRange
')几乎与它相同,但并不完全相同。幅度和相位 FFT 表示形式的图像使用正常的 FFT 运算符,“+fft
”和“+ift
”生成。我们将首先在 生成 FFT 图像及其逆 中介绍这一点。 生成 FFT 图像及其逆
(幅度和相位)
现在,让我们简单地尝试对 Lena 图像进行傅里叶变换往返。也就是说,我们简单地执行正向变换,然后立即应用逆变换以获取原始图像。然后,我们将比较结果以查看生成的质量水平。
|
![[IM Output]](../img_photos/lena.png)

![[IM Output]](lena_roundtrip.png)
![]() |
compare
" 程序返回了衡量两张图片差异程度的指标。在本例中,您可以看到整体差异非常小,大约为 0.22%
。至少在一个像素上的峰值差异(“PAE
”,峰值绝对误差)大约为 1%
。您可以通过使用 ImageMagick 的 HDRI 版本来改进这一点。(参见下面的 带 HDRI 的 FFT)。让我们仔细看看上面往返过程中生成的 FFT 图像。正如 John M. Brayer 关于傅里叶变换所说... 我们通常不显示相位图像,因为大多数看到它们的人很快就会屈服于致幻剂或最终进入西藏寺院。请注意,“-fft
” 运算符生成了两张图像,第一张图像是“幅度”分量(是的,它大部分是黑色的,中间有一个彩色点),而第二张,看起来几乎随机的图像,包含“相位”分量。PNG 图像只能存储每个文件一张图像,因此“+adjoin
” 或输出文件名中的“%d
”实际上并不需要,因为 IM 会处理它。但是,我在上面包含了这些选项以确保完整性,以便清楚地表明我正在生成两个单独的图像文件,而不是一个。有关更多详细信息,请参阅 编写多图像序列。由于生成了两个图像,幅度图像(第一个或第零个图像)被保存到“lena_fft_0.png
”中,而相位图像(第二个图像)被保存到“lena_fft_1.png
”中。![]() ![]() |
为了防止因保存 FFT 图像而导致的任何扭曲,最好不要将它们保存到磁盘,而是在内存中保存它们,并在您处理图像时使用它们。 如果您必须保存,最好使用 Magick 文件格式“ MIFF ”,以便以最高质量(位深度)保留图像。此格式还可以将多个图像保存到一个文件中。对于脚本工作,您也可以使用详细的“TXT ”枚举像素格式。请勿使用“ JPEG ”,“GIF ”图像格式保存它们。如果您必须将这些图像保存到文件中以供实际查看,例如用于 Web 浏览器,请使用图像格式“ PNG ”,并将其“+depth ”重置为内部默认值(正如我们在这些示例中所做的那样)。但是,它只能存储每个文件一张图像。“ TIFF ”文件格式也可以使用,尽管它不适合 Web 浏览器,但它允许每个文件有多个图像。 |
MIFF
”文件格式...
magick lena.png -fft +depth lena_fft.miff |
-write
”将它们保存到完全独立的文件名中(参见 写入图像)...
magick lena.png -fft +depth \ \( -clone 0 -write lena_magnitude.png +delete \) \ \( -clone 1 -write lena_phase.png +delete \) \ null: |
NULL:
”图像格式来丢弃两个图像,这两个图像仍然保存在内存中,以便进一步处理。最后,我们再次读取这两个图像,以便将其魔术地还原为正常的“空间”图像...FFT 过程生成的两个图像对修改非常敏感,即使很小的变化也会导致结果严重失真。因此,重要的是永远不要以任何可能扭曲这些值的图像格式保存它们。重要的是要记住,当从频域恢复图像时,需要这两个图像。因此,如果您打算将它们用于图像重建,那么保存一个图像,而丢弃另一个图像,这样做是没有用的。仅幅度或仅相位图像
最后,让我们尝试仅从其幅度分量或仅从其相位分量重建图像。
magick lena_fft_0.png -size 128x128 xc:'gray(50%)' \ -ift lena_magitude_only.png magick -size 128x128 xc:gray1 lena_fft_1.png -ift lena_phase_only.png |
![]() 仅幅度 |
![]() 仅相位 |
频率谱图像
您可能已经注意到,幅度图像(第一个或第零个图像)看起来几乎完全是黑色的。它实际上并非如此,但对于我们的眼睛来说,所有值都非常非常小。这样的图像在查看和研究时并不真正有趣,因此让我们使用对数变换来增强结果,以生成“频率谱”图像。这是通过对 归一化 的“幅度”图像应用强 评估对数变换 来完成的。现在我们可以看到幅度图像的频谱版本的细节。您甚至可能会在频谱图像中看到一些特定的颜色,但通常情况下,频谱图像中的这些颜色并不重要。更重要的是每个频率的整体强度以及它们产生的模式。因此,您可能还希望在增强后将频谱图像灰度化。您需要使用多少对数增强取决于图像,因此您应该调整它,直到获得您需要清楚地看到图像频率谱模式的细节量。但是请记住,您不能使用频谱图像进行逆“-ift ”变换,因为它会产生过于明亮的图像。
|
![]() |
HDRI FFT 图像
当我们将傅里叶变换的结果映射到图像表示时,我们将浮点 "复数" 的值缩放并转换为整型图像值。这自然会产生 舍入误差和其他“量子”效应,尤其是在较小的低频幅度中。如果精度对您的图像处理很重要,那么您将需要使用 位质量(例如 ImageMagick 的 Q32 或 Q64 位版本),或者更好的是使用 HDRI 版本的 ImageMagick,以便将值存储为浮点数。当使用带有 幅度和相位 表示的傅里叶变换的 HDRI 版本的 IM 时,幅度分量仍然将全部为正值,因此可以像上面所示的那样使用,只是精确度更高。但是,相位分量仍将如前所述进行偏差和缩放。换句话说,HDRI 中的幅度和相位表示完全相同,只是精度更高。例如,这里我使用 HDRI 版本的 ImageMagick 来生成图像的另一个“往返”转换。
|
![]() |
![]() ![]() |
支持浮点的文件格式包括“MIFF ”,“TIFF ”,“PFM ”以及 HDRI 特定的“EXR ”文件格式。但是,您可能需要设置“-define quantum:format=floating-point ”才能使其正常工作。 |
FFT 作为实部和虚部
到目前为止,我们只查看了傅里叶变换图像的“幅度”和“相位”表示。但是,如果您编译了 HDRI 版本的 IM,您也可以使用浮点“实数”和“虚数”分量来处理图像。这是通过使用选项“+fft
”和“+ift
”的“plus”版本来完成的。例如,这里我使用 HDRI 版本的 IM 也执行了图像的“往返”FFT,但这次生成了实数/虚数图像。
|
![]() |
当您使用 plus 形式生成实数/虚数 FFT 图像时,您必须使用 HDRI 版本。如果您没有,大约 1/2 的值将为零,导致图像看起来“脏”。例如...
|
![]() |
|
![]() 仅实数 |
![]() 仅虚数 |
傅里叶变换的属性
恒定图像的 FFT
让我们演示一下这些属性。首先,让我们简单地取一个常数颜色图像,并获取其幅度。请注意,在这种情况下,幅度图像确实是纯黑色的,除了图像最中心的单个彩色像素外,该像素位于像素位置宽度/2、高度/2。此像素是图像的零频率或 DC(“直流”)值,是唯一不代表正弦波的像素。换句话说,此值仅仅是 FFT 常数分量!为了更清楚地看到这个单个像素,让我们也放大图像的该区域...
|
![]() |
![]() ![]() |
虽然直流值的“相位”并不重要,但它应该始终为“零”角(相位颜色值为 50% 灰色)。如果未设置为 50% 灰色,则直流值将具有“不真实”分量,并且其值会根据给定的角度进行调制。 |
直流色的影响
在更典型的非恒定图像中,直流值是图像的平均颜色。如果您将图像完全模糊、平均或调整大小为单个像素或颜色,您通常会获得这种颜色。例如,让我们从“Lena”图像的 FFT 中提取直流像素。
|
![[IM Output]](../img_photos/lena.png)

![[IM Output]](lena_magnitude.png)

![[IM Output]](lena_dc_zoom.gif)
例如,让我们将该“暗粉色”直流像素替换为其他颜色,例如更橙色的“番茄”颜色…
|
![]() |
正弦波图像的频谱
接下来,让我们看一下来自具有 4 个周期跨图像的单个正弦(或余弦)波图像的光谱
magick -size 128x129 gradient: -chop 0x1 -rotate 90 -evaluate sine 4 \ sine4.png magick sine4.png -fft +delete \ -auto-level -evaluate log 100 sine4_spectrum.png |
![[IM Output]](sine4.png)

![[IM Output]](sine4_spectrum.png)
![]() ![]() |
上述梯度图像的非寻常创建是必要的,以确保生成的正弦波图像完美地平铺在整个图像上。 正常的“ gradient: ”图像不能完美地平铺,因此从它生成的正弦波也不能完美地平铺。对这种不完美平铺的图像进行 FFT 变换,将导致一系列不希望的谐波,而不是傅里叶变换频谱中的单个“点”。有关此问题的更多详细信息,请参见 Generating the Perfect Gradient。 |
magick -size 128x129 gradient: -chop 0x1 -rotate 90 -evaluate sine 16 \ -write sine16.png -fft -delete 1 \ -auto-level -evaluate log 100 sine16_spectrum.png |
![[IM Output]](sine16.png)

![[IM Output]](sine16_spectrum.png)
小变大,大变小。
这是处理傅里叶变换时需要牢记的最重要方面之一,因为它是从图像中去除噪声(小特征)并保留图像整体更大方面的关键。让我们仔细看一下这三个“频率”,方法是绘制它们的原始幅度(而不是对数频谱)。
|
![]() |
![[IM Output]](lena_spectrum.png)
![]() ![]() |
在生成过程中,FFT 算法只生成图像的左半部分。另一半是通过生成的数据的旋转和复制生成的。 将频域图像转换回空间域图像时,算法再次只查看图像的左半部分。右半部分被完全忽略,因为它只是一个副本。 因此,当(在后面的示例中)您对 FFT 幅度图像进行“陷波滤波”时,您实际上只需要滤波幅度图像的左侧。您还可以通过忽略右半部分来节省一些工作。但是为了清楚起见,我将在两半都进行“陷波滤波”。 |
直接生成 FFT 图像
现在我们可以利用以上信息来实际生成正弦波图像。您只需要创建一个黑色和 50% 灰色图像对,然后添加具有适当幅度和相位的“点”。例如…
magick -size 128x128 xc:black \ -draw 'fill gray(50%) color 64,64 point' \ -draw 'fill gray(50%) color 50,68 point' \ -draw 'fill gray(25%) color 78,60 point' \ generated_magnitude.png magick generated_magnitude.png \ -auto-level -evaluate log 3 generated_spectrum.png magick -size 128x128 xc:gray50 generated_phase.png magick generated_magnitude.png generated_phase.png \ -ift generated_wave.png |
![[IM Output]](generated_spectrum.png)
![[IM Output]](generated_phase.png)

![[IM Output]](generated_wave.png)
![]() ![]() |
实际上,只需要第一个(最左边的)“gray25”点即可生成正弦波,因为 IFT 变换完全忽略图像的右半部分,因为这应该只是左半部分的旋转镜像。 |
![]() ![]() |
直流值的相位必须具有“零角”(50% 灰色颜色)。如果您不能确保这一点,直流颜色值将受其非零相位的调制,从而产生更暗、可能“裁剪”的图像。 |
![]() ![]() |
相位中的其他像素可以是您喜欢的任何灰度级,并且将有效地将正弦波在图像中“滚动”。同样,实际上只有最左边的点的相位才重要。右侧被完全忽略。只需确保中心直流相位像素保持 50% 灰色即可。 |
FUTURE: Perlin Noise Generator using FFT
垂直线的频谱
显示细线和粗线的 FFT 频谱演示小特征如何在图像的 FFT 中变得“大”,而大特征则变得“小”。将它链接回可以视为具有单个谐波的“线”的正弦波。旋转线矩形图案图像的频谱
接下来,让我们看一下黑色背景中宽度为 8、高度为 16 的白色矩形的光谱。
magick -size 8x16 xc:white -gravity center \ -gravity center -background black -extent 128x128 rectangle.png magick rectangle.png -fft +delete \ -auto-level -evaluate log 100 rect_spectrum.png |
![[IM Output]](rectangle.png)

![[IM Output]](rect_spectrum.png)
magick rectangle.png -rotate 45 -gravity center -extent 128x128 \ -write rect_rot45.png -fft -delete 1 \ -auto-level -evaluate log 100 rect_rot45_spectrum.png |
![[IM Output]](rect_rot45.png)

![[IM Output]](rect_rot45_spectrum.png)
magick rectangle.png -rotate 45 -geometry +30+20 -extent 128x128 \ -write rect_rot45off.png -fft -delete 1 \ -auto-level -evaluate log 100 rect_rot45off_spectrum.png |
![[IM Output]](rect_rot45off.png)

![[IM Output]](rect_rot45off_spectrum.png)
平坦圆形图案图像的频谱
接下来,让我们看一下来自具有白色、平坦圆形图案的图像的光谱,一种情况的直径为 12(半径为 6),另一种情况的直径为 24(半径为 12)。
magick -size 128x128 xc:black -fill white \ -draw "circle 64,64 64,70" -write circle6.png -fft -delete 1 \ -auto-level -evaluate log 100 circle6_spectrum.png magick -size 128x128 xc:black -fill white \ -draw "circle 64,64 64,76" -write circle12.png -fft -delete 1 \ -auto-level -evaluate log 100 circle12_spectrum.png |
![[IM Output]](circle6.png)

![[IM Output]](circle6_spectrum.png)
![[IM Output]](circle12.png)

![[IM Output]](circle12_spectrum.png)
高斯图案图像的频谱
接下来,让我们看一下来自两个图像的光谱,每个图像都包含一个白色高斯圆形图案,它们的 sigma 分别为 8 和 16
magick -size 128x128 xc:black -fill white \ -draw "point 64,64" -gaussian-blur 0x8 -auto-level \ -write gaus8.png -fft -delete 1 \ -auto-level -evaluate log 1000 gaus8_spectrum.png im_profile -s gaus8.png gaus8_pf.gif im_profile -s gaus8_spectrum.png gaus8_spectrum_pf.gif |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
magick -size 128x128 xc:black -fill white \ -draw "point 64,64" -gaussian-blur 0x16 -auto-level \ -write gaus16.png -fft -delete 1 \ -auto-level -evaluate log 1000 gaus16_spectrum.png im_profile -s gaus16.png gaus16_pf.gif im_profile -s gaus16_spectrum.png gaus16_spectrum_pf.gif |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
网格图案图像的频谱
接下来,让我们转换一个只包含一组间距为 16x8 像素的网格线的图像。
magick -size 16x8 xc:white -fill black \ -draw "line 0,0 15,0" -draw "line 0,0 0,7" \ -write mpr:tile +delete \ -size 128x128 tile:mpr:tile \ -write grid16x8.png -fft -delete 1 \ -auto-level -evaluate log 100000 grid16x8_spectrum.png |
![[IM Output]](grid16x8.png)

![[IM Output]](grid16x8_spectrum.png)
更多频谱信息
如果您想了解更多关于频谱图像及其属性的信息,请点击以下链接。实际应用
好的,现在我们已经介绍了基础知识,使用傅立叶变换有哪些实际应用?可以使用傅立叶变换完成的一些事情包括:1)增加或减少图像的对比度,2)模糊,3)锐化,4)边缘检测和 5)噪声去除。改变图像对比度 - 系数开方
可以通过执行正向傅立叶变换,将幅度图像提高到某个幂,然后将其与相位一起用于逆傅立叶变换来调整图像的对比度。要提高对比度,使用略小于一的指数;要降低对比度,使用略大于一的指数。因此,让我们首先使用 0.9 的指数来提高 Lena 图像的对比度,然后使用 1.1 的指数来降低对比度。
magick lena.png -fft \ \( -clone 0 -evaluate pow 0.9 \) -delete 0 \ +swap -ift lena_plus_contrast.png magick lena.png -fft \ \( -clone 0 -evaluate pow 1.1 \) -delete 0 \ +swap -ift lena_minus_contrast.png |
![[IM Output]](../img_photos/lena.png)

![[IM Output]](lena_plus_contrast.png)
![[IM Output]](../img_photos/lena.png)

![[IM Output]](lena_minus_contrast.png)
模糊图像 - 低通滤波
傅立叶变换最重要的性质之一是,空间域中的卷积等效于频域中的简单乘法。在空间域中,使用小的方形简单卷积滤波器(核)通过 -convole 选项模糊图像。这称为低通滤波器。最简单的滤波器只是一个等权重的方形阵列。也就是说,所有值都为一,在应用卷积之前,通过除以其总和进行归一化。这等效于局部或邻域平均。另一个低通滤波器是 -gaussian-blur 或 -blur 提供的高斯加权圆形滤波器。在频域中,一种低通模糊滤波器只是一个由黑色包围的恒定强度白色圆圈。这类似于空间域中的圆形平均卷积滤波器。但是,由于空间域中的卷积等效于频域中的乘法,我们只需要执行正向傅立叶变换,然后将滤波器与幅度图像相乘,最后执行逆傅立叶变换。我们注意到,小尺寸的卷积滤波器将对应于频域中的大圆圈。乘法通过 -composite 使用 -compose 乘法设置进行。因此,让我们尝试使用两种尺寸的圆形滤波器来执行此操作,一种直径为 40(半径为 20),另一种直径为 28(半径为 14)。
magick -size 128x128 xc:black -fill white \ -draw "circle 64,64 44,64" circle_r20.png magick lena.png -fft \ \( -clone 0 circle_r20.png -compose multiply -composite \) \ \( +clone -evaluate log 10000 -write lena_blur_r20_spec.png +delete \) \ -swap 0 +delete -ift lena_blur_r20.png magick -size 128x128 xc:black -fill white \ -draw "circle 64,64 50,64" circle_r14.png magick lena.png -fft \ \( -clone 0 circle_r14.png -compose multiply -composite \) \ \( +clone -evaluate log 10000 -write lena_blur_r14_spec.png +delete \) \ -swap 0 +delete -ift lena_blur_r14.png |
![]() ![]() ![]() ![]() |
![]() ![]() ![]() ![]() ![]() |
![]() ![]() ![]() ![]() ![]() |
magick circle_r20.png -blur 0x4 -auto-level gaussian_r20.png magick lena.png -fft \ \( -clone 0 gaussian_r20.png -compose multiply -composite \) \ \( +clone -evaluate log 10000 -write lena_gblur_r20_spec.png +delete \) \ -swap 0 +delete -ift lena_gblur_r20.png magick circle_r14.png -blur 0x4 -auto-level gaussian_r14.png magick lena.png -fft \ \( -clone 0 gaussian_r14.png -compose multiply -composite \) \ \( +clone -evaluate log 10000 -write lena_gblur_r14_spec.png +delete \) \ -swap 0 +delete -ift lena_gblur_r14.png |
![]() ![]() ![]() ![]() |
![]() ![]() ![]() ![]() ![]() |
![]() ![]() ![]() ![]() ![]() |
检测图像中的边缘 - 高通滤波
在空间域中,从图像中提取边缘的高通滤波器通常实现为具有正负权重的卷积,使得它们加起来为零。在频域中,事情要简单得多。这里的高通滤波器只是低通滤波器的反转版本。也就是说,低通滤波器明亮的地方,高通滤波器黑暗,反之亦然。因此,在 ImageMagick 中,我们只需要对低通滤波器图像进行 -negate 操作。因此,让我们使用圆形图像对 Lena 图像应用高通滤波器。然后再次使用纯粹的高斯曲线。
magick circle_r14.png -negate circle_r14i.png magick lena.png -fft \ \( -clone 0 circle_r14i.png -compose multiply -composite \) \ \( +clone -evaluate log 10000 -write lena_edge_r14_spec.png +delete \) \ -delete 0 +swap -ift -normalize lena_edge_r14.png magick -size 128x128 xc: -draw "point 64,64" -blur 0x14 \ -auto-level gaussian_s14i.png magick lena.png -fft \ \( -clone 0 gaussian_s14i.png -compose multiply -composite \) \ \( +clone -evaluate log 10000 -write lena_edge_s14_spec.png +delete \) \ -delete 0 +swap -ift -normalize lena_edge_s14.png |
![]() ![]() ![]() ![]() |
![]() ![]() ![]() ![]() ![]() |
![]() ![]() ![]() ![]() ![]() |
锐化图像 - 高增益滤波
锐化图像的最简单方法是对其进行高通滤波(不进行归一化拉伸),然后将其与原始图像混合。
magick lena.png -fft \ \( -size 128x128 xc: -draw "point 64,64" -blur 0x14 -auto-level \ -clone 0 -compose multiply -composite \) \ -delete 0 +swap -ift \ lena.png -compose blend -set option:compose:args 100x100 -composite \ lena_sharp14.png |
![[IM Output]](../img_photos/lena.png)

![[IM Output]](lena_sharp14.png)
去除噪声 - 陷波滤波
许多噪声图像包含某种模式噪声。这种噪声很容易在频域中去除,因为模式显示为几个点或线的模式。回想一下,一个简单的正弦波是一个重复的模式,并且在频谱中仅显示为 3 个点。为了去除这种噪声,人们只需要(但不幸的是)手动屏蔽(或陷波)幅度图像中的点或线。我们通过转换为频域、创建频谱的灰度版本、屏蔽点或线、对其进行阈值处理、将二值掩模图像与幅度图像相乘,然后转换回空间域来做到这一点。让我们在 小丑图像 上尝试一下,该图像包含对角条纹状抖动模式。首先,我们将小丑图像转换为以生成其幅度和相位图像。
magick clown_orig.jpg -fft \ \( +clone -write clown_phase.png +delete \) +delete \ -write clown_magnitude.png -colorspace gray \ -auto-level -evaluate log 100000 clown_spectrum.png |
![]() 原始图像 |
![]() |
![]() 频谱 |
![]() 相位 |
magick clown_spectrum_edited.png clown_spectrum.png \ -compose difference -composite \ -threshold 0 -negate clown_spectrum_mask.png |
![[IM Output]](clown_spectrum_edited.png)

![[IM Output]](../img_photos/clown_spectrum_mask.png)
magick clown_magnitude.png clown_spectrum_mask.png \ -compose multiply -composite \ clown_phase.png -ift clown_filtered.png |
![[IM Output]](clown_orig.jpg)

![[IM Output]](clown_filtered.png)
非常好的结果。但我们还可以做得更好。正如您在前面的示例中所看到的,简单的“圆圈”对 FFT 图像并不特别友好,因此让我们稍微模糊一下掩模...
|
![]() |
并过滤小丑,这次在内存中重新生成 FFT 图像。
|
![]() |
我们甚至可以获取原始图像和结果之间的差异,以创建噪声去除区域的图像。
|
![]() |
magick twigs.jpg -fft +delete -colorspace gray \ -auto-level -evaluate log 100000 twigs_spectrum.png |
![[IM Output]](twigs.jpg)

![[IM Output]](twigs_spectrum.png)
magick twigs_spectrum_edited.png twigs_spectrum.png \ -compose difference -composite \ -threshold 0 -negate twigs_spectrum_mask.png |
![[IM Output]](twigs_spectrum_edited.png)

![[IM Output]](../img_photos/twigs_spectrum_mask.png)
magick twigs.jpg -fft \ \( -clone 0 twigs_spectrum_mask.png -compose multiply -composite \) \ -swap 0 +delete -ift twigs_filtered.png |
![[IM Output]](twigs.jpg)

![[IM Output]](twigs_filtered.png)