ImageMagick 示例 --
蒙版

索引
ImageMagick 示例前言和索引
Alpha(遮罩)通道
使用蒙版与图像
特殊图像蒙版
区域和区域子图像
背景移除
填充孔洞 (正在建设中)
在这些示例中,我们着眼于透明度的特殊处理,透明度通道,使用蒙版,以及最终移除不需要的背景或其他元素,例如标志、文本、垃圾信息。

Alpha 通道

图像的透明度(alpha)通道是完全可选的,通常需要与普通“颜色”通道分离的特殊处理。请参见上文的图像颜色空间。透明度通道的存在也会影响各种操作符如何处理其他颜色通道,通常是因为完全透明的颜色通常应该被操作完全忽略。如果不是这种情况,图像周围会出现“黑色光晕”,例如在 IM v6 的早期 IM 错误中出现的情况。例如,调整大小光晕错误模糊与透明度错误。更糟糕的是,此通道有时也被称为图像的“透明度”或“不透明度”通道,甚至被称为图像的“蒙版”。然而,所有这些都指的是图像的相同特殊第四通道。 [IM 输出]为了解释差异,我们需要一个正在工作的示例图像,为此,我将使用“月牙”图像的 PNG 图像(来自复制不透明度合成示例)。现在,如您所见,此图像有很多区域是完全透明的。不仅如此,我还需要使用“PNG”图像格式保存图像,它是少数几个正确理解和处理透明和半透明颜色的图像格式之一。
我可以通过将图像叠加在 IM 内置的棋盘格模式上,使用Alpha 合成来演示这种透明度。

    magick composite -compose Dst_Over -tile pattern:checkerboard \
              moon.png  moon_background.jpg
[IM Output]

内部 Alpha 通道

现在,在内部,IM v7 将透明度信息存储在一个“alpha”通道中,该通道与颜色通道一样,只是一个普通的灰度图像,其值从白色(完全透明或清晰)到黑色(完全不透明)。它有点像您观察原始图像轮廓时会得到的效果。低级操作符,例如“-level”和“-threshold”,将数据处理为 alpha。如果您不确定,请查看官方选项参考
创建日期:2003 年 12 月 10 日(最初为“通道”)
更新日期:2018 年 10 月 2 日
作者:Anthony Thyssen,<Anthony.Thyssen@gmail.com>
示例生成于:[版本图像]
URL:https://imagemagick.org.cn/Usage/masking/
这是一种非常古老的方法,用于从图像中提取“alpha”透明度值。它将透明度通道保存为“alpha”图像文件格式,并且需要两个单独的步骤和命令来定义正确的图像文件格式。


magick moon.png alpha:moon.matte
magick MIFF:moon.alpha moon_matte2.png # You can join those two steps in a pipeline as well... magick moon.png alpha:- | magick - moon_matte3.png
[IM Output]
此提取图像“alpha”的技术在 IM v5 仍在使用时很常见。基本上,这是获取图像透明度的唯一方法。现在它很少使用。

控制图像透明度

有两个操作符可以让您对内存中图像的透明度通道进行低级控制。较新的操作符“-alpha”方法现在是推荐的控制方法,尽管许多 IM 示例仍然显示和使用旧的操作符“-alpha”。图像不仅可以具有 alpha 通道数据,而且还具有一个“开关”,该开关定义通道数据是否可见或有效。这意味着图像在 alpha 通道方面可以有三种状态。
开关    通道数据
 alpha off  没有 alpha 数据(没有分配内存)
 alpha off  存在旧的 alpha 数据(但未使用)
 alpha on  当前正在使用的 alpha 数据
需要记住这一点,因为各种方法的行为取决于图像处于上述三种状态中的哪一种。如果“开关”关闭,操作符将不会触碰 alpha 数据,因为它可能根本不存在。在这种情况下,旧的 alpha 仍然可能存在,未修改,因此已过时。正如您将看到的那样,这实际上在某些情况下很有用。但是请注意,某些操作符可能会出于某种原因自动打开或关闭 alpha 开关。例如,“-compose CopyOpacity -composite”将始终在生成的图像中打开 alpha 通道,因为它是操作符的工作,将数据复制到 alpha 通道。因此,它必须存在于最终结果中。但是,它在输入数据中的存在可能会产生其他后果。有关更多详细信息,请参阅复制不透明度合成方法。类似地,使用颜色“None”创建画布也会自动创建和启用透明度通道,以确保空白图像确实是透明的。另一方面,使用某些其他颜色名称创建画布通常不会创建任何透明度通道,因为默认情况下图像是不透明的。
以下是各种“-alpha”方法及其对图像及其透明度的影响示例。

Alpha Off"-alpha off"

这只是一个简单的图像开关,它会关闭透明度对图像的任何影响。它实际上不会删除或破坏附加到图像的 alpha 通道,它只是关闭该通道对图像的任何影响。同样,在关闭后,没有操作符会影响附加的 alpha 通道。例如,让我们使用“月牙”图像(来自复制不透明度合成示例),并简单地关闭图像 alpha 通道。

  magick moon.png  -alpha off     alpha_off.png
[IM Output] ==> [IM Output]
请注意,当透明度关闭时,月球形状完全消失了,但这实际上很少见。基本上,即使是“透明”区域也具有颜色,只是通常不可见,在这种情况下,隐藏的颜色是用于创建月球图像的的分形画布图像。这种隐藏的颜色可以是任何东西,从简单的GIF 透明度颜色(GIF 格式使用该颜色在其颜色表中表示透明度)到在图像创建过程中留下的垃圾颜色,如上所述。更典型的是,对于任何完全透明的像素,透明度颜色只是纯黑色。请注意,靠近边缘的像素可能是半透明的,因此仍然具有仅部分可见的有效颜色。上面的“-alpha Off”操作将简单地“停用”或“关闭”通道。透明度数据本身尚未从内存中存储的图像数据中清除或删除。它仍然存在,只是暂时不可用。但是……如果图像在透明度数据关闭时保存,则没有透明度数据将保存到图像文件格式中。因此,关闭的 alpha 数据不存在于保存的图像副本中,即使它存在(只是关闭)于内存版本中。此外,由于许多文件格式不允许透明度(例如 JPEG),因此这些文件格式在保存图像时会自动执行与“-alpha Off”等效的操作(而实际上并没有这样做)。通常,这会导致所有透明区域在保存为 JPEG 图像时通常变为黑色。有关在保存到 JPEG 文件格式之前移除透明度的正确方法,请参见下面的Alpha Remove - 移除透明度。“+alpha”操作符是一个更旧的命令,与“-alpha Off”完全相同。也就是说,它只是关闭了透明度通道。请注意,通常需要关闭 alpha,然后才能使用灰度蒙版图像与复制不透明度 Alpha 合成方法一起使用。如果您不这样做,合成操作符将复制启用的透明度(不透明度通道),而不是使用预期的灰度颜色。

Alpha Set"-alpha set"

'Set' alpha 方法与旧的“-alpha on”选项相同。这确保图像具有“透明度”或 alpha 通道,但如果它不存在或已关闭,则将其初始化为完全不透明(请参见下面的Alpha Opaque 方法)。但是,如果图像已经存在并启用了 alpha 通道,则它将不会执行任何操作。换句话说,此操作符确保存在 alpha 通道,而不会修改图像在内存中的外观。因此,它本身不会显示对图像的任何更改,但与其他操作符组合使用时会产生实际效果。因此,如果您使用Alpha Off关闭 alpha 通道,然后使用Alpha Set再次启用它,则图像将具有 alpha 通道,但它将是完全不透明的,就像请求“Set”操作时图像的外观一样。

  magick moon.png  -alpha off    -alpha set    alpha_set.png
[IM Output]
如果应用于具有启用 alpha 通道的图像,则不会进行任何更改。

  magick moon.png  -alpha set    alpha_noset.png
[IM Output]
简而言之,此操作符在应用时不应更改图像的外观。它仅确保 alpha 通道设置,使得图像保持原样。这通常用于从未知图像文件格式或输入源读取图像后,这些格式或来源可能存在或不存在 alpha 通道。然后,此操作符将确保图像具有 alpha 通道(对于 JPEG 等图像格式),但保留任何已启用且存在的 alpha 通道(例如,对于 GIF 或 PNG 格式)。这是在将图像读入内存后或更重要的是,在图像处理完毕后并希望重新启用干净的 alpha 通道时,确保图像具有 alpha 通道的推荐方法。

启用 Alpha

-alpha On”与之前看到的 禁用 Alpha 方法正好相反。通常,这对于您想要的用途来说过于简单,因此应极少使用。在几乎所有情况下,您都应该使用“-alpha Set”。基本上,“On”方法只是翻转开关,以便图像透明度数据再次可见。任何现有的透明度数据都不会被修改,因此,如果内存中的图像仍然保留一些旧的 alpha 通道数据,那么这些数据将突然再次可见。例如,这里我们将透明度数据设置为“Off”,然后立即将其恢复为“On”,重新生成原始图像。

  magick moon.png  -alpha off  -alpha on    alpha_on.png
[IM Output]
但是,如果图像还没有任何之前的 alpha 数据,它将将其初始化为完全不透明。这在逻辑上是合理的。因此,对于刚读入内存的新图像,它等效于 Alpha Set,但不能用于此目的。Alpha On 唯一应该使用的时间是,当您之前有目的地关闭 alpha,现在想要恢复该数据时。例如,关闭然后打开 alpha 通道可用于在应用某些非常具体的操作符(如“-shade”)之前保留 alpha 通道数据。有关此特殊用法的示例,请参见 阴影形状图像

激活/停用 Alpha

分别启用和禁用 alpha 通道,并具有持久性。这类似于 Imagemagick 6 中的开/关。在 Imagemagick 7 中,-alpha off 将永久删除 alpha 通道,因此 -alpha on 将不会重新启用它。

离散 Alpha

独立处理 alpha 通道(不进行混合)。

Alpha 不透明

此方法不仅确保 alpha 通道处于“活动”状态,而且还确保它完全不透明,无论图像是否已激活/打开或停用/关闭透明度。例如……


  magick moon.png  -alpha opaque    alpha_opaque.png
