ImageMagick 示例 --
图像卷积
- 索引
- ImageMagick 示例前言和索引
- 卷积介绍
-
模糊图像(低通滤波)
- 模糊内核
- 高斯与模糊核
- 软化模糊(与原始图像混合)
- 使用模糊“反锐化”图像(从原始图像中减去)
- 边缘检测卷积(高通滤波)
- 方向卷积(斜率,罗盘滤波)
-
相关
- 卷积与相关(非对称内核影响)
- 相关和形状搜索
- 相关与 HitAndMiss
- 邻居计数
卷积介绍
“Convolve
”和与其密切相关的“Correlate
”方法,在很多方面与形态学非常相似。实际上,它们的工作方式几乎完全相同,在每个位置匹配一个邻域“内核”,使它们只是另一种特殊的形态学“方法”。实际上,它们也使用与基本内核和用户定义内核中定义的相同代码,甚至相同的内核定义。有关专门为该运算符设计的使用内核(有很多),我建议您参考模糊内核和边缘检测内核。最重要的内核是“Gaussian
”内核。但是,卷积比形态学要古老得多,它会生成更多灰度梯度效果,而不是形态学通常生成的二进制形状研究效果。这就是为什么它通常被认为是与形态学截然不同或独立的运算,并且它是图像处理的核心运算。基本上,卷积或相关执行对指定邻域内所有像素的“加权平均”。也就是说,它将每个附近像素的值乘以内核中给出的量,然后将所有这些值加在一起以产生最终结果。因此,最终图像中的每个像素通常将包含周围源图像中所有其他像素的至少一小部分。从另一个角度来看,图像中每个像素的颜色将被添加到(模糊)或从(锐化/边缘检测)其所有附近邻居的颜色中,如使用的内核所定义。‘convolve’ 和 ‘correlate’ 是相同的操作,只是在非常细微但重要的方面有所不同,对于我们现在将要查看的示例和控件,您可以将它们视为基本上相同的事物。稍后(参见卷积与相关),我们将研究这两个运算符在实际上的差异,以及为什么它们以如此细微的方式有所不同。但在大多数情况下,它们是相同的方法。卷积 ( )
如上所述,‘Convolve
’ 方法通过根据内核中的浮点值对局部邻域中的每个像素进行加权来工作。然后简单地将加权值加在一起以生成结果图像中新的替换像素。例如,让我们使用一个非常小的用户定义的卷积核来对单个像素进行卷积。我还设置了特殊的显示内核设置,这样您就可以看到正在定义和使用的内核的详细信息(显示的图像已放大)。
|
0.5
”值,并将得到的“半亮”像素添加到结果图像中。类似地,当内核的原点精确地位于原始像素上时,它将获得“1.0
”的值,并复制原始像素,而周围没有其他值(黑色)在邻域中添加任何成分到结果中。请注意,任何内核值为“0.0
”将不会参与最终计算。零值实际上不属于“邻域”,就像形态学内核中的任何“Nan
”值都不会参与一样。因此,该内核由 5 个元素的邻域组成。在很多方面,‘Convolve
’ 方法与形态学‘Dilate
’ 方法非常相似,但是 ‘Dilate
’ 仅将内核视为一种类型的位图掩码,在邻域内定位最大值。另一方面,‘Convolve
’ 是邻域内所有值的加权和,因此每个内核元素的值都在最终结果中起作用。卷积操作的语法是…-morphology Convolve {convolution_kernel}
-convolve {convolution_kernel}
在 IM v6.5.9 之前,较旧的 "-convolve " 不理解形态学内核定义。它只接受用户定义内核的“旧样式”,它仅包含一串逗号分隔的值以生成一些奇数大小的正方形内核。现在它将接受“新样式”的卷积内核定义。但是它仍然仅限于“奇数大小”的正方形内核。并且将保持这种状态,直到它开始使用新的“形态学”卷积方法。 |
较旧的 "-convolve " 运算符与新的形态学 ‘Convolve ’ 方法并不完全相同。以下是两种操作的差异列表…
最终,随着事物与新的形态学 ‘ Convolve ’ 方法合并,上述大多数差异将发生变化。 |
Convolve
’ 的实际工作原理,我建议您还查看 EECE \ CS 253 图像处理,第 7 讲,空间卷积。 维基百科,卷积 文章中有一些关于卷积过程的不错的一维动画。卷积核缩放
上面的示例对于像单个像素这样的几乎全黑图像效果很好,但是如果您将其应用于真实图像,您将遇到问题…
|
0.5
’,加上原始像素的完整副本。也就是说,内核中所有值的总和为 3,这使得结果图像亮了三倍!如果您返回并查看上面的‘showKernel’ 输出,您会看到它列出了该内核,其“卷积输出范围为 0 到 3”。这表明该内核通常会使图像亮度增加三倍。为了解决这个问题,您需要将内核中的所有值除以 3。也就是说,“0.5
”的值实际上应该约为“0.1667
”,而中心值“1.0
”应该约为“0.3333
”。这个过程被称为“内核归一化”。例如,这是手动“归一化”的结果和内核定义…
|
上面显示的“内核图像”(使用特殊的 内核到图像脚本 生成)也显示了生成的归一化内核。如您所见,内核本身现在非常暗,因为其所有值都很暗,尽管它们加起来的值为“1.0 ”。从现在开始,显示的所有卷积内核图像都将进行调整,使其最大值设置为白色,否则您通常只会看到一个黑暗且基本无用的“内核图像”。 |
-define convolve:scale={kernel_scale}
”允许您为内核指定一个全局缩放因子,从而调整整体结果的亮度。
|
内核归一化(自动缩放)
您无需计算缩放因子(如上所述),只需让 IM 通过提供特殊的“!
”归一化标志来在内部计算此“归一化缩放因子”。
|
“! ”字符有时也用于各种 UNIX 命令行 shell 的特殊用途。因此,您可能需要使用反斜杠对其进行转义,即使在引号中也是如此。建议谨慎。 |
-convolve
”变体将自动执行此归一化。您可以让 IM 归一化内核,然后通过给定量再次对其进行缩放以调整其输出范围。为了使这更容易,您可以将缩放因子指定为百分比。例如,这里我归一化了内核,但随后将值重新缩放为计算大小的 50%,从而产生更暗的结果。
|
!
”的值实际上等同于使用“1!
”甚至“100%!
”。如果您想翻转内核中的正值和负值,您甚至可以使用负缩放因子。有关此示例,请参阅 “非锐化”使用模糊的图像。如果内核已以这种方式归一化,则 显示内核 输出将告诉您它已归一化。归一化工作原理
实际的“内核归一化”工作方式是将所有内核值加在一起(包括任何可能的负值)。如果结果非零,则对所有值进行缩放,以使它们的组合值加起来等于 1(“1.0
”)。请注意,如果您有负值,这实际上可能会创建一个值大于 1 的内核,通常在原点处。它特别发生在 非锐化 内核中。但是,重要的是,内核作为一个整体加起来等于“1.0
”,因此最终图像不会因 卷积 操作而变暗或变亮。如果加法结果为零(“0.0
”),则假设内核是特殊的 零和内核。在这种情况下,内核将被缩放以使所有正值等于“1.0
”,同样,所有负值加起来将等于“-1.0
”。这些内核在 边缘检测 技术中尤其普遍。 显示内核 输出也将指定它是零和,如果内核采用这种形式,即使它实际上不是一个归一化的零和内核,尽管这也可以从显示的其他数字中轻松看出。大多数数学确定的内核都是预先归一化的。这包括数学推导的内核:“Unity
”、“Gaussian
”、“LoG
”、“DoG
”、“Blur
”、“Comet
”。但是,离散常数内核未预先归一化,因此您必须使用 内核归一化设置(如上所述)来执行此操作。这包括内核:“Laplacian
”、“Sobel
”、“Roberts
”、“Prewitt
”、“Compass
”、“Kirsch
”、“FreiChen
”。请注意,“FreiChen
”内核具有专门为更具体目的而预先加权的子类型。FreiChen 内核不应归一化,而应按原样使用。 零和归一化
并非所有卷积内核都使用正值。您也可以获得使用正值和负值的混合内核,并且这些内核的值通常旨在加起来为零,以产生 零和内核。这些内核对于更高级的图像卷积非常重要,因为它们提供了 边缘检测 和 锐化图像 的技术。正如我在上一节中提到的,通常的归一化标志“!
”将适用于这些内核。但有时由于特殊情况,您希望确保内核保持“零和”。特殊的“^
”归一化方法只是提供了一种在以下情况下确保内核为“零和”的方法...- 如果用户的内核定义不够精确,无法确保零和。例如,您无法将“
1/3
”或任何其他 3 的分数因子指定为精确的浮点小数。 - 数学曲线被内核大小(半径)“裁剪”,因此它可能不再是零和。例如,这发生在基于无限响应曲线的“
LoG
”或“DoG
”内核中。出于这个原因,IM 实际上在这些内核上内部使用这种特殊的归一化。 - 确保 相关“形状蒙版”是零和,以便在搜索中,IM 可以平等地寻找正负匹配。请参阅下面的 相关形状搜索。
-1.0
”,所有正值将被缩放以加起来等于“+1.0
”。结果是,内核作为一个整体,将保证加起来等于零。请注意,如果您将此归一化方法用于诸如“高斯”之类的全正内核,您仍然会获得一个正确归一化的内核。因此,这种形式的归一化仍然可以与 模糊内核 一起使用。但是,它不应用于直接定义的 锐化 甚至 非锐化 内核,因为这可能包含负值,但需要加起来等于 1(使用正常归一化方法)。 与单位核混合内核
内核缩放设置的完整语法是...-define convolve:scale='{kernel_scale}[!^] [,{origin_addition}] [%]'
-set option:convolve:scale '{kernel_scale}[!^] [,{origin_addition}] [%%]'
-set
”时百分号要加倍。可选的归一化标志“!
”或“^
”将首先应用于用户定义的或内置的内核(如果需要)。之后,内核将根据“kernel_scale”因子进行缩放,从而增加或减少卷积对结果的有效“功率”。默认缩放因子为“1.0
”。最后,内核的“原点”值将添加逗号后的数字。默认“origin_addition”为“0.0
”。最后一步实际上是在先前生成的归一化和缩放内核中“添加”一个给定“缩放”的 Unity 内核。这会生成可以... 的内核。请注意,如果您给出了百分比(“%
”)标志,则该百分比将应用于“kernel_scale”因子和“origin_addition”。当涉及分数时,这可以使比例更容易阅读和理解。内核缩放定义的示例用法...
-define convolve:scale='!50%,100%' -morphology Convolve Laplacian:2 |
Laplacian:2
”内核...0 | -1 | 0 |
---|---|---|
-1 | 4 | -1 |
0 | -1 | 0 |
0 | -0.25 | 0 |
---|---|---|
-0.25 | 1 | -0.25 |
0 | -0.25 | 0 |
0 | -0.125 | 0 |
---|---|---|
-0.125 | 0.5 | -0.125 |
0 | -0.125 | 0 |
0 | -0.125 | 0 |
---|---|---|
-0.125 | 1.5 | -0.125 |
0 | -0.125 | 0 |
Laplacian:2
”作为锐化内核进行卷积,但锐化强度仅为“50%
”。请记住,在比例设置中给出的任何“%
”标志都将使这两个值都成为百分比。如果不存在,则这两个值只是简单的直接乘数。例如,所有这些缩放选项都是等效的这两个归一化标志也是如此。它们可以出现在卷积缩放设置中的任何位置,但它们始终会在任何其他缩放发生之前应用。
50,100% 50%,100 %50,100 .5,1 0.5,1.0
输出结果偏差控制
当您处理包含负值的内核时,结果图像中的一些像素应该被分配负值。这在 零和内核(见下文)中尤其如此。不幸的是,除非您拥有专门构建的 HDRI 版本的 ImageMagick 来保留生成的负值,否则任何负结果都会被裁剪为零(黑色)。您只会从卷积中获得正结果。它只是不能存储在普通的图像格式中,留下了一半的结果。您可以构建 HDRI 版本的 ImageMagick 来保留生成的负值,然后提取您想要的信息。或者,您可以使用负缩放因子将内核取反。例如,使用...-define convolve:scale='-1'
-bias
”,您仍然可以保留正负结果。用于非 HDRI 版本的 IM 的设置是...
-define convolve:scale=50%\! -bias 50% |
-1.0
”,白色代表“+1.0
”。在下面的 相关形状搜索 示例中展示了一个这样做的示例。模糊图像(低通滤波)
IM 示例的另一部分,特别是 模糊和锐化图像,实际上处理了该主题的实际方面。这里我们查看更多具体细节。但是,首先我们将描述基本内核以及如何直接使用它们而无需修改。稍后我们将研究修改模糊以生成其他效果的方法。模糊内核
Unity
这是一个特殊的内核,它实际上什么也不做。仅指定一个内核元素,因此每个像素都被替换为其自身,没有任何变化。例如,这里是一个无操作的 卷积...从 IM v 6.6.9-4 开始,内核可以接受一个参数,作为内核特定的比例参数。这使您可以使用它来乘以图像的值,例如使图像更亮或更暗。
|
Disk:0.5
”生成,这也允许您在内核生成中指定一个额外的缩放参数。(例如:最后一个示例中的“Disk:0.5,0.5
”)。类似的内核(用于 卷积)也可以由带有“sigma”值为“0.0
”的“Gaussian
”内核生成器生成。但是,它只能生成一个小的 3x3 内核,由一个中心值为“1.0
”的值和周围 8 个值为“0.0
”的值组成。
使用形状内核的均值或平均滤波
虽然下面定义的大多数卷积内核通常在某种程度上涉及使用高斯曲线,但您仍然可以使用以前的 形态形状内核 来简单地对给定(较大)区域内的像素进行平均。当然,您需要对内核进行 归一化,以便实际生成平均值,而不仅仅是邻域的总和。例如,这里我使用一个较小的“Octagon
”形状内核,来对每个像素周围圆形区域内找到的所有像素值进行平均。结果是,每个像素的值在定义的邻域中的所有 25 个像素上平均分配。也就是说,它相当于对给定形状的“均值”或“平均”滤波器。如果您想从该平均值中排除原始像素,只使用周围的像素,那么您可以使用“Ring
”内核(只提供一个半径)。其他 形状内核 也可以以相同的方式使用,例如对“Diamond
”、“Square
”或大的“Disk
”形状的像素值进行平均,以及您想要的任何尺寸。然而,虽然对形状区域的恒定平均会模糊图像,但它往往会在结果图像中产生不寻常的效果(特别是 混叠伪像)。更具体地说,使用“平坦”的平均内核往往会将尖锐的边缘转换为更厚的线性斜率,并在加厚的边缘处突然改变斜率。结果的厚度是内核“radius*2-1
”。不同的边缘角度如何影响斜率厚度和斜率线性取决于“平坦”或平均内核的形状。
magick -size 80x80 xc: -draw 'polygon 15,15 15,65 60,15' shape.png magick shape.png \ -define convolve:scale=! -morphology Convolve Square:5 \ shape_mean_square.png magick shape.png \ -define convolve:scale=! -morphology Convolve Disk:5 \ shape_mean_disk.png |
-blur 5x65535
来实现。在形态学可用之前,Fred Wienhaus 在他的脚本中经常使用这种方法。
高斯内核(2d 高斯模糊)
您可能已经注意到,“Gaussian
”内核是用于 卷积 图像的最常用的内核。这是用于模糊效果的数学理想内核。例如,这里是一个小的“Gaussian
”内核的 Show Kernel(它们可以非常快地变得非常大)...我实际上不想对上面进行卷积,因为我只想显示它将要使用的内核。因此,我使用了一个“:0
”的 迭代次数,所以它什么都不做。同样,我使用特殊的“null:
”文件格式来丢弃生成的图像输出。正如您从卷积输出范围中看到的那样,“Gaussian
”内核已经为您进行了归一化(缩放)。但是您也会注意到它仍然是一个相当大的内核,充满了小的分数值。如果您仔细观察,您会发现最大值(2.48678,也在第一行中列出)在中心,最小值在边缘和角落(大约 .000000194 的值)。这里是一个典型的使用卷积的高斯模糊...内核语法很简单...
Gaussian:[{radius}]x{sigma} |
-gaussian-blur
”运算符所使用的参数完全相同,该运算符实际上使用该内核执行 卷积。第一个数字,像大多数 形态内核 一样,是内核的“radius”或大小。这只是一个整数,最小值为 1,使最小的可能内核大小为 3x3 个元素。最好的方法是始终指定零,这允许 ImageMagick 为提供的“sigma”值计算一个适当的半径。第二个更重要的参数是“sigma”,它定义了每个像素应该模糊或“散布”多少。值越大,图像越模糊。这是一个浮点数。必须提供sigma值。如果给出“0.0
”的 sigma 值,您将得到一个相当无用的“Unity
”内核(具有给定的半径,或半径为 1,因此产生一个 3x3 内核,其中包含一个周围为“0.0
”值的“1.0
”值)。正如您在上面看到的,使用任何类型的“Unity
”内核进行卷积对图像没有任何影响!如果您确实指定了一个“radius”,那么通常最好使其至少是“sigma”的两倍,IM 通常计算一个大约是其 3 倍的半径(实际上是提供有意义结果的最大半径),尽管这取决于您特定 IM 安装的 编译时质量。有关“Gaussian
”内核参数的影响以及一般图像模糊的更多信息,请参见... 模糊图像。
模糊内核(1d 高斯模糊)
“Blur
”内核与 高斯内核 非常相似,甚至采用相同的参数(见下文)。但高斯是二维曲线,而“Blur
”内核产生一维曲线。也就是说,它会生成一长串薄薄的单行值。这里是一个小的“Blur
”内核的 Show Kernel 输出。
|
|||
|
Blur
”内核的实际配置文件。它是使用 Kernel Image 脚本“kernel2image
”创建的,然后使用“im_profile
”脚本对该图像进行绘制。它清楚地显示了此内核表示的“高斯钟形曲线”。以下是如何使用此内核水平模糊图像的示例。
|
Gaussian
”完全相同,但还有一个可选的旋转角度。
Blur:[{radius}]x{sigma}[,{angle}] |
Unity
”内核的线性等效项。“angle”允许您将内核旋转 90 度,从而使您可以垂直模糊图像。
|
Gaussian
”内核产生的 2 维图像模糊更快的形式。有关如何实现此操作的详细信息,请参阅下面的 高斯与模糊内核。
彗星内核(一半 1d 高斯模糊)
“Comet
”内核几乎与“Blur
”内核完全相同,但实际上只是模糊内核的一半。请注意,原点的定义位置在左侧边缘,而不是内核的中心。这对卷积内核来说很不寻常,因此产生了非常不寻常的结果。它像手指在湿润的油漆表面上涂抹一样,在一个方向上模糊图像,留下颜色痕迹。有点像彗星的尾巴,或者流星或流星坠落的痕迹。
|
|
高斯与模糊核
如前所述,“Gaussian
”和“Blur
”内核密切相关,实际上可以完成相同的工作。两者都是 高斯曲线 的表示,前者是二维表示,而后者是一维表示。例如,以下是“-gaussian-blur 0x2
”的重复,它等效于“-morphology Convolve Gaussian:0x2
”操作。
|
|
|
>
”来进行 90 度旋转列表(在本例中为两个内核)。例如...
magick face.png -morphology Convolve 'Blur:0x2>' face_blur_x2.png |
以上所有示例都是等效的,也是“-blur ”运算符的工作原理。
|
-blur
”和“-gaussian-blur
”运算符之间的真正区别。在后者中,使用了一个大的二维内核,而在前者中,使用两个小的二维内核。然而,在速度方面,“-blur
”运算符通常快一个数量级,因为它使用两个小得多的内核,而不是一个非常大的内核。模糊参数越大(sigma参数的大小),内核就越大,两种操作之间的速度差异就越大。因此,“-blur
”运算符通常是推荐使用的运算符。两种运算符之间结果的唯一区别是小的量子舍入效应(除非您使用 HDRI)和边缘效应(取决于 虚拟像素设置)。这两者都是由由于在“blur”卷积的两个单独步骤之间保存中间图像而导致的信息丢失造成的。这种差异通常小到肉眼看不见,对任何实际应用都没有影响。 柔化模糊(与原始图像混合)
您可以通过将任何类型的模糊与原始图像的某些部分混合来柔化其影响。尤其是在应用非常强的模糊时。例如...
magick face.png -morphology Convolve Gaussian:0x3 face_strong_blur.png magick face.png face_strong_blur.png \ -compose Blend -define compose:args=60,40% -composite \ face_soft_blur.png |
混合
”合成方法,将模糊图像(合成源图像)的“`60%`”与原始图像(合成目标图像)的“`40%`”混合,从而在最终图像上产生“柔化模糊”效果。但是,您可以直接通过`将内核与单位内核混合
`来完成相同操作,并使用相同的比例。
|
单位
”(或“单位”)内核,以防止结果变暗。重要的是,对于`模糊内核
`,这两个数字加起来为“`100%`”,就像您对`合成混合
`一样。您也可以使用更快的两遍模糊,但在此情况下,我们不能直接将“混合”合并到内核中,因为两个独立的卷积不会“干净地”分离。因此,我们将需要再次进行`混合合成
`。
|
请记住,“`-blur `”运算符与使用更快的两遍`模糊内核 `完全相同。 |
使用模糊“取消锐化”图像(从原始图像中减去)
通过进一步进行内核混合,使您开始使用负缩放,您可以从原始图像中减去模糊效果。结果是一种称为“反锐化”的技术。请参见`反锐化,维基百科
`,了解它是如何获得如此不幸的名字的。
|
合成混合
`来完成此操作。上面的示例实际上是错误命名的“`-sharpen
`”运算符的工作原理,但仅使用“*sigma*”模糊控制。但是,没有提供对操作的其他控制。混合与上面给出的完全相同。您可以使用更快的两遍一维`模糊内核
`,但同样,您需要将混合操作作为单独的步骤进行。
|
软化模糊
`几乎相同,但模糊图像是从原始图像中减去而不是添加。一种称为`外推混合
`或超出正常 0 到 100% 范围的混合的混合方法。同样,您只需指定要从原始图像中减去的模糊图像的比例即可。例如,让我们过度锐化图像,导致一些混叠和颜色失真。
|
-unsharp
`”运算符提供了另一种类型的控制。具体来说,一个差异阈值,使得锐化仅在给定差异较大时应用,例如在图像中的实际边缘附近。该阈值可以用于防止“锐化”小的缺陷,如皱纹或相机噪声。图像反锐化通常与非常小的模糊(*sigma*=0.75 数量级)一起使用,在调整大小或扭曲图像后,以改进最终结果。请参见`锐化调整大小的图像
`,以了解一些示例。使用“反锐化”技术进行图像锐化的另一种方法是实际定位图像边缘并使用它们来锐化图像。请参见下面`使用边缘检测锐化图像
`,以了解详细信息。但是,它通常被认为速度较慢,尽管不是快很多。边缘检测卷积(高通滤波)
边缘检测是卷积大量使用的另一个领域。这里任务是以各种方式突出显示或增强图像的边缘。这可以是尽可能准确地定位边缘,也可以是确定每个边缘的斜率角度或方向。但是,图像中存在噪声会使这项工作变得更加困难,例如由扫描仪、数码相机产生的噪声,甚至仅仅是由 JPEG 图像文件格式的有损压缩引起的噪声。一般来说,较大的内核可以更好地处理噪声,但会损失边缘定位精度,而较小的内核会产生清晰的边缘定位结果,但会产生更多由图像噪声引起的虚假结果。有很多小的、众所周知的内核,这些内核已经被开发出来并用于边缘检测。这些内核大多以研究数学或开发特定内核类型的数学家的名字命名。因此,您有诸如“`拉普拉斯
`”、“`索贝尔
`”和“`普雷维特
`”之类的内核。这些“命名”内核通常非常小,并且使用整数定义,因此可以构建到专门设计的优化软件和硬件中以提高速度。也就是说,它们被称为“离散”内核。因此,您需要将内核作为其使用的一部分进行`缩放
`或`归一化
`。边缘检测也具有锐化图像边缘的副作用。`
`零和内核
所有边缘检测内核都具有一个共同特征。它们都是零和的。这意味着它们包含负值,但内核中的所有值加起来为零。对于平滑的单色图像,使用此类内核进行`卷积
`将产生一个“零”或黑色图像。但是,对于任何其他图像,您将获得包含负值和正值的结果。例如,这里我在包含一些基本形状的图像上应用了一个离散的“`索贝尔
`”边缘检测器...
magick -size 80x80 xc:black \ -fill white -draw 'rectangle 15,15 65,65' \ -fill black -draw 'circle 40,40 40,20' shapes.gif magick shapes.gif -define convolve:scale='!' \ -morphology Convolve Sobel shapes_sobel.gif |
索贝尔
`”内核定义)。但是,它只找到了一组边缘,“正”从左到右从黑到白的斜率。为了获得“负”斜率,您需要使用`内核缩放设置
`来对内核取反。例如...
|
索贝尔
`”内核,您也可以将其旋转 180 度以获得与“缩放取反”相同的结果,但并非所有内核都是以这种方式对称的。另一种解决方案是向结果添加`输出偏差
`。也就是说,向结果图像添加 50% 的灰色,使负值比此值更浅,正值更亮。但是,您还需要`缩放内核
`以确保结果不会被图像的“黑色”和“白色”限制“裁剪”。
|
|
索贝尔
`”内核,以了解有关结果处理技术的更多信息,尤其是涉及方向确定的技术。使用`输出偏差
`的另一种方法是构建 Imagemagick 的特殊`HDRI
` 版本。这使用浮点值在内存中存储图像,这意味着图像值不会因使用整数而被“裁剪”或“舍入”。但是,即使您使用此特殊版本的 IM,您仍然需要在保存到普通图像文件格式之前对结果进行后处理,或者您需要使用特殊支持浮点的图像文件格式。但是,您无需担心中间图像结果中的裁剪或舍入效果,从而使处理变得更容易。`
`边缘检测内核
LoG:高斯函数的拉普拉斯算子
LoG:{radius},{sigma} |
拉普拉斯
`”微分(斜率)运算符,已通过添加高斯模糊而平滑。这反过来又消除了图像中大多数噪声的影响,可以通过“*sigma*”设置进行调整。内核包含负值,这些负值围绕一个强烈的中心峰形成一个环。在上图所示的“内核图像”中,负值显示为深色(接近黑色)的颜色,边缘衰减到零(深灰色)朝向边缘。以下显示了它的效果,说明了它是如何突出显示图像边缘的。拉普拉斯内核是无方向的,但在边缘的两侧都会产生正脊和负脊。为了定位边缘,您将寻找正脊和负脊之间的零交叉点,这种技术被称为`马尔和希尔德里斯边缘检测
`。此内核也非常适合`锐化图像
`。DoG:高斯函数的差
DoG:{radius},{sigma1}[,{sigma2}] |
高斯函数的拉普拉斯算子
`”的主要批评之一是,由于它是一个非常不寻常的数学曲线,因此很难实现。它也不是一个记录得很好的曲线。另一个方面是,它不能像高斯函数那样“分离”成更快的两遍解决方案(请参见`高斯函数与模糊内核
`)。但是,通过生成两个“`高斯函数
`”内核,它们具有略微不同的 *sigma* 值(大约为 1.6 的比例),并将它们相互减去,您可以实际生成“`高斯函数的拉普拉斯算子
`”的近似值。结果是,与“`LoG
`”内核相比,“`DoG
`”更容易在硬件中生成。例如,这里我并排放置了“`LoG
`”和“`DoG
`”内核的`内核图像
`,以便比较。如果您查看`高斯函数的差,维基百科
` 网页,您会看到一些图表,它们还比较了“`LoG
`”(或“墨西哥帽”)和“`DoG
`”的轮廓,显示了匹配曲线之间的非常小的差异。*需要更多有关如何映射 LoG 的 sigma 以生成近似等效的 'DoG' 的信息。如果您知道,请通过页脚中的地址给我发送电子邮件。*应用的结果也非常相似。
|
请注意,两个“*sigma*”值都应定义,至少一个应非零。任一 sigma 分量的值为零将等效于“`单位 `”内核,这意味着它保持图像不变。如果两个值都为零,则两个高斯函数将是“`单位 `”内核,当它们被减去时将产生一个完全为零或黑色的结果(加上任何偏差值)。当参数为“`Dog:0,0,*非零*`”时,DoG 变成了一个简单的带通滤波器,它被定义为“单位”内核(生成原始图像)减去低通滤波器内核(模糊图像)。因此,以下内容会生成一个带通滤波后的图像,其滤波器值为 *sigma2*=2
|
拉普拉斯
`”内核,而不是具有不等的对角线偏差。例如,半径=1(对于 3x3 内核)和 sigma 为 1 将生成...
|
|||
|
-blur
”运算符(在内部使用“Blur
”内核)来生成相同的结果。但是要做到这一点,您需要分别生成两个“模糊”图像,然后将结果相减,并加上适当的缩放和偏差。例如...
|
4
”)。这是因为,减去两个归一化的模糊不会产生与在“DoG
”内核中将两个减去的高斯曲线归一化在一起产生的相同(增加的)幅度结果。但是除了幅度之外,上面的示例图像等效于第一个“DoG
”内核结果,只是生成速度更快,特别是对于较大的 sigma 值。重点在于,尽管工作量更大,这种复杂方法比直接使用“DoG
”或“LoG
”内核更快。离散拉普拉斯内核
Laplacian:{type} |
LoG
”内核计算的,但经过缩放以在小型内核数组中使用离散整数。这样,您可以使用生成的专用快速图像过滤器,这些过滤器仅使用整数数学来处理图像数据。但是 ImageMagick 是一个更通用的图像处理器,因此不提供这种超快的专用过滤器。但是人们喜欢使用它们,因为它们更容易理解,因此其中许多已内置到 IM 中。这里提供的内核都不旋转,大多数是“各向异性的”,这意味着它们不是完美的圆形,尤其是在对角线方向。但是请参阅上一节(“DoG
”内核),了解如何生成真正的“各向同性 3x3 拉普拉斯内核”。前两个“Laplacian:0
”和“Laplacian:1
”内核是使用最广泛的“离散拉普拉斯内核”形式。它们非常小,这意味着它们可以非常准确地定位边缘,但也容易增强图像噪声。请注意,并非所有“类型”数字都已定义,为将来定义更多离散内核留出了空间。使用的数字被选中以更好地匹配该数字定义的内核。 Laplacian:0
(默认)
8 邻域拉普拉斯算子。可能是最常见的离散拉普拉斯边缘检测内核。这里我使用 显示内核 来提取“离散”和“未归一化”内核,然后在向您展示归一化内核的结果后,再加上 输出偏差。LoG
”或“DoG
”,都会产生比预期更复杂的结果。在这种情况下,生成无偏差图像(没有任何 输出偏差)效果会更好。因此,让我们在没有偏差的情况下重复上面的操作,以便只保留较亮的“正”边缘。
|
|
Laplacian:1
4 邻域拉普拉斯算子。也经常使用。
|
|||
|
Laplacian:2
3x3 拉普拉斯算子,中心:4 边缘:1 角点:-2
|
|||
|
Laplacian:3
3x3 拉普拉斯算子,中心:4 边缘:-2 角点:1
|
|||
|
Laplacian:5
5x5 拉普拉斯算子
|
|||
|
Laplacian:7
7x7 拉普拉斯算子
|
|||
|
Laplacian:15
离散 5x5 LoG(Sigma 大约为 1.4)
|
|||
|
Laplacian:19
离散 9x9 LoG(Sigma 大约为 1.4)
|
|||
|
使用边缘检测锐化图像(增强原始图像的边缘)
“LoG
”和“DoG
”内核也可用于锐化图像,而不是 使用模糊来使图像不清晰。基本上,您需要做的就是将内核结果(包括负结果)添加到原始图像。要做到这一点很容易,只需将 100% 加权的“Unity
”或“身份”内核添加到缩放因子即可。这就是提供它的原因。例如...
|
这比 非锐化技术 生成的图像更宽泛、更平滑的锐化(结果显示在右侧)。也就是说,因为它是对图像的真正锐化,而不是通过减去模糊而伪造的锐化。 |
例如,锐度较低...
|
或者更锐利...
|
方向卷积(斜率和罗盘)
与上面一样,这些内核寻找图像颜色强度的斜率,但不是任何斜率,它们寻找特定方向的斜率。在数学上,这被称为“导数”,这实际上只是“斜率”的另一种说法。但是了解不同方向的斜率信息也可能有用,因为它可以作为一种方法,您可以从中确定斜率或图像边缘的角度或“罗盘”方向。也就是说,图像中某个特定点的斜率的二维方向。斜率也用于称为图像“浮雕”和“阴影”的图像处理技术中。目前还没有可用的“生成”内核,只有“命名”的预定义内核,例如 Sobel 和 Roberts。但是我确信,浮雕和阴影内核生成函数将在未来某个时间点被移入形态学/卷积内核集。因此,让我们看看一些“命名”的方向内核。方向核
Sobel
我们在讨论 零求和内核 时已经看到了“Sobel”内核。此内核是一个原始的方向(一阶导数)内核,旨在返回某个特定正交方向的边缘斜率。默认情况下,它被设计用于使用“
Sobel:{angle}
convolve
”操作进行从左到右的斜率检测。结果本质上是图像的 X 导数(斜率)。
|
如果您查看内核,您可能会认为它被声明反了。从某种意义上说,您实际上是正确的。但是,这是由于“Convolve”的实际工作方式造成的。 您可以在下面的 Convolve 与 Correlate 中详细了解这种“反转”。 |
50%
”的 偏差,否则无法看到这一点。虽然前面的例子中没有负斜率,但下面的例子中有一个,因此我还添加了一个 偏差设置,以便您可以看到它。
|
如果您将此内核与“Correlate ”一起使用,您将发现与内核定义方式“匹配”的斜率。在这种情况下,您将获得从左侧高(白色值)到右侧低(黑色值)的斜率的正结果。在上面的示例中,两条线将被交换。但是上面是“卷积”,而不是“相关”(意思是匹配内核)。再次查看 Convolve 与 Correlate,了解有关差异的更多详细信息。 |
Sobel
”内核应用于人脸图像的结果。请注意,sobel 和大多数其他边缘检测内核倾向于在非常强的边缘产生 2 像素厚的响应,并在单像素宽的线上产生 3 像素厚的响应。这比拉普拉斯边缘检测器要强得多。您可以使用“angle”参数旋转此内核,通常以 90 度的倍数旋转。但是您也可以以 45 度的倍数旋转它,即使它不是为此设计的。这对于从所有 45 度旋转导数结果的最大值中获取 45 度量化的方向导数或梯度幅度很有用。这里再次出现,但旋转了 90 度(从上到下)。
|
使用“
Sobel
”内核收集图像所有边缘的一种方法是,在所有方向上将内核应用 4 次,并收集看到的最大值(使用 淡化数学合成)。这近似于梯度幅度。
|
Sobel
”内核的所有 90 度旋转。
|
|
|
上述示例中使用的 "-gamma " 函数用于对 "索贝尔 " 结果返回的值执行数学上的 "平方" 和 "平方根" 操作。有关更多详细信息,请参阅 数学函数的幂。额外的 " +level " 确保 加法合成 不会超出图像量子范围。有关详细信息,请参阅 量子效应,非 HDRI 与 HDRI。 |
magick -size 30x600 xc:'#0F0' -colorspace HSB \ gradient: -compose CopyRed -composite \ -colorspace RGB -rotate 90 rainbow.jpg magick shapes.gif -define convolve:scale='50%!' -bias 50% \ \( -clone 0 -morphology Convolve Sobel:0 \) \ \( -clone 0 -morphology Convolve Sobel:90 \) \ -delete 0 \ \( -clone 0,1 -fx '0.5+atan2(v-0.5,0.5-u)/pi/2' rainbow.jpg -clut \) \ \( -clone 0,1 -fx 'u>0.48&&u<0.52&&v>0.48&&v<0.52 ? 0.0 : 1.0' \) \ -delete 0,1 -alpha off -compose CopyOpacity -composite \ face_sobel_direction.png |
-fx
" 表达式是使用 "atan()" 函数将 X、Y 向量转换为角度的表达式。然后,它使用外部 彩虹渐变图像 作为 颜色查找表 进行着色。第二个 "-fx
" 表达式创建一个阈值透明度蒙版,使任何没有斜率的区域都变得透明。但是,上述技术往往会为真实图像生成大量混乱的信息,因为它没有考虑斜率的幅度。以下是另一个更复杂的版本。它几乎所有计算都在绿色 "G" 通道中进行,从而将所需的图像处理量减少了三分之一。然后,它使用 HSB 色彩空间来创建方向(色调)和幅度(亮度)。
|
罗伯茨
"
Roberts:{angle}
罗伯茨
" 内核比之前的 "索贝尔
" 内核简单得多,并且会产生更紧密的边缘位置(低至 2 个像素)。当然,这也使其更容易受到噪声影响。通常,此内核由更小的 2x1 或甚至 2x2 内核表示,但是通过将其实现为 3x3 内核,我可以在 45 度增量中 "循环" 旋转内核。例如,以下是 45 度的结果,更常见地称为 "罗伯茨十字" 内核。
|
索贝尔
" 一样,您也可以使用 多内核处理 从所有方向生成最大斜率。但是这次我们将得到 8 x 45 度方向,而不是只有 4 个。
|
索贝尔
" 一样简单地合并一半数量的卷积。基本上,仅使用一个 "罗伯茨
" 卷积生成的斜率比与实际图像对齐的斜率偏移了半个像素。也就是说,计算出的斜率位于 "+1
" 和 "-1
" 值之间,位于像素之间,但存储在中心 "-1
" 像素中。但是,这也意味着通过保存围绕像素的所有斜率并将它们加在一起,您将获得一个更小的更锐利的边缘检测,只有 2 个像素(而不是 4 个像素)突出显示了清晰的边缘边界。 普雷维特
Prewitt:{angle}
"普雷维特 " 内核与 "索贝尔 " 非常相似,虽然对特定边缘检测的精确方向要宽松得多。因此,结果有点模糊。
|
罗盘
Compass:{angle}
这是 "普雷维特罗盘" 内核,据称比 "索贝尔 " 具有更强的方向感。
|
基尔希
Kirsch:{angle}
这是另一个强大的方向感边缘检测器。
|
弗莱-陈
此内置函数提供了三组内核。第一个是 "索贝尔
" 的 "各向同性"(统一方向)变体,其中 "2
" 值已替换为 2 的平方根。
Frei-Chen:[{type},][{angle}]
上面的内核是 "弗莱-陈 " 内核的核心,它是默认的未加权内核。
|
索贝尔
" 一样,此内核应使用 90 度倍数的角度进行应用。为了使事情更简单,提供了两个内核(具有相同的权重),一个用于正交使用,另一个用于对角线使用。
第三组类型包含 9 个经过专门设计和加权的内核,这些内核不仅用于特定方向的边缘检测,还用于确定锋利边缘的实际角度。此处的 "类型" 是一个从 "
弗莱-陈:1 弗莱-陈:2
11
" 到 "19
" 的数字,允许您从该集中提取任何一个内核。但是,如果您提供 "类型" 值为 "10
",您将获得一个包含所有 9 个预加权内核的多内核列表。The kernels are each applied to the original image, then the results are added together to generate the edge detection result. This is best done using a HDRI version of ImageMagick.
magick image.png \ \( -clone 0 -morphology Convolve FreiChen:11 \) \ \( -clone 0 -morphology Convolve FreiChen:12 \) \ \( -clone 0 -morphology Convolve FreiChen:13 \) \ \( -clone 0 -morphology Convolve FreiChen:14 \) \ \( -clone 0 -morphology Convolve FreiChen:15 \) \ \( -clone 0 -morphology Convolve FreiChen:16 \) \ \( -clone 0 -morphology Convolve FreiChen:17 \) \ \( -clone 0 -morphology Convolve FreiChen:18 \) \ \( -clone 0 -morphology Convolve FreiChen:19 \) \ -delete 0 -background Black -compose Plus -flatten \ result.pfm
If a type of 10 is given then a multi-kernel list of all the 9 weighted kernels shown above is generated. This lets you use multi-kernel composition to do the above, much more simply...
magick image.png -define morphology:compose=Plus \ -morphology Convolve FreiChen:10 \ result.pfm
I have not however found out what the supposed meaning of the results are. If anyone has any experience or knowledge about how this is actually used, please let me know, so I can include it here for others to use.
相关 ( )
"卷积
" 方法基本上用于图像处理,而 "相关
" 方法则更适合于模式匹配。也就是说,它对图像与其内核执行 "互相关" 操作,以寻找图像中给定形状的匹配。实际上,"卷积
" 和 "相关
" 是相同的操作。它们之间的唯一区别实际上非常小,即内核的 x 和 y 反射(相当于 180 度旋转)。我发现的关于相关和卷积的工作原理以及它们如何相互区别的最佳指南是 David Jacobs 撰写的 CMSC 426,2005 年秋季课程笔记。 卷积与相关(非对称内核效果)
正如我上面提到的,"卷积
" 和 "相关
" 这两种运算符本质上是相同的。实际上,用户经常说卷积,而他们真正想表达的是相关。而且相关实际上是更容易理解的方法。对于围绕中心 "原点" 对称的内核(这种情况非常典型),这两种方法实际上是相同的。只有当您使用非对称或不均匀的内核时,这种差异才会显现出来。例如,这里我使用 "L" 形 "平面" 内核与我们的 "单个像素" 图像进行比较。
如您所见,"卷积
" 将中心处的单个像素扩展为围绕它形成 "L" 形状。即使原点本身不是 "邻域" 的一部分。现在让我们重复此示例,但改用 "相关
"。如您所见,"相关
" 也扩展了单个像素,形成了 "L" 形状,但它是一个 "旋转" 的 "L" 形状。这本质上是这两种方法之间的唯一区别。"相关
" 方法按 "原样" 应用内核,这会导致单个像素扩展为 "旋转" 的形式。另一方面,"卷积
" 实际上使用内核的 180 度 "旋转" 形式,以便每个像素都被扩展为相同的非旋转形状。如果您想查看一些关于 "卷积
" 的工作原理的精彩示例,我建议您也查看 EECE \ CS 253 图像处理,第 7 课,空间卷积。第 22 页的图表实际上将 "反射" 内核应用于单个像素,就像我在上面所做的那样。这种旋转差异可能看起来并不大,但这意味着在数学方面,卷积操作(用星号 ( '
*
' ) 符号表示)是 交换的,也就是说,如果将内核和图像都视为一个值的数组(或两个图像),那么 F * G == G * F
。这也意味着卷积是 结合的,也就是说 ( F * G ) * H == F * ( G * H )
。有关这方面的更多信息,请参阅 卷积属性,维基百科。"相关
" 操作既不是 交换的,也不是 结合的。尽管它与之密切相关(通过内核的旋转)。基本上,"卷积
" 更像是数学上的 "乘法",而 "相关
" 则不是。所有这些麻烦的例外情况是,当所使用的内核在旋转 180 度后是相同的。也就是说,内核关于 "原点" 是对称的。在这种特殊情况下,这两种操作都会生成等效的结果。令人困惑的是,大多数用于卷积的内核(如高斯模糊、拉普拉斯算子等)是对称的,在这种情况下,您实际上是在进行卷积还是相关并不重要。因此,人们对这些含义变得放松和模糊。只有当它们不对称时,例如在 形状搜索(见下文)的情况下,或者使用方向内核(如 索贝尔)时,这种差异才会变得很重要。 相关和形状搜索
"相关
" 方法的实际用途(按 "原样" 应用内核邻域,不进行旋转)是一种古老但简单的方法,用于定位与提供的内核中找到的形状大致匹配的形状对象。例如,如果我们要使用 "相关
" 和 "L" 形内核来尝试搜索我们使用卷积方法示例创建的图像,我们将得到...
|
附注:请注意,上面的内核图像中的 "黑色" 区域表示值为零。此内核中没有负值,只有正值代表要匹配的形状。 |
相关
" 方法在内核 "原点" 与图像中相同形状完全匹配的位置产生了最大亮度。但它也会产生较低的亮度结果,在这种情况下,您只会得到形状的局部匹配。匹配的形状越多,像素就越亮。但是我要提醒您,虽然 "相关
" 在这种情况下成功了,但它并不是真正很好的方法。例如,它可以在亮度非常高的区域生成大量的错误匹配。可以通过对不应与图像的黑暗背景匹配的区域使用负值来缓解此问题。也就是说,不匹配背景的区域应该使生成的像素亮度降低。
|
附注:为了使内核图像更清晰,我生成了内核图像,以便正值(前景)为白色,负值(背景)为黑色,零值(不关心)为透明。但是,实际上使用的内核是完全定义的,它以数字形式表示,其 "邻域" 是一个完整的矩形。 |
^
"。这很重要,因为它将分别对内核中的正值和负值进行归一化。也就是说,您希望与背景像素一样地搜索前景像素。这意味着您可以通过使用 IM 的 HDRI 版本 或适当使用 输出偏差(见上文)来搜索给定形状的正匹配和负匹配。例如,这里我将 "L" 形搜索应用于包含正 "L" 形和负 "L" 形的测试图像。(显示的图像已放大)
|
50%
”缩放因子,这样不匹配的像素就是黑色,而完美匹配的像素就是白色。一旦你拥有一个“相关
”匹配图像,你需要尝试找到匹配的“峰值”。这可以使用另一个相关来完成,但并不总是很有效。更好的方法是使用更精确的模式匹配方法“命中与不命中
”形态学,以及为此目的创建的特殊“峰值
”。这将找到任何仅被更暗颜色像素包围的单个像素。其他“峰值
”内核可用于查找“更松散”的匹配。
在这里,你可以轻松找到形状最佳匹配的位置,尽管匹配程度已经丢失。你可能想查看比较和子图像搜索的“峰值查找”部分。但也要查看 Fred Weinhaus 的脚本“maxima
”。将来:使用快速傅立叶变换的归一化互相关,用于生成具有非常大图像(源图像和子图像)的快速图像相关。 相关与命中与不命中形态学
如果你将我表示的内核图像与命中与不命中形态学方法使用的内核进行比较,你会发现它们实际上代表的是同一件事。'命中与不命中 ' |
'相关 ' |
|
---|---|---|
前景 | 值为“1.0 ” |
值为“1.0 ”(归一化前) |
不关心 | 值为“Nan ”或“0.5 ” |
值为“Nan ”或“0.0 ” |
背景 | 值为“0.0 ” |
值为“-1.0 ”(归一化前) |
结果 | 从背景的最大值中减去前景的最小值。因此,只有完全匹配才会产生正结果,阈值处理将产生二进制匹配图像。 | 生成图像与形状匹配程度的范围。只要整体模式存在,一些背景像素的值可能大于前景像素的值。可能难以定位特定的“匹配”峰值。你还可以找到负匹配。 |
命中与不命中
”只会找到具有明确前景与背景差异的完全匹配。因此,它对噪声和近似匹配的容忍度远低于“相关
”。另一方面,'相关
'可以使用线性图像处理来执行,更具体地说,可以使用快速傅立叶变换。这可以使使用更大模式和内核的模式匹配速度更快,尤其是在涉及多个模式时,为你节省将图像和模式转换为频域的成本。它也适用于实际图像,尽管可能还需要一些预处理和使用HDRI。使用哪种方法取决于你,以及你想要的结果。仅完全匹配,或具有更多错误的近似匹配,以及更快速算法的可能使用。请注意,对于在较大图像中查找较小的彩色图像的完全匹配,程序“magick compare
”的子图像定位功能将提供比“命中与不命中
”或“相关
”方法更好的方法。这是因为它使用“颜色向量差异的最小二乘”进行子图像匹配,这可以为匹配结果提供更好的指标。但是它同样缓慢,尤其是对于大型图像。邻居计数
卷积可以用于的一个更不寻常的事情称为邻居计数。也就是说,计算图像中每个像素点周围特定区域中存在的像素数量。计数邻居
基本上,通过使用非常简单的卷积内核,你可以创建一个包含二进制图像中特定点周围邻居数量计数的图像。通过卷积大小为“1.5
”的环形内核,你可以获得邻居计数。这里是对小区域中每个像素的邻居进行计数,并显示前后单个像素的放大图(使用放大图像脚本生成)...如你所见,所有像素的灰度级都显示了它们有多少邻居,包括边缘上的任何虚拟像素邻居。如果你想将当前像素包含在计数中,可以使用方形内核。通过适当的转换(包括级别调整)并使用PbmPlus 文件格式,你可以将上述灰度级转换为实际数字,如果你需要的话。如果你想排除实际形状内部的像素,你可以使用一个中心像素为强负数的内核,然后钳位任何负结果(如果你使用IM 的 HDRI 版本)。生成具有围绕大型负中心周围的正 1 的这种内核的一种简单方法是对标准离散拉普拉斯内核进行负缩放。
magick area.gif -define convolve:scale=-1\! \ -morphology Convolve Laplacian:0 -clamp neigh_edge.gif |
生命游戏
1970 年,英国数学家约翰·霍顿·康威在《科学美国人》杂志上发表了一个特殊的模拟,它变得非常流行。现在它被称为康威的生命游戏。它基于一个点网格,每个点要么“活着”,要么“死了”。然后,在下一代中,哪些“细胞”被归类为“活着”或“死了”,取决于一组非常简单的规则,这些规则纯粹基于它们周围的活邻居细胞的数量。- 邻域是围绕每个“细胞”的 8 个像素。
- 如果一个“活”细胞有 2 或 3 个邻居,它将继续存活。
- 如果一个“死”细胞正好有 3 个邻居,它将“活”起来(出生)。
- 否则,细胞将变为或保持“死亡”。
这将得到每个像素周围 8 个邻居(是否为“白色”)的计数,加上如果中心像素为“活”或“白色”,则值为 10。因此,此内核的值将为死像素的“
'3: 1, 1, 1 1, 10, 1 1, 1, 1'
0
”到“8
”,或活像素的“10
”到“18
”。如果我们将此内核按值 20 缩放(实际上按“0.05
”缩放以生成渐变,见下文),你将生成一个具有 21 种可能的灰度级的图像。也就是说,你将获得一个“黑色”值以表示“0
”灰度级,以及一个白色值以表示“21
”灰度级,但内核实际上无法生成这种值。现在,我们可以将“生命游戏”规则编码到一个颜色查找表图像中,以便将上述内核生成的邻居计数“灰度级”魔术般地转换为根据“生命规则”的适当“生死”结果。
magick -size 21x1 xc:black -fill white \ -draw 'point 3,0 point 12,0 point 13,0' \ life_clut.gif enlarge_image -25.3 -ml 'Life Rules' life_clut.gif life_clut_enlarged.png |
magick -size 15x15 xc:black -fill white \ -draw 'line 3,2 3,4 line 10,10 12,10 point 10,11 point 11,12' \ life_gen_000.gif magick life_gen_000.gif -define convolve:scale=0.05 \ -morphology Convolve '3:1,1,1 1,10,1 1,1,1' \ life_clut.gif -interpolate integer -clut \ life_gen_001.gif magick life_gen_001.gif -define convolve:scale=0.05 \ -morphology Convolve '3:1,1,1 1,10,1 1,1,1' \ life_clut.gif -interpolate integer -clut \ life_gen_002.gif magick life_gen_002.gif -define convolve:scale=0.05 \ -morphology Convolve '3:1,1,1 1,10,1 1,1,1' \ life_clut.gif -interpolate integer -clut \ life_gen_003.gif magick life_gen_003.gif -define convolve:scale=0.05 \ -morphology Convolve '3:1,1,1 1,10,1 1,1,1' \ life_clut.gif -interpolate integer -clut \ life_gen_004.gif |
|
这只是 IM 可以处理的各种“元胞自动机”的一个例子。当然,还有许多更快专门用于“生命”和“元胞自动机”的程序,它们通常做的事情完全相同,但我希望展示 IM 足够灵活,也能做到这一点。由于结果是简单的二进制图像,你还可以使用 IM 的 形态学 方法,例如 命中和错失模式搜索 或 互相关 来搜索特定的生命模式,这使得使用 IM 进行生命研究更实用,尽管速度很慢。