[IM Output]
在 IM 的旧版本中,这等效于使用“-alpha off”关闭 alpha 通道,然后使用“-alpha on”打开它,同时将其重置为不透明。

  magick moon.png  -alpha off -alpha on  alpha_opaque_matte.png
[IM Output]
此操作后,图像的原始“形状”将无法恢复,因为原始 alpha 通道数据已被覆盖。当然,这也等效于使用“-alpha off -alpha set”,但您也可以在这种情况下使用“-alpha opaque”。

Alpha 透明

类似地,这确保 alpha 通道处于“活动”状态,但也完全透明。

  magick moon.png  -alpha transparent    alpha_transparent.png
[IM Output]
图像的颜色数据仍然存在,因此,之后关闭透明度将再次显示图像现有的颜色。

  magick moon.png  -alpha transparent  -alpha off  alpha_transparent_off.png
[IM Output]
当然,图像的原始“形状”实际上已被破坏,因此在此操作之后无法恢复。在 透明画布 中介绍了其他使图像完全透明的方法。

提取 Alpha

Extract”方法将简单地复制图像的“alpha”蒙版作为灰度通道蒙版。

  magick moon.png  -alpha extract    alpha_extract.png
[IM Output] ==> [IM Output]
请注意,完全不透明为白色,而完全透明为纯黑色。由于图像沿边缘包含一些半透明像素(用于反锯齿,使图像形状更平滑),因此此图像不是纯黑白色,而是在边缘周围也包含一些灰色的像素。如果您的 ImageMagick 是旧版本的 IMv7,则这是一种(近似)等效的技术,使用通道提取。

  magick moon.png  -channel a -separate +channel -negate alpha_extract.png
Extract”方法还会将 alpha 设置为“Off”,但它不会被清除,因此将 alpha 通道恢复为“On”将重新创建原始图像的形状蒙版。

  magick moon.png  -alpha extract -alpha on   alpha_extract_on.png
[IM Output]
请注意,所有原始颜色都将被替换为白色,边缘周围有各种深浅的灰色。如果我们使用白色背景删除透明度,就可以看到这一点(请参见下面的 Alpha Remove 方法)。

  magick alpha_extract_on.png -background white -alpha remove alpha_edge.png
[IM Output]
这些“灰色”像素实际上在 从反锯齿形状生成边缘轮廓 中得到了很好的利用,用于从图像形状生成平滑的边缘或轮廓。保存 alpha 通道的这种副作用,在使用 阴影操作符 时具有特别的优势,该操作符不理解或使用图像的 alpha 通道。请参见子部分 蒙版阴影形状

复制 Alpha

Copy”方法是“Extract”的逆运算,本质上是对自身执行 CopyOpacity。也就是说,它将把灰度图像(无论其 alpha 通道是否已启用)转换为形状蒙版图像。

  magick alpha_extract.png  -alpha copy   alpha_copy.png
[IM Output] ==> [IM Output]
图像是否存在 alpha 通道并不重要,它只根据图像灰度值创建图像透明度。创建形状蒙版后,您可以使用各种 颜色着色Duff-Porter alpha 混合方法对其进行着色。有关使用形状蒙版的示例,请参见 蒙版作为彩色形状

Alpha 形状

为了更方便地使用灰度图像,“Shape”方法不仅创建形状蒙版(如 Alpha Extract 所示),而且还会使用当前背景颜色对其进行着色。

  magick alpha_extract.png -background Yellow -alpha shape   alpha_shape.png
[IM Output] ==> [IM Output]
这意味着您可以通过对图像进行整形,然后将其扁平化到不同的背景颜色上,来快速对灰度蒙版进行着色。

  magick alpha_extract.png -background Yellow -alpha shape \
                            -background Blue   -alpha remove alpha_colormask.png
[IM Output]
背景实际上不是此“形状”着色操作的正确颜色。它应该使用“填充”颜色来设置形状的前景颜色。因此,应该使用哪种颜色可能会发生变化。背景仅由于访问当前填充颜色的内部困难而使用。此更改可能会在 IMv7 中发生。
当然,更快速、更有效的方法是使用更专业的 颜色级别调整 来将黑白色图像直接映射到特定颜色。这将避免需要启用甚至修改现有图像的透明度通道。

  magick alpha_extract.png  +level-colors Blue,Yellow   level_color.png
[IM Output]
以上将使用线性颜色空间映射颜色,可能需要在某个时刻转换为 sRGB 以获得更视觉上正确的颜色渐变。

删除 Alpha

-alpha Remove”方法(添加到 IMv7.7.5 中)旨在使用当前“-background”从图像中删除透明度。

  magick moon.png  -background tan  -alpha remove  alpha_remove.png
[IM Output]
请注意,虽然透明度被“删除”了,但 alpha 通道将保持开启状态,但现在将完全不透明。如果您不再需要 alpha 通道,则可以使用 禁用 Alpha 来禁用它。此操作简单快速,并且无需任何额外的内存使用或与其他透明度删除技术相关的副作用。因此,这是删除图像透明度的首选方法。对于其他技术,或者如果您的 ImageMagick 版本早于 v6.7.5,请查看下面的更详细的讨论 从图像中删除透明度)。

Alpha 背景

从 IM v6.5.2-10 开始,提供了“Background”方法,它将完全透明像素的隐藏颜色设置为当前背景颜色。通常,这种颜色无关紧要,因为只有在 alpha 通道 关闭 时才能看到它。但是,完全透明像素的颜色保存在 PNG 图像文件格式中,对于大型图像,具有随机未知的完全透明颜色会显着影响其压缩处理。有关更多详细信息,请参见 具有更好压缩的 PNG 以及 IM 论坛讨论 消除 alpha 通道垃圾。请注意,没有应用颜色混合,只是直接将颜色分配给任何完全透明的颜色。但是,像素仍然保持完全透明,因此您不会看到图像有任何变化。
例如,这里我用它将所有完全透明的像素设置为“HotPink”。

  magick moon.png -background HotPink -alpha Background moon_hotpink.png
[IM Output]
如您所见,这并没有改变图像的实际外观。为了查看更改,我们现在将 关闭 alpha 通道。

  magick moon_hotpink.png -alpha off moon_hotpink_off.png
[IM Output]
这与 删除透明度 不同。
形状的边缘将使所有半透明像素不透明,从而产生一些强烈的锯齿(阶梯式)边缘效果。请注意,即使是通常仅不透明的 PNG24 格式,如果所有完全透明的颜色相同,它仍然可以保存布尔透明度。有关详细信息,请参见 PNG 子格式 中的示例。此替换颜色的过程实际上几乎等同于执行“-channel RGB -fill color -opaque None +channel”。请参见 直接颜色替换。请注意,许多其他图像处理操作符也将将任何完全透明的像素魔术化为完全透明的黑色(颜色“None”),因为这等效于数学零的颜色。以下是已知执行此操作的一些图像操作的摘要,但没有一个像使用此操作符那样直接或快速。

  magick moon.png \( +clone -alpha off \) \
                        -compose SrcIn   -composite   moon_black.png
  magick moon.png -channel RGBA  -blur 1x.000000001  moon_black.png
  magick moon.png -channel RGBA   -gaussian 1x0      moon_black.png
  magick moon.png -fuzz 0% -transparent none         moon_black.png
最后一种方法(请参见 模糊因子和透明颜色)特别有用,因为您不仅可以将所有透明颜色设置为完全透明黑色(“None”),还可以将所有接近完全透明的颜色(否则具有有效的但实际上不可见的颜色)设置为完全透明黑色,只需指定模糊因子即可。这将产生一些数据丢失,但可能会改善具有大量接近完全透明颜色的图像的压缩。通常,这些几乎完全透明的像素可能具有非常奇怪或错误的颜色,而此方法将允许您在它们导致其他问题之前删除这些奇怪的像素。

从图像中删除透明度

虽然 禁用 Alpha 只会翻转开关并关闭透明度通道,但如果您尝试将图像保存为不允许使用透明度的文件格式,也可以获得相同的效果。例如,保存为 JPEG……

  magick -size 70x60 xc:none -font Candice -pointsize 50 \
          -fill Black -annotate +10+45 'A' -channel RGBA  -blur 0x5 \
          -fill white -stroke black -draw "text 5,40 'A'"   a.png

  magick a.png  a.jpg
[IM Output] ==> [IM Output]
请记住 JPEG 文件格式 不保存 alpha(透明度)通道,因此它会直接关闭该通道。在这种情况下,透明部分将变成黑色(典型结果)。但是,根据图像源,透明区域也可能变成其他随机颜色或不合适的颜色。此外,在许多情况下,半透明像素可能呈现出非常奇怪的颜色,通常不可见,因为它们几乎完全透明。简单地关闭透明度将使这些像素像大拇指一样突出,使结果看起来比您预期的更糟糕。例如,请查看上面“A”的左上角边缘。无论哪种情况,简单地关闭透明度通常都不是我们想要的。最佳解决方案 是使用 Alpha Remove 方法快速简单地将透明度替换为底部的背景色...

  magick a.png   -background skyblue  -alpha remove -alpha off a_remove.jpg
[IM Output]
严格来说,在这种情况下不需要 Alpha Off,因为保存到 JPEG 会自动执行此操作。
去除透明度的另一种方法是,以某种方式生成一个新的“背景”或“画布”图像,并将您的图像 叠加 到该背景上,以替换透明度。最好同时保留原始图像的元数据,例如可能存在的配置文件、标签、标题和注释。生成此类画布的方法示例在 创建相同大小的图像画布 中。以下是一种方法...

  magick a.png \( +clone -alpha opaque -fill SkyBlue -colorize 100% \) \
          +swap -geometry +0+0 -compose Over -composite  \
          -alpha off  a_compose.jpg
[IM Output]
另一种更简单的方法是使用一个操作,该操作在内部为您创建一个“克隆的背景画布”,并在操作员执行的更大图像处理操作的一部分中生成它。最常用的方法是 扁平化 图像。该操作员经常用于此目的,以至于删除透明度的过程通常被错误地称为“扁平化”。例如...

  magick a.png   -background skyblue -flatten  -alpha off  a_flatten.jpg
[IM Output]
但是,这对于“mogrify”或多个图像的序列无效,主要是因为“-flatten”操作员实际上是为将多个图像合并为单个图像而设计的。另一种适用于多个图像的常用方法是为图像提供一个大小为零的 边框,并使用相应的“-bordercolor”。例如...

  magick a.png   -bordercolor skyblue -border 0  -alpha off  a_border.jpg
[IM Output]
其他与上述方法密切相关的图像处理操作符也可以从图像中删除透明度。这些包括:马赛克合并框架Extent 操作符也可以使用,并且允许您在删除透明度的同时扩展或裁剪图像,但前提是您知道最终图像的大小。您不必用纯色替换透明度。如果您使用 DIY 构图(如上所示),您可以使用任何图像作为替换背景。一个简单的示例是使用“composite”命令将图像“放置在”原始图像下方(使用 平铺)(使用 Dst_Over)。这种构图方法可以确保原始图像的元数据和大小得到保留。

  magick composite -compose Dst_Over -tile pattern:checkerboard \
                                               a.png  a_undertile.jpg
[IM Output]
上面提到的许多方法,要么会受到虚拟画布信息的影响,要么会破坏图像可能具有的任何虚拟画布信息,作为其处理的一部分。在涉及虚拟画布时,您可能需要更仔细地查看各个操作员的详细信息。在许多情况下,虚拟画布的影响对您的整体图像处理非常有用。

布尔 Alpha 透明度

对于某些图像文件格式,您不需要完全删除 alpha 通道,只需允许纯开/关或布尔透明度即可。索引(调色板)图像文件格式,例如 GIFPNG8,就是这种情况的典型代表。当前示例在 GIF 布尔透明度 中进行了查看,但最终应该移到这里。

轮廓或光晕透明度

有时您希望在包含透明度的图像周围添加轮廓。一种方法是使用 EdgeOut 形态学 快速获取原始图像的所有相邻像素,对它们进行着色,然后 在下面(DstOver)构图 它与原始图像。

  magick knight.png \( +clone \
             -channel A -morphology EdgeOut Diamond +channel \
             +level-colors red \
           \) -compose DstOver -composite    knight_outlined.png
[IM Output] ==> [IM Output]
这在从包含半透明边缘像素的 PNG 图像创建 GIF 格式图像时特别有用。它提供最少的背景色,但将图像的其余部分保持完全透明。有关此问题的更多信息,请参见 背景图案上的 GIF。另一种方法是在形状周围生成一个柔和的半透明光晕。为此,我们将 模糊 并重新着色图像,然后再次 在下面(DstOver)构图 它与原始图像。

    magick knight.png \(  +clone \
              -channel A  -blur 0x2.5 -level 0,50% +channel \
              +level-colors red \
            \) -compose DstOver  -composite    knight_halo.png
[IM Output]
这实际上类似于使用 柔和轮廓复合字体 效果,但使用的是形状图像而不是带注释的文本。

使用图像蒙版

蒙版图像

如前所示,有两种方法可以蒙版图像,以便使图像的一部分透明。您选择的方法取决于您的图像蒙版是灰度蒙版还是形状蒙版。

编辑图像蒙版

图像的蒙版是一个非常有用的东西。例如,我们可以通过修改原始图像的蒙版来非常轻松地擦除图像的部分。请记住,“-draw”操作符无法绘制任何内容,并且目前没有擦除选项。在这里,我们创建一个图像,然后通过提取和修改其蒙版,在将其恢复到原始图像之前。

  magick -size 100x100 xc:none   -stroke black  -fill steelblue \
          -strokewidth 1   -draw "circle 60,60 35,35" \
          -strokewidth 2   -draw "line 10,55 85,10"      drawn.png

  magick drawn.png -alpha extract  mask.png

  magick mask.png -fill black -draw "circle 40,80 60,60" mask_bite.png

  magick drawn.png mask_bite.png \
          -alpha Off -compose CopyOpacity -composite \
          drawn_bite.png
[IM Output] ==> [IM Output] ==> [IM Output] ==> [IM Output]
请记住,蒙版中的“黑色”是透明的,而白色是不透明的,因此我们只需要在不想显示的任何东西上绘制黑色即可。不要忘记上面“-alpha Off”操作,因为它对于确保灰度图像不包含不需要的透明通道至关重要。瞧,我们在原始图像中咬了一口。我们还可以重新添加我们删除的图像的一部分。例如,在这里我重新添加了从原始图像中删除的“咬”的一部分,方法是在蒙版上绘制白色区域。然后,使用 CopyOpacity 通道合成 将蒙版再次返回到原始图像。

  magick mask_bite.png -fill white \
          -draw "circle 50,70 60,60" \
          -draw "roundRectangle  78,5 98,25 5,5" \
          -alpha off  mask_bite2.png
  magick composite -compose CopyOpacity mask_bite2.png drawn.png drawn_bite2.png
[IM Output] ==> [IM Output] ==> [IM Output]
关于重新添加部分,需要提醒您一点。通常,ImageMagick 会将任何完全透明的颜色替换为黑色,这通常是因为这是操作符背后的数学运算方式。毕竟,它是完全透明的,因此它的颜色通常无关紧要。这意味着,如果我们使之前未绘制的图像的一部分不透明,那么它通常会是黑色,因为这是图像透明度下的颜色。但是,在上面的示例中,您会注意到 PNG 图像文件格式正确地保留了图像的原始(变为透明的)颜色。因此,重新添加部分的颜色保持为原始图像的“SteelBlue”颜色。如果将图像保存为其他文件格式或进一步修改,则不应依赖此行为。
以下是一种从图像中擦除部分的替代方法,但它不是提取和修改灰度蒙版,而是使用形状蒙版作为一种“擦除”工具,使用 DstOut 合成方法

  magick -size 100x100 xc:none -draw "circle 40,80 60,60" mask_shape.png

  magick drawn.png mask_shape.png -compose DstOut -composite drawn_bite3.png
[IM Output] - [IM Output] ==> [IM Output]
如您所见,有时形状蒙版更容易处理,因为您避免了提取和恢复 alpha 通道的需要。但是,Duff-Porter Alpha 合成方法(我正在使用的)永远不会允许您恢复已变为透明的颜色。使用这些方法,任何已变为透明(因此颜色未定义)的元素都将保持透明。实际上,使用 Alpha 合成方法 擦除图像的部分实际上会破坏完全透明像素的底层颜色。它不会保留它。毕竟,透明颜色实际上不是真正的颜色!

蒙版作为彩色形状

除了仅使用蒙版来添加或重新添加图像的透明度外,还可以以各种方式直接将蒙版与图像组合。例如,假设我们只想使用蒙版作为我们想要以各种颜色叠加在图像上的符号或形状。为此,我们需要一个蒙版,我将从一个特殊的“符号”字体中提取出来。

  magick -font WebDings -pointsize 24 label:Y \
          +trim +repage  -negate   heart_mask.gif
[IM Output]
请注意,我反转了标签图像以使其成为合适的蒙版图像,它由白色前景(不透明)在黑色背景(透明)上组成。从 IM v6.4.3-7 开始,将灰度蒙版转换为彩色形状的最简单方法是使用 Alpha Shape 操作符。这与 Alpha Copy 完全相同,但多了一个步骤来对最终形状进行着色。

  magick heart_mask.gif  -background Red -alpha Shape  heart_red.png
[IM Output]
请注意,使用“PNG”图像格式作为生成的形状图像,而不是 GIF,以避免 GIF 布尔透明度 方面的问题。
在此之前,最简单的解决方案是将 alpha 蒙版反转为遮罩 通道图像,然后使用 Combine 生成形状图像。

  magick heart_mask.gif -negate  \
          -background Gold  -channel A  -combine   heart_gold.png
[IM Output]
在这种情况下,形状蒙版的颜色由“-background”颜色定义,该颜色由 Combine 用于填充新图像的未定义通道。一种更老但更复杂的方法是使用“CopyOpacity”合成方法将图像的透明度设置为给定蒙版,然后使用 统一颜色着色 对生成的形状进行着色。这种方法有效,并且长期以来是最佳技术,但现在不再推荐。

  magick heart_mask.gif \( +clone \) -alpha off \
          -compose CopyOpacity  -composite \
          -fill HotPink  -colorize 100%    heart_hotpink.png
[IM Output]
现在您拥有一个“形状”图像,您只需简单地将图像叠加到我们想要的任何背景上,例如内置的玫瑰图像,使用多种 图像分层技术Alpha 合成方法

  magick rose: -page +2+2  heart_gold.png \
                 \( +clone -repage +7+29 \)  \
                 \( +clone -repage +52+14 \)  \
          -flatten       rose_with_love.gif
[IM Output]
如果我们希望所有符号都使用相同的颜色,这就可以了,但是如果我们希望使用多种颜色,则需要多个中间图像,这对于叠加大量具有多种不同颜色的符号来说是不切实际的。一种制作多色叠加的方法是在读取图像后立即重新着色形状图像。

  magick rose: \(  heart_gold.png           -repage +2+2   \) \
          \( +clone -fill Red     -colorize 100% -repage +7+29 \) \
          \( +clone -fill HotPink -colorize 100% -repage +52+14 \) \
          -flatten      rose_colored_love.gif
[IM Output]
请注意,我们只读取了一个形状图像,然后为每个要叠加的新的“层”重新着色该图像的 克隆。有关重新着色基本图像的更多示例,请参见有关 颜色修改 的整节内容。另请参见 绘制符号,了解在图像中标记特定位置的替代方法。以及 图钉映射分层示例,了解更自动化的分层技术。

数学合成

您可能并不想将蒙版叠加到某个背景上,而只对使用蒙版的白色或黑色部分本身对图像进行着色感兴趣。这相对简单,只需使用一些 数学 Alpha 合成方法 即可更改蒙版的颜色以匹配颜色、平铺或其他图像。例如,“Multiply”合成方法将用叠加图像替换白色区域(乘以值为 1),同时保持黑色区域(乘以值为 0)为黑色。“Screen”操作符与“Multiply”完全相同,但图像被反转,因此它实际上用黑色区域替换图像的黑色区域。例如,让我们使用上面更大的蒙版图像来叠加使用平铺图案生成的更大的图像。

  magick mask_bite.png -size 100x100   tile:tile_disks.jpg \
                        -compose Multiply  -composite   compose_multiply.png
  magick mask_bite.png -size 100x100   tile:tile_water.jpg  \
                        -compose Screen    -composite   compose_screen.png
[IM Output] ==> [IM Output] [IM Output]
Multiply” Alpha 合成方法对于替换文本图像的背景(例如:白色背景上的黑色文本)特别有用,例如从 Postscript 文档 生成的图像。

蒙版 Alpha 合成

使用三种图像形式的 蒙版 Alpha 合成 允许您使用相同的蒙版将两张图像直接合并在一起。

  magick -size 100x100   tile:tile_water.jpg  tile:tile_disks.jpg \
           mask_bite.png    -composite   compose_masked.png
[IM Output]
第一张图像将替换蒙版的黑色背景部分,而第二张图像将替换蒙版的白色前景部分。蒙版本身作为第三张图像给出。蒙版用于选择和混合两个不同的图像,以生成最终结果。它实际上非常类似于两张图像的映射 混合。请记住,最终图像的大小和元数据将来自上述操作(黑色部分)的第一个“背景”图像,因此如果想要反过来,请交换图像并 反转 蒙版。最后请记住,如果您使用的是“composite”命令而不是“convert”,则“覆盖”图像(白色部分)首先给出,其次是“背景”图像(黑色部分)。换句话说,对于该命令,前两个图像需要交换。

对齐两个蒙版图像

正在建设中
On aligning two masked images...

If your masks are pure boolean, you should have no problems however you
apply them.  However masks containing 'anti-aliased', 'gray', or
'semi-transparent' edging to make them 'smooth looking' can be serious
headache if you do not handle them properly and with care.

The rest of this discussion is on 'anti-aliased' masks.

Anti-Aliased Masks which join together come in two styles...

 * Ones which fit together like jigsaw puzzle pieces OR
   like a shaped peg into a shaped hole (shared boundary)

 * Masks that are ment to overlay a solid area (layered)

The latter is easy to handle and is the normal effect you get when you overlay
some colored shape over a fully-opaque image.  Essentially you would use
'over' composition to compose the shape.

The former 'jigsaw' masks however is harder.  Such masks are not meant to
either overlap, or underlap each other.  And yet if you try to join them
using the obvious and normal 'over' composition you will end up with a
semi-transparent join where 'anti-aliased edges' are merged.

Example of a bad 'jigsaw mask' join (over)

The correct way to join masks and shaped 'jigsaw' images is to use
Plus composition to 'add' the images together, with either a
black or fully-transparent background.

Example of a correct 'jigsaw mask' join (plus)


For another example of DIY image joining, using 'Dst-In', 'Dst-Out', and
'Plus' composition, see examples in...
  https://imagemagick.org.cn/Usage/compose/#dstin

I also go though this joining detail in the bug report of 3 image alpha
composition Composite Mask Bug
- Fixed.

For more on the difference between 'over' and 'plus' see 'Blend' (plus) vs 'Dissolve' (over)

Examples of correctly joining edge aligned pieces is shown in
3d Cubes - Affine and again in 3d Boxes - Perspective
and in Isometric Cube using Shears
  https://imagemagick.org.cn/Usage/warping/#sheared_cube

The Major problems in these examples is that the individual parts were NOT
generated using the same mask, but distorted to their final positions.
As such they do not quite fit together properly and joined together.

These examples need to be updated to use a 'Plus' composition method.  To
generate improved results, but even then they will still probably not be quite
'right' as the masks do not exactly 'fit' together.


生成正确边缘对齐的蒙版

The best idea is to use the same mask (negated) for BOTH pieces, rather than
attempting to draw the two masks separately. Otherwise you have the two masks
overlap, OR leave a gap, exactly as you have seen.

Correct methods of mask joining..

    * use mask to set transparency on one piece
      use negated mask to set transparency of other piece
      'Plus' the two pieces together.

    * Use mask to Add transparency to just one piece, then
      'Over' compose that piece over a complete image.

    * use a three image masked composition
      see https://imagemagick.org.cn/Usage/compose/#mask
      and https://imagemagick.org.cn/Usage/masking/#masked_compose
      Which uses the mask to select results from two different images.

Remember, 'Over' only needs the 'source' or 'overlay' image masked, the
background image should not have aligned semi-transparent edges.
But a 'plus' composition needs both images masked with and exact negative
mask of each other align the joined edge.

WARNING:  Draw does NOT currently allow you to generate two shapes that will
fit together properly without overlap!!!!

See Draw Fill Bounds for details.

I have not checked SVG to see if it has the same problem.


特殊图像蒙版

写入蒙版 - 保护像素不受更改

“写入”或“剪裁蒙版”是一个特殊的灰度图像,它被添加到大小相同的现有图像中。它定义了图像中要被归类为“不可变”或“不可写”的区域,这些区域受大多数图像处理操作符的影响。操作符“-mask”将一个外部图像链接到内存中的图像。操作符“+mask”的“加号”形式从图像中删除蒙版。例如,这里我使用“写入蒙版”来保护背景像素不被写入,同时旋转色调,将前景的红色玫瑰重新着色为蓝色玫瑰。

  magick rose: -mask rose_bg_mask.png \
          -modulate 110,100,33.3  +mask rose_blue.png
[IM Output] [IM Output] ==> [IM Output]
蒙版有点粗糙,但效果很好。请记住,“写入蒙版”用于指定要保护或保留的部分。请记住,在 IMv7 中...
操作符“-mask”定义一个“写入保护”蒙版
有关更高级的示例,请参阅 色度键蒙版,它更多地关于生成蒙版,而不是将其用作写入蒙版。写入或剪裁蒙版旨在在直接修改图像中的像素时工作。例如:否定、级别、颜色着色、调制、绘制、合成、形态学、卷积。对于生成新图像的操作符(调整大小、扭曲、扩展等),它将无法保留原始像素,因为蒙版将无法与新图像大小相对应。此类操作还将具有从图像中移除或取消设置“写入蒙版”的副作用。以下是一个示例...

  magick -size 70x70 xc:red  red_image.png
  magick -size 70x70 xc: -draw 'circle 35,35 30,5'  write_mask.png

  magick red_image.png  -mask write_mask.png \
          -fill blue -opaque red   +mask    masked_color_replace.png
[IM Output] [IM Output] ==> [IM Output]
请注意,蒙版和结果图像的边缘都是平滑的(抗锯齿),这是因为蒙版不仅仅是一个布尔蒙版,而是一个混合蒙版。“写入蒙版”是一个混合蒙版,因为蒙版中的“灰色”像素将通过存在的灰色程度,将新像素与旧图像值混合。这会产生非常平滑的边缘,并且还允许您在修改区域和未修改区域之间生成图像的渐变。但是,混合蒙版虽然适用于单个操作,但在用于多个操作时可能不太好,因为它的混合效果将被多次应用。这个问题在形态学循环操作中尤其普遍。但前提是您使用的是非布尔混合蒙版。如果出现问题,最好简单地对图像的副本执行所有操作,然后对原始图像使用 蒙版 Alpha 合成。建议谨慎。
这种蒙版的使用实际上正是 合成蒙版 的工作原理!但这仅在应用合成操作符的持续时间内有效。

  magick -size 70x70 xc:green  green_image.png

  magick red_image.png  green_image.png  write_mask.png \
          -composite    masked_composite.png
[IM Output] [IM Output] [IM Output] ==> [IM Output]
等效于(使用反转的蒙版)...

  magick write_mask.png  -negate -write MPR:mask +delete \
          red_image.png -mask MPR:mask \
          green_image.png  -composite  +mask  masked_composite_equiv.png
[IM Output]
也就是说,蒙版被反转,然后应用于第一个“目标”图像。然后将第二个图像合成到第一个图像上,只修改原始蒙版图像的“白色”区域。
三张图像“-composite”操作使用“写入”蒙版

在形态学中,写入蒙版通常用于生成操作的 条件或约束形态学 形式。IM 讨论论坛中讨论过一个这样的示例,清理文本周围的噪声,以限制膨胀的影响。注意:-crop 应该能够通过裁剪蒙版并将蒙版分配给新图像来保留单个图像的图像蒙版。但是,目前还没有做到。

剪裁蒙版和剪裁路径

此操作符的“-clip-mask”形式几乎与上述形式完全相同,但只提供布尔(全有或全无)类型的蒙版。因此,您无法获得“混合”或平滑的结果。例如...

  magick red_image.png  -clip-mask write_mask.png \
          -fill blue -opaque red   +clip-mask    clipped_modulate.png
[IM Output]
如您所见,结果是高度锯齿状的(带有阶梯状边缘),因为“-clip-mask”不像“-mask”那样产生混合结果。它的唯一优点是速度稍快(虽然快不了多少)。它最初是为了允许处理 TIFF 图像文件中的剪裁路径 而提供的,是一个非常旧的操作符(IMv5)。应该使用较新的“-mask”操作符。
在 IMv7 中,并排实现了“写入蒙版”和“剪裁蒙版”,尽管从技术上讲,它们执行的功能完全相同。因此,您可以同时应用这两个蒙版。

但是,不建议同时使用这两个蒙版,结果也不确定。此外,这种“布尔蒙版”形式已从 IMv7 中删除。

TIFF 图像的剪裁路径

“剪裁路径”是 TIFF 图像文件格式的一部分,它定义了一个矢量路径,用于定义 TIFF 图像内的“形状区域”。在 IM 中,操作符“-clip”和“-clip-path”读取此“剪裁路径”并将其转换为 剪裁蒙版(如上)。因此,它定义了一个“写入蒙版”,它将保护形状免遭修改。存储在 TIFF 图像中的剪裁路径被定义为 SVG 路径绘制,您可以使用以下命令从 TIFF 图像文件格式中提取剪裁路径...

  magick identify -format '%[8BIM:1999,2998:#1]' image_clip.tiff

人们经常遇到的最大问题是,将所有未剪裁的部分设置为透明。这需要您写入蒙版写入保护的区域!这是一个解决方案,它将整个图像转换为透明,然后打开“剪裁路径”,然后使现在可写的部分不透明(可见)。

  magick input.tiff -alpha transparent -clip -alpha opaque -strip out.tiff
操作符“+clip”还会关闭并移除剪裁蒙版(就像“+clip_mask”一样)。但是,对于任何图像文件格式,都没有文件格式将当前剪裁蒙版保存在图像中。(至少在 IMv7 中是如此)

读取蒙版 - 忽略像素输入

请注意,写入蒙版将限制写入图像的像素。但是,它不会限制在执行操作以创建要写入的新像素数据时,被“读取”的像素。这基本上意味着,如果您使用的是“区域效果”或“邻域”类型的操作符,例如 模糊形态学卷积,那么靠近边缘的“可写像素”可能会包含来自蒙版或不可写区域的颜色值。例如,这里我们保护前景玫瑰免遭写入,然后模糊图像。也就是说,我们只想强烈地模糊图像的背景部分。

  magick rose: -mask rose_fg_mask.png \
            -blur 0x8   +mask  rose_bg_blur_fail.png
[IM Output] [IM Output] ==> [IM Output]
结果是使用 **写入保护蒙版**,并非预期结果。
如您所见,尽管前景颜色受蒙版保护,但这些颜色仍然被用作模糊玫瑰周围背景的一部分。因此,靠近前景的模糊背景具有明显的红色色调或光晕。换句话说,前景颜色“泄漏”到周围的背景中。这通常不是人们在模糊图像背景(例如作为镜头聚焦效果的一部分)时想要做的。人们真正想要的是让模糊完全“忽略”前景像素,并且只允许背景的颜色作为模糊过程的一部分。也就是说,他们想阻止模糊“读取”前景像素。

IMv7 的读取蒙版解决方案

在 IMv7 中,使像素颜色像素不可读的唯一方法是使像素透明。透明像素默认没有颜色,因此“隐藏的颜色”不是模糊操作所做的计算的一部分。这给了我们一个“技巧”。使前景像素透明,应用模糊(或其他)操作,然后关闭透明度(在这种情况下,它实际上并不想要)。然后我们可以恢复图像的前景部分。如果听起来很复杂,那就是。以下是如何执行这些步骤,同时显示中间图像以试图使该技术清晰...

  magick rose: rose_bg_mask.png -alpha off \
          -compose CopyOpacity -composite   +compose  rose_bg_only.png
  magick rose_bg_only.png  -channel RGBA -blur 0x8   rose_bg_blurred.png
  magick rose_bg_blurred.png      -alpha off         rose_bg_blur_opaque.png
  magick rose_bg_blur_opaque.png \
                rose: rose_fg_mask.png -composite    rose_bg_blur_good.png
[IM Output] ==> [IM Output] ==> [IM Output] ==> [IM Output]
[IM Output] ==> [IM Output] ==> [IM Output] [IM Output] ==> [IM Output]
结果是去除了之前“泄漏”到模糊背景中的红色光晕效果。以下是对写入蒙版和读取蒙版版本的背景模糊的并排比较,因此您可以清楚地看到我们如何去除了前景颜色“泄漏”到背景中的情况。
[IM Output]
写入
[IM Output]
读取
蒙版方法差异
上面的示例假定原始图像没有 alpha 通道。如果图像还包含 alpha 通道,则需要单独分离和处理 alpha 通道,从而付出双倍的努力。一个例子是在“扭曲调整大小”讨论中展示的,该讨论想要忽略使用扭曲调整大小的图像周围的虚拟像素。有关详细信息,请参阅 正确调整大小(使用扭曲)。请注意,上面提到的内容也与模糊的 孔洞填充 技术非常相关。唯一的区别是,它正在保留背景免遭修改,而不是前景。这使得它稍微简单一些。真正的“读取蒙版”应该在 IMv7 中可用,以使上面只是简单地添加“读取蒙版”和可选的“写入蒙版”。

区域和区域子图像

区域是另一种方法,可以将操作的影响限制在图像的较小区域。例如,这里我将整个矩形区域着色为红色...

  magick koala.gif  -region 40x33+15+5 -fill red -colorize 50% \
          koala_region_red.gif
[IM Output]
您还可以使区域透明...

  magick koala.gif -alpha set \
          -region 40x33+15+5 -alpha transparent   koala_region_trans.gif
[IM Output]
请注意,我需要确保原始图像启用了 alpha 通道,然后才能使“区域图像”透明。如果这样做,IM 将使“区域图像”中的任何透明度变得透明,您将看不到任何变化。有关详细信息,请参阅下面的 区域工作原理
在 IM v6.6.9-5 之前,透明度保留是损坏的,区域中的透明度结果始终是“透明到原始”。因此,上面的结果将不包括任何透明像素,即使图像允许使用透明度也是如此。
使用区域的最大原因是,它不仅将效果限制在一个小区域内,它实际上会提取图像中的那个矩形区域,并将所有后续的简单操作应用到那个较小的区域。这意味着,如果您只修改非常大图像中的一个非常小的区域,例如进行红眼去除,那么您不仅可以将操作范围限制在该区域,还可以以更快的速度执行操作,并且提取的区域图像本身更小。总之...一个写入蒙版将在整个图像上执行操作,但会限制实际更改的像素,而区域则使用较小的提取子图像。请注意,没有任何东西可以阻止您将这两种方法一起使用。虽然如果您将裁剪蒙版应用于区域,则裁剪蒙版应与提取的区域图像的大小相匹配。

扭曲局部区域

由于“图像区域”实际上会提取原始图像的“小子图像”进行处理,因此您可以利用特殊的“局部化”圆形扭曲来扭曲原始图像的小区域。例如,这里有一行条纹。

  magick -size 600x70 xc:darkred \
          -fill white -draw 'roundrectangle 5,5  595,65 5,5' \
          -fill black -draw 'rectangle 5,25 595,31' \
          -fill red -draw 'rectangle 5,39 595,45' \
          lines.gif
[IM Output]
现在,通过定义区域,我们可以以不同的方式扭曲不同区域的线条。

  magick lines.gif \
          -region 90x70+10+0    -swirl  400  \
          -region 90x70+100+0   -swirl  400 \
          -region 90x70+190+0   -swirl -400 \
          -region 120x70+280+0  -implode 1.5 \
          -region 100x70+380+0  -implode -7  \
          -region 101x70+480+0  -wave 10x50 -crop 0x70+0+10\! \
          +region lines_regions.gif
[IM Output]
请注意,“-implode”和“-swirl”非常适合使用区域,因为它们具有扭曲图像的外边缘与定义区域之外的图像其余部分匹配的特性。也就是说,它们实际上是设计用于执行“局部图像扭曲”。请注意,当我使用波浪扭曲时,我必须裁剪生成的“波浪”图像的大小,使其再次适合于提取它的原始区域。请记住,区域仅在与简单图像处理运算符一起使用时才起作用。任何其他运算符,包括另一个“-region”运算符,都会在应用该运算符之前取消区域处理。

区域的工作原理及其问题

实际上,区域的工作方式是...
  • 根据“-region”运算符,从图像中提取较小的图像,使用简单的裁剪和区域参数。
  • 将任何后续的简单图像处理运算符应用于较小的图像。
  • 当看到非简单图像运算符时,或者找到另一个“-region”运算符时,或者使用“+region”关闭区域时,提取的区域将覆盖原始图像的提取位置。
区域的工作方式类似于使用图像堆栈运算符,虽然它在图像魔法出现之前就存在了很久。例如,它是 IM 版本 5 的一个组成部分。例如,如果您有这个区域操作...

  ... -region WxH+X+Y  ...simple-operators... +region ...
结果等效于(对于单个图像)...

  ... \( +clone -crop WxH+X+Y ...simple-operators... \
         \) -geometry +X+Y -composite   ...
或者(对于多个图像)...

  ... \( -clone 0--1 -crop WxH+X+Y ...simple-operators... \
         null: +insert \) -geometry +X+Y -layer composite ...
“区域图像”如何实际覆盖到“原始图像”上有点棘手...如果原始图像没有启用透明通道,则“区域图像”使用叠加合成进行合成。这意味着区域图像中的透明区域将变为透明,让您看到其背后的原始图像。例如,这里我故意在原始图像中关闭了透明度,但随后旋转区域,从而在角落产生一些透明区域。

  magick koala.gif -alpha off -region 30x30+10+10 \
          -alpha on -background None  -rotate 30  koala_region_rotate_1.gif
[IM Output]
如您所见,旋转区域(在“区域图像”中是透明的)的角落显示了“原始图像”。基本上,由于原始图像无法处理透明度,因此区域图像只是简单地叠加,具有透明的角落。如果原始图像包含活动的透明度,则修改后的区域图像中的透明度也可以修改,因此透明度只是“按原样复制”。

  magick koala.gif -alpha set  -region 30x30+10+10 \
          -background None  -rotate 30    koala_region_rotate_2.gif
[IM Output]
如您所见,IM 使用复制合成,因此区域图像中存在的任何透明度也将复制到原始图像。如果由于某种原因您希望原始图像保留其原始透明度,请先关闭 Alpha,然后在区域图像恢复后,再次打开它以恢复它。
放大或缩小的区域图像可能无法“放回”原处。例如,这里我调整(并着色)区域图像,使其变小...

  magick koala.gif  -region 30x30+10+10 \
          -resize 75% -fill red -colorize 30%  koala_region_shrink.gif
[IM Output]
如您所见,原始区域没有被恢复的区域图像覆盖。因此,那些没有被覆盖的部分没有被替换。同样,如果区域变大,原始图像的更多部分可能会被叠加的区域图像覆盖。

  magick koala.gif  -region 30x30+10+10 \
          -resize 150% -fill red -colorize 30%  koala_region_enlarge.gif
[IM Output]
在这两种情况下,区域的左上角偏移都不会移动。您不能只缩小区域图像并将其居中放置在区域区域内,也不能将区域图像放置在另一个位置。应谨慎操作以防止区域图像改变大小。虽然在某些特殊情况下,您仍然可以处理调整大小的区域。有关此示例,请查看上面的“波浪扭曲”示例。
与“mogrify”一样,您无法合并多个子图像,因为这需要使用非简单图像操作。但是,您可以使用“-draw”作为替代合成方法。有关示例,请参见Mogrify 中的 Alpha 合成.

在撰写本文时,“区域图像”仍然包含从原始图像中提取的裁剪虚拟画布偏移。这可能是,也可能不是一个错误,取决于您是否认为此信息有用。当前在恢复区域图像时未使用偏移量。

如果不需要偏移量(因为它会干扰扭曲等运算符),请在“-region”选项后跟一个“+repage”运算符以从区域图像中删除偏移量。删除或修改它不会影响其恢复到原始图像。


背景去除

图像处理中最常见的问题之一是从现有的完全不透明的图像中生成蒙版。此类图像通常从万维网上下载,或由程序生成,或以不提供任何透明度形式的图像格式生成。您也可能有一张某个物体的照片,并想去除背景。请记住,照片没有任何对透明度的理解,因此您需要自己去除不需要的部分。不幸的是,这个问题没有通用的解决方案,尤其是在您还想保留图像的半透明边缘时。因此,有数百种执行此任务的方法和变体,所有这些都取决于具体情况。与图像蒙版密切相关的是调整透明度以匹配要叠加的背景图像。这是作为保存到GIF 图像文件格式的一部分进行详细说明的,该格式仅允许布尔透明度。

屏蔽简单背景(填充)

当图像的背景是简单的单色固体颜色时,您通常可以通过执行替换图像中的颜色来生成简单的蒙版(和背景去除)。例如,这里是对具有纯色背景的图像进行直接填充蒙版。

  magick cyclops.png -alpha set -channel RGBA \
          -fuzz 1% -fill none -floodfill +0+0 white \
          cyclops_flood_1.png
[IM Output]
好吧,这没有奏效,因为右上角的填充“种子”点实际上没有到达图像的所有部分!!!解决这个问题的方法是稍微扩大图像,以便为填充提供一条路径到达图像的所有外边缘。但是,为此,您需要知道背景的颜色。

  magick cyclops.png -bordercolor white -border 1x1 \
          -alpha set -channel RGBA -fuzz 1% \
          -fill none -floodfill +0+0 white \
          -shave 1x1    cyclops_flood_2.png
[IM Output]
当然,我们没有指定一个很好的模糊因子。这样做的弊端是,您会在图像中的物体周围得到一个光晕。这是因为大多数图像沿边缘包含特殊像素,这会使图像看起来更平滑。但是,由于此图像相对于背景而言具有良好的黑色边框,因此可以使用很好的大模糊设置来很好地将图像与背景分离。

  magick cyclops.png -bordercolor white -border 1x1 \
          -alpha set -channel RGBA -fuzz 20% \
          -fill none -floodfill +0+0 white \
          -shave 1x1    cyclops_flood_3.png
[IM Output]
此技术存在一些问题。首先,它是图像的全部或无的蒙版,产生的边缘是锯齿状的、阶梯状的,而且看起来很糟糕。这对于有限的 GIF 图像文件格式来说很好,但如果您计划将该图像叠加到另一个背景上,则效果不佳。而且,要获得每个抗锯齿边缘像素非常非常困难。因此,如果我在黑色背景上叠加上面的图像,您可能会看到一些比正常更白的像素。

  magick cyclops_flood_3.png -background black -flatten \
          cyclops_flood_3_over.png
[IM Output]
此外,如果您确实设法使用足够高的模糊因子,您很可能遇到边缘像素很少或“泄漏”到图像中心的 问题。最后,像这样的直接填充不适用于非简单单色固体颜色的背景。

剪切带边框的物体

具有现有单色边框的图像对于这些背景去除方法具有明显的优势,因为边框提供了“内部”和“外部”图像之间的明确边界,这反过来允许使用更好的方法来指定背景图像的边界。也就是说,我们不是指定哪些颜色应该被视为背景,而是指定哪些颜色标记被掩盖的物体的边界。此外,由于边界颜色已知,因此只有两种特定颜色会在图像边缘混合在一起。也就是说,两种颜色都是已知的,因此边缘的透明度如何也非常好地已知。
正在建设中

移除已知背景

虽然将简单的背景去除到“布尔”蒙版相对简单,但当背景不那么简单时,事情就变得更复杂了。但是,如果背景本身是已知的。您可以使用它来帮助从其他图像中去除它。从 IM v6.3.4 开始,添加了一种特殊的Alpha 合成方法,称为“ChangeMask”,它允许直接从图像中去除已知的背景。例如,这里有一个未经修改的背景图像,以及一个被具有简单布尔(直接开启/关闭)透明度的 GIF 图像叠加的图像。通过使用“ChangeMask”,我们可以恢复那个原始叠加图像(如果它与背景非常不同)。

  magick overlay_figure.gif   overlay_bgnd.gif  \
            -compose ChangeMask  -composite  overlay_removed.png
[IM Output] [IM Output] ==> [IM Output]
基本上,它所做的是确定像素与一个图像到另一个图像的“差异”有多大,如果差异小于当前的模糊因子,则使该像素透明。只有完全透明的像素被添加到图像中,否则原始图像保持原样,透明度和所有内容。我们可以通过使用旧的“Difference”合成方法来生成比较差异图像来模拟该运算符...

  magick composite overlay_figure.gif   overlay_bgnd.gif  \
            -compose Difference     overlay_difference.png
[IM Output] ==> [IM Output] ==> [IM Output]
如您所见,差异图像是所有未改变部分的黑色,而改变部分的混合颜色。
通过分离和添加各个颜色通道,并进行阈值处理,我们可以得到两个图像之间任何通道的差异掩码。

  magick overlay_difference.png -channel RGB -separate +channel \
          -evaluate-sequence add  -threshold 0   overlay_mask.png
[IM Output]
使用此掩码,我们可以将任何未改变的区域设置为透明。

  magick overlay_figure.gif overlay_mask.png \
          -alpha off -compose CopyOpacity -composite \
          overlay_removed.png
[IM Output]
如您所见,'ChangeMask' 合成方法使此过程变得更加容易。但是,这仅提供了一种“开/关”类型的背景遮罩。它不允许模糊或抗锯齿边缘,也不允许结果透明羽化。

差值图像蒙版和羽化

上述方法可以扩展到具有锯齿边缘的图像以及非简单背景的图像。例如,这里我们有一个白色背景上的“独眼巨人”,我们想要提取它。然后,我们生成此图像与背景颜色(由左上角像素定义)之间的差异的灰度图像。

  magick cyclops.png \( +clone -fx 'p{0,0}' \) \
          -compose Difference  -composite  \
          -modulate 100,0  -alpha off  difference.png
[IM Output] [IM Output]
当然,此差异图像不能直接用作掩码。如果使用它,您实际上会使大部分图像半透明,而不是仅仅是周围的背景。但是,从这个差异图像中,可以创建许多不同的透明度掩码,具体取决于您要实现的目标。我们可以调整上述差异图像以生成所有与背景颜色略有不同的像素的掩码。

  magick difference.png  -threshold 0  boolean_mask.png
  magick cyclops.png  boolean_mask.png \
          -alpha off -compose CopyOpacity -composite \
          cyclops_boolean.png
[IM Output] [IM Output]
如您所见,布尔值“任何差异”会导致原始背景的大部分被包含在内。这是因为原始图像要么是“抗锯齿”的,要么是与背景略微模糊的(在本例中,这是由原始图像从 JPEG 格式图像调整大小引起的)。如果原始图像本身是布尔叠加(例如 GIF 格式图像叠加在背景上),则不会出现此问题。在这种情况下,您的结果将是完美的(参见上面的“ChangeMask”示例)。通过改变“-threshold”,您可以在布尔值(仅开/关)掩码中添加一个“模糊因子”,从而使掩码更接近图像本身。

  magick difference.png  -threshold 15%  threshold_mask.png
  magick cyclops.png  threshold_mask.png \
          -alpha Off -compose CopyOpacity -composite \
          cyclops_threshold.png
[IM Output] [IM Output]
请注意,独眼巨人图像的眼睛现在也被视为一个透明的!这个“孔”突出了这种技术的最大缺点。图像对象中接近背景颜色,或更糟的是,与背景完全匹配的部分,将被认为与背景相同。当然,这对于“有孔”对象的图像(如甜甜圈)可能是可取的,但对于我们的独眼巨人来说,一个“有孔的眼睛”绝对是一个错误。原始的“光晕”效果对于某些东西(例如文本)也可能是有益的,以便当您想要将它叠加在其他“噪声”背景上时,它更容易阅读。您可以通过在应用掩码之前稍微模糊掩码来增强光晕效果,以便由此产生的“光晕”随着距离的增加而减小。

  magick difference.png -bordercolor black -border 5 \
          -threshold 10%  -blur 0x3  halo_mask.png
  magick cyclops.png -bordercolor white -border 5   halo_mask.png \
          -alpha Off -compose CopyOpacity -composite  cyclops_halo.png
[IM Output] [IM Output]
可以使用更多 直方图调整 对掩码图像进行进一步修改,从而对特定图像的结果进行非常精确的控制。使用正确的参数,您可以调整周围的光晕,直到它实际上不存在,尽管通过这种方式完全消除它很困难。请参见下一节以了解改进的技术。在生成阈值掩码时,实际上建议使用少量的模糊(例如“-blur 0x0.707”或 2 的平方根),只是为了平滑掩码的边缘。当然,结果将不是布尔值,所以不要尝试将其保存到 GIF 格式的图像文件中。这也是 模糊羽化 的一个例子。但请注意,它与真正的 使用距离羽化形状 不完全相同。但是,在处理“位图”或“阈值掩码”(如我们在上面创建的掩码)时,少量模糊羽化,然后进行大量距离羽化,可能会产生最好的总体结果。

恢复半透明边缘

我们在上面使用的 差异遮罩 技术可以与之前的 洪泛填充遮罩 技术一起使用,以解决我们在更简单的遮罩技术中看到的大多数问题。在这里,我们研究了一种多层遮罩技术,但这种技术应该能够产生近乎理想的图像背景去除效果,同时保留边缘处的抗锯齿阴影像素。但是,这仅限于已知背景的图像,并且前景像素具有良好的对比度“边缘”。在本例中,我决定使用一些很难分离的东西,但它在边缘周围显示了比抗锯齿目的通常更多的阴影像素。一个具有阴影效果的形状。

  magick -size 70x60 xc:none -font Candice -pointsize 50 -stroke black \
          -fill black          -annotate +12+42 'A' -channel RGBA  -blur 0x3 \
          -fill tile_disks.jpg -annotate +10+40 'A' \
          tile_water.jpg  -compose DstOver -composite letter.png
[IM Output]
首先,我们需要生成一个差异图像,幸运的是,我们知道背景图像是什么。当然,对于纯色背景来说效果也一样,只要存在良好的对比度让我们生成两个掩码即可。基本上,通过使用差异图像,我们可以消除背景图像的任何影响,并从中生成我们将使用的掩码。

  magick letter.png  tile_water.jpg \
          -compose Difference -composite \
          -modulate 100,0 -channel B -evaluate set 0 \
          -alpha Off  diff_mask.png
[IM Output]
请注意,这次我稍微处理了灰度差异图像,将其限制为红色和绿色通道,同时清除蓝色通道,生成一个黑色和黄色的差异图像。这很棘手,因为它释放了“蓝色”通道,允许生成一个干净的洪泛填充掩码,独立于差异图像本身。从技术上讲,我也可以清除绿色通道,这样我就可以用它来生成第二个掩码。但让我们不要过早兴奋。现在我们需要两个掩码:一个外部掩码,定义所有肯定会透明的区域;以及一个定义图像中对象内部的掩码,而不会生成任何不需要的“孔”。因此,让我们使用多个不同的模糊因子从外部向内洪泛填充图像,以便我们可以选择将要使用的两个内部和外部掩码。

  for fuzz in 01 03 06   28 32 34; do \
    magick diff_mask.png -fill blue -fuzz $fuzz% \
            -bordercolor black -border 1x1 -floodfill +0+0 black \
            -shave 1x1 diff_mask_$fuzz.png; \
  done
[IM Output]
-fuzz 1%
[IM Output]
-fuzz 3%
[IM Output]
-fuzz 6%
== [IM Output]
-fuzz 28%
[IM Output]
-fuzz 32%
[IM Output]
-fuzz 34%
以上图像中的蓝色区域是被遮罩的区域。请记住,我们为此目的清除了蓝色通道。第一个掩码应该遮罩图像中我们肯定要完全透明的区域。也就是说,我们预期在最终图像中完全透明的部分。掩码内部区域应该仍然包含图像的大部分黑色光晕阴影。在本例中,图像本身与背景的其余部分之间存在很多相互作用,因此我选择了一个 '1%' 的 模糊因子,它仍然包含图像周围的大片区域。在更典型的非阴影情况下,此区域甚至可以更小,低至非百分比值,例如 5 或 10。第二个掩码应该具有足够大的“模糊”,以便吞噬所有存在的半透明像素。也就是说,一直到图像的边界,最好是实际上进入图像边界,而不会完全去除边界,或“泄漏”到图像本身(参见上面的最后一张图像)。此掩码的反面实际上将代表最终图像中所有完全不透明(因此代表内部)的像素。此选择可能很困难,可能需要很多尝试才能找出要使用的最佳值。对于此图像,可以毫无问题地选择一个非常高的模糊 '32%'。基本上,您希望尝试将其提升到足以使最终图像不包含任何原始“背景”像素,但同时又不让掩码吞噬(或泄漏到)图像内部。如果您在周围的“边缘”颜色中存在间隙,可能还需要进行一些手动编辑才能使掩码完全正确。我们现在可以使用此掩码来提取图像的“核心”或内部。也就是说,我们确信不包含任何半透明区域到我们正在去除的原始背景模式的部分。

  magick diff_mask_32.png -channel blue -separate +channel -negate \
          letter.png +swap -alpha Off -compose CopyOpacity -composite \
          letter_inside.png
[IM Output]
请注意我是如何从洪泛填充的掩码图像中提取蓝色掩码的。此外,由于洪泛填充的“全有或全无”特性,掩码将在边缘周围显示出严重的阶梯或锯齿效果。这就是第二个掩码将帮助我们修复的问题。请记住,此图像仅包含我们知道不与原始背景交互的像素,并且将在最终图像中保持原样。它不包含任何阴影效果,以及我专门尝试恢复的抗锯齿像素。恢复这些像素才是真正的工作所在。通过取反和减去(乘以)掩码,我们可以生成一个新的掩码,该掩码定义了我们想要提取半透明边缘或阴影像素的区域...

  magick diff_mask_01.png -negate diff_mask_32.png \
          -channel blue -separate +channel -compose multiply -composite \
          mask_aliasing_area.png
[IM Output]
然后,使用此区域从差异掩码中提取抗锯齿像素,该掩码定义了像素的透明度。我们对这些像素进行归一化,以获得从不透明到透明的平滑过渡。

  magick diff_mask.png -channel red -separate +channel \
          mask_aliasing_area.png -alpha Off -compose CopyOpacity -composite \
          -background gray30 -compose Over -flatten -normalize \
          mask_antialiased_pixels.png
[IM Output]
以上掩码中颜色越浅,像素的不透明度就越高。同样,颜色越深,透明度就越高。请注意,这里我使用了灰色背景,以确保图像中存在的透明颜色不会干扰图像的 归一化。如果没有这样做,归一化将失败。平面灰色本身并不重要,因为它们位于掩码区域之外,因此将在以后被忽略。现在我们有了正确的透明度级别,我们需要知道应该使用什么颜色来表示这些半透明像素。此颜色通常与图像的边缘颜色相同,在本例中,简单地为黑色。但是,由于原始背景的相互作用,我决定为阴影选择深灰色。
您需要以某种方式弄清楚半透明像素应该是什么颜色,以便您可以为抗锯齿像素设置正确的颜色。

这可能是
  1. 固定的边缘颜色(例如:近黑色,如本例所示)
  2. 使用最接近的完全不透明边缘像素的颜色(使用形态学。参见 稀疏颜色作为填充运算符
  3. 计算:一旦知道 alpha 和背景颜色,就可以减去背景颜色以校正像素颜色。请参见下面的 使用两个背景去除背景
基本上取决于你的图像。
既然我们已经做到了,让我们也重新遮罩图像,只留下这些特殊的边缘像素。

  magick mask_antialiased_pixels.png mask_aliasing_area.png \
          -compose multiply -composite -negate \
          -background '#444' -channel A  -combine letter_edging.png
[IM Output]
现在只需要将图像的内部“核心”与半透明边缘像素叠加起来。

  magick letter_inside.png letter_edging.png \
          -background none  -flatten    letter_recovered.png
[IM Output]
瞧,我们得到了一个背景被去除的图像,从而生成一个完美的抗锯齿图像,并正确恢复了半透明的边缘和阴影。您甚至可以将其叠加到完全不同的背景上。

  magick letter_recovered.png tile_aqua.jpg \
          -background none -compose DstOver -flatten    letter_on_aqua.png
[IM Output]
我用于此示例的图像非常困难,具有很大的“边缘”区域。大多数图像并没有那么糟糕,但这种方法可能是最好的,也是最通用的背景去除技术。现在,它已经被放置在一个名为“bg_removal”的 shell 脚本中,该脚本使用单个命令,没有临时文件,并且具有许多关于掩码执行方式的额外选项。

使用两个背景移除背景

先前技术的主要问题在于,你实际上没有足够的信息来完全恢复关于前景物体的所有信息。你需要恢复两部分信息,前景物体中每个像素的透明度,以及它的原始颜色。而你无法仅从一张图像中完美地恢复这两部分信息。即使你确切地知道背景图像是什么样的,你也不能简单地将其从前景物体中减去,除非两者差异很大且颜色已知。问题在于你无法确定可见的颜色是真实的颜色(不透明),还是其他颜色与背景的混合(半透明)。你无法将原始颜色从所需的 alpha 值中分离出来,除非你有一些额外的信息来源。唯一可以完全恢复前景物体所有细节的情况是,你拥有两张包含两种截然不同但完全已知背景颜色的图像。在这种情况下,你拥有足够的信息来恢复前景物体的颜色及其透明度,从而实现完美的背景去除。选择两张图像的重要因素是,背景颜色在整张图像中尽可能不同。也就是说,颜色不仅是互补色,而且在所有通道中强度都是相反的。例如...
[IM Input] [IM Input]
虽然使用了不同的背景颜色,但两张图像都包含完全相同的物体。所示物体并不简单,而是包含许多半透明的颜色。你可以在图像火焰中看到深蓝色背景的可见部分,尽管这种透明度在较浅的黄色背景中几乎不可见。通过使用两种颜色,覆盖物体的半透明像素将与两种截然不同的颜色混合,因此在两张图像中颜色会略有不同。通过测量每个像素的不同之处,你可以准确地确定哪些像素是半透明的,以及透明度有多高。实际上,有足够的信息让你完美地恢复覆盖物体的透明度。恢复透明度或“蒙版”当然是第一步,实际上是一个非常简单的步骤。生成一张差值图像,然后合并并最大化在每个通道中找到的差异。

  magick match_navy.gif match_gold.gif \
          -compose difference -composite -separate \
          -evaluate-sequence max -auto-level -negate \
          match_alpha.png
[IM Output]
生成的这张图像完美地映射了每个像素的透明度。它本质上是源图像中原始物体的“alpha 蒙版”。但是,它仅在覆盖图像同时包含完全透明区域和完全不透明区域时才有效。如果不是这种情况,则需要将每个通道除以两种背景颜色的差值,而不是上述步骤中的规范化步骤(“-evaluate-sequence max -auto-level”)。也就是说,除以 0.0 到 1.0 之间的值,差异越大越好。如果两种背景颜色是纯黑色和纯白色,则无需规范化,只需两张图像的差值即可。然后对差值进行 反转,以便最大差异产生零 alpha 或完全透明,而无差异产生最大 alpha 或完全不透明。下一个任务更难,因为每个半透明像素的颜色都会受到背景的影响,你不能仅使用 alpha 蒙版从其中一张源图像中提取物体。例如...

  magick match_navy.gif match_alpha.png \
          -alpha Off -compose Copy_Opacity -composite \
          match_bad_colors.png
[IM Output]
基本上,我们得到的是图像中半透明“火焰”的背景颜色产生的可怕光晕。这并不是一个好的结果。这被称为“颜色溢出”(来自 色度键控蒙版,也称为蓝屏或绿屏技术),这可能是一个主要问题。我们需要做的是从半透明像素中去除背景颜色。但是,由于我们已经恢复了原始图像的 alpha 通道,所以我们确切地知道需要从每个像素中去除多少颜色,以便恢复覆盖的原始颜色。要做到这一点,我们不仅需要其中一张源图像和刚刚提取的 alpha 通道,还需要知道该源图像中背景的精确颜色。当使用纯色背景时,这是一个相对容易的问题,就像这些示例一样。例如,这里我恢复了原始颜色...

  magick match_navy.gif match_alpha.png -alpha Off \
          -fx "v==0 ? 0 : u/v - u.p{0,0}/v + u.p{0,0}" \
          match_alpha.png -compose Copy_Opacity -composite \
          match_recovered.png
[IM Output]
我使用源图像中的左上角像素(FX 公式“u.p{0,0}”)作为背景颜色,从半透明像素中去除。如果需要,可以调整此颜色或直接替换要去除的颜色。颜色恢复的关键在于上面复杂的 FX 混合减法操作。这将根据 alpha 蒙版(“v”)增强源图像的原始颜色(“u”),然后从最终结果中减去背景颜色(u.p{0,0} 或左上角像素)。公式并不简单,要特别感谢 IM 论坛讨论 Undo a Composite -dissolve 中的 HugoRune,他确定了所需的数学运算。讨论还详细介绍了所有步骤是如何工作的,是如何推导出来的,甚至是如何从任何两个已知但不同的背景图案中提取覆盖物。以下是一条包含所有步骤的完整命令。

  magick match_gold.gif match_navy.gif -alpha off \
          \( -clone 0,1 -compose difference -composite \
             -separate -evaluate-sequence max -auto-level -negate \) \
          \( -clone 0,2 -fx "v==0?0:u/v-u.p{0,0}/v+u.p{0,0}" \) \
          -delete 0,1 +swap -compose Copy_Opacity -composite \
          match_recovered_2.png
[IM Output]
在 IM v6.6.8-3 中,如果 FX 使用“p{}”引用透明像素,则会获取零值,而不是实际的完全透明颜色值!这是一个错误,已在 IM v6.6.8-5 中报告并修复。尚不清楚此错误是在何时引入的。

这仅仅是一个问题,如果你决定先将 alpha 图像合并到源图像中,然后尝试使用已知的背景颜色来修复半透明或“溢出”颜色。
这次,使用“金色”背景图像进行颜色提取,并由第二个“-clone”操作中的“0”选择,但可以使用任何源图像。只需注意一点。上述操作假设左上角像素是未受污染的背景颜色。如果不是,你可能需要修改命令以指定特定的像素颜色,或者使用包含正确背景颜色信息的第三张图像。如果背景颜色在图像中不一致,则后一种方法至关重要,但即使这种复杂情况也可以解决。以下是用于覆盖在纯黑色和纯白色背景上的图像的更简单的序列。在这种情况下,颜色始终从黑色背景图像中恢复,因为它只是一个简单的除法运算,因此可以使用更快的 除法合成,而不是缓慢的 FX DIY 运算符

  magick match_black.gif match_white.gif -alpha off \
          \( -clone 0,1 -compose difference -composite -negate \) \
          \( -clone 0,2 +swap -compose divide -composite \) \
          -delete 0,1 +swap -compose Copy_Opacity -composite \
          match_recovered_3.png
[IM Input] [IM Input] ==> [IM Output]

用于背景恢复的影棚照片理想的背景是哑光(非反射)黑色,以及简单的纯色(非反射)白色。背景也应该尽可能平滑且无变化。在专门用于背景去除的照片拍摄中,使用两种互补颜色可能效果更好。例如,使用绿色和品红色背景拍摄照片。基本上,你需要在拍摄第二张照片之前以某种方式替换背景颜色屏幕。请注意,两张照片的顺序在背景去除中并不重要,但它们应该尽可能干净且统一,并且主体和相机必须保持完美静止和固定。一个更好的方法可能是简单地在物体后面放置一块距离较远的白色屏幕,并使用两种不同颜色的灯均匀地照亮屏幕,以免物体产生阴影。使用此技术,你可以在不需要对影棚进行任何物理改变的情况下,切换到另一种背景颜色,从而拍摄具有两种不同背景的两张照片。这两种颜色背景技术适用于透明物体,但物体拍摄时产生的反射或背景扭曲或“镜头”效果将不会被此技术记录,只有它的透明度会被记录。另一方面,物体上恒定光源的反射将被保留!如果你尝试过,请告诉我们,并提供源照片和结果的示例,以便包含在此处。你将在你的网站的链接处被提及,以便人们可以查看。
视频背景恢复如果你有一系列包含许多不同但复杂的背景的图像(例如视频),你可以尝试获取所有图像的最小值和最大值,以生成接近纯黑色和白色背景图像以供使用。图像越多,效果越好。使用这两张图像,可以提取任何恒定的徽标及其半透明度,然后可以使用相同的技术将其从所有帧中去除。但是,它仅适用于恒定的半透明覆盖物,可能不适用于使用颜色或色调失真,甚至使用纯色徽标的徽标。但它至少可以让你确定徽标的精确形状。对于完全不透明或更难的徽标,可以使用孔洞填充(参见下一节)来填充周围颜色缺失的细节。有关更多信息,请参见 IM 论坛讨论

孔洞填充

虽然蒙版、添加透明度和去除背景提供了一种处理不需要的元素的方法,但通常“孔洞”不是你想要的最终结果。当然,你可以简单地将带有孔洞的图像覆盖到其他图像上以填充它们,但这可能无法产生无缝的结果。要从图像中擦除元素,你不仅想要将其剪切出来,还要用周围孔洞的顏色、阴影和纹理替换它们。以下是确定如何使用什么来填充孔洞的几种技术。

创建要填充的孔洞

假设我们有一张带有难看文本的图像...

  magick zelda_tn.gif -gravity Southwest -annotate +8+20 Zelda zelda_text.jpg
我们真正想要做的是去除该文本,最简单的方法是将其蒙版,以便在文本所在位置留下一个“孔洞”。这简化了问题,因为我们不再关心去除了什么。我们只需要填充一个孔洞。
[IM Output]
但是,对于这种情况,我将使用一条覆盖“难看文本”的绘制线来创建蒙版,就好像用户快速使用了一个图像编辑器一样。

  magick -size 120x90 xc:black  -stroke white  -strokewidth 7 \
          -draw 'stroke-linecap round line 9,62 36,63' \
          -threshold 10%  zelda_text_mask.gif
[IM Output]
仅仅创建“孔洞”本身可能是一个棘手的问题,而自动解决方案可能取决于你试图去除什么,甚至可能涉及将数百张包含相同“文本”或“徽标”的图像进行比较以准确地定位它。请注意,孔洞越小,最终结果越好。可以从原始图像中保留的信息越多,结果就越好。一个粗糙的形状奇特的孔洞也比一个非常光滑的孔洞更好。因此,花点时间制作尽可能小的孔洞来去除所有不需要的效果,这可以产生很大的影响。
现在,让我们使用蒙版从图像中剪切出一个孔洞,这也将检查它是否覆盖了所有不需要的部分。

  magick zelda_text.jpg \( zelda_text_mask.gif -negate \) \
          -compose CopyOpacity -composite   zelda_text_hole.png
因此,这里我们有一张带有“孔洞”的图像,需要填充它。
[IM Output]

模糊填充

因此,我们有一个孔洞,需要用某种颜色填充它。一种不会让人觉得我们从图像中实际去除了一些东西的方法。
最简单的方法之一是简单地模糊图像,让孔洞周围的颜色“扩散”到孔洞中,然后去除透明度。

  magick zelda_text_hole.png -blur 0x1 -alpha off zelda_text_fill.png
使用的模糊量取决于使用的孔洞的大小。
[IM Output]
现在,我们可以 底层这张模糊的图像以“填充”我们之前创建的“孔洞”...

  magick zelda_text_hole.png zelda_text_fill.png \
          -compose Dst_Over  -composite   zelda_text_removed.png
[IM Output] ==> [IM Output] [IM Output] ==> [IM Output]
文本已被移除。这并不完美,因为该区域的颜色模糊表明某些内容已被移除。例如,如果你仔细观察塞尔达头部旁边的窗框,你可以看到模糊的效果。此外,该区域看起来比图像的其余部分“更平滑”,这在照片中尤为明显。但它是一种广泛且快速的技巧,你经常会在视频中看到它,他们在视频中尝试移除一些电视台为了版权保护目的添加的标识。隐藏移除的另一种方法是使实际移除变得明显。例如,如果你想 保护某人的匿名性
正在建设中
其他方法的链接。调整大小模糊填充方法... 稀疏颜色,谢泼德方法(快速)。另请参阅 snibgo,填充孔洞 模糊边缘像素... 稀疏颜色作为填充运算符。另请参阅 snibgo,按优先级填充孔洞 我想使用一个形态学运算符,它在颜色通道中设置颜色,同时在隐藏的背景通道中计算距离。这应该生成一个非常快速的无泄漏谢泼德式填充,称为“**颜色扩散**”。请参阅论文 扩散曲线,它大量使用此技术。关于填充孔洞(文本移除)的一个大型且古老的讨论在 IM 用户论坛上 文本移除讨论。一个较新的讨论是 用边界上的最近颜色填充区域,它更多地是关于填充而不模糊。在 Stack Overflow,从 jpeg 中移除文本 中展示了其他一些非 IM “填充孔洞”方法,用来擦除图像的一部分。例如,使用 Python Skimage。或者使用 Python OpenCV 图像修复