ImageMagick 範例 --
遮罩

索引
ImageMagick 範例前言與索引
Alpha (遮罩) 色版
對影像使用遮罩
特殊影像遮罩
區域和區域子影像
背景移除
孔洞填補 (建構中)
在這些範例中,我們將探討透明度的特殊處理、透明度色版、使用遮罩,以及最終移除不需要的背景或其他元素,例如標誌、文字、垃圾郵件。

Alpha 色版

影像的透明度(alpha)色版完全是可選的,並且通常需要與一般「顏色」色版分開處理。請參閱上方的影像色彩空間。透明度色版的存在也會影響各種運算子處理其他顏色色版的方式,這通常是因為完全透明的顏色通常應該被運算完全忽略。如果不是這種情況,您會在影像周圍看到「黑色光暈」,例如在 IM v6 早期的主要 IM 錯誤中所見。例如調整大小光暈錯誤透明度模糊錯誤。更糟糕的是,這個色版有時也被稱為影像的「透明度」或「不透明度」色版,甚至是影像的「遮罩」。然而,所有這些都指的是影像的同一個特殊的第四個色版。[IM 輸出]為了說明差異,我們需要一個有效的範例影像,為此我將使用「新月」影像的 PNG 影像(來自複製不透明度合成範例)。現在,如您所見,此影像有很多區域是完全透明的。不僅如此,我還需要使用「PNG」影像格式儲存影像,該格式是少數能夠正確理解和處理透明和半透明顏色的影像格式之一。
我可以透過使用Alpha 合成將影像覆蓋在 IM 內建的棋盤格圖案上來演示這種透明度。

    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>
使用以下版本產生範例:[版本影像]
網址:https://imagemagick.dev.org.tw/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 關閉  沒有 alpha 資料(沒有配置記憶體)
 alpha 關閉  舊的 alpha 資料存在(但未使用)
 alpha 開啟  目前正在使用的 alpha 資料
需要記住這一點,因為各種方法的行為取決於影像處於上述三種狀態中的哪一種。如果「開關」關閉,運算子將不會觸摸 alpha 資料,因為它可能根本不存在。在這種情況下,舊的 alpha 可能仍然存在、未經修改,因此已過時。如你所見,這在某些情況下實際上很有用。但是請注意,某些運算子可能會因為某種原因自動開啟或關閉 alpha 開關。例如,「-compose CopyOpacity -composite」將始終開啟結果影像中的 alpha 通道,因為它是運算子的工作,將資料複製到 alpha 通道中。因此,它必須存在於最終結果中。但是,它在輸入資料中的存在可能會產生其他後果。有關詳細資訊,請參閱Copy_Opacity 合成方法。同樣,使用顏色「None」建立畫布也會自動建立並啟用透明度通道,以確保空白影像確實是透明的。另一方面,使用其他顏色名稱建立畫布通常不會建立任何透明度通道,因為預設情況下影像是完全不透明的。
以下是各種「-alpha」方法以及它們如何影響影像及其透明度的範例。

Alpha 關閉-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 移除 - 移除透明度。「+alpha」運算子是一個較舊的命令,與「-alpha Off」完全相同。也就是說,它只是關閉透明度通道。請注意,在將灰度蒙版圖片與複製不透明度 Alpha 合成方法一起使用之前,通常需要關閉 Alpha。如果不這樣做,合成運算子將複製啟用的透明度(不透明度通道),而不是使用預期的灰度顏色。

Alpha 設置"-alpha set"

Set」Alpha 方法與舊的「-alpha on」選項相同。這確保圖片具有「透明度」或 Alpha 色版,但如果它不存在或被關閉,則會將其初始化為完全不透明(請參閱下面的Alpha 不透明度方法)。但是,如果圖片已經存在並啟用了 Alpha 色版,則它不會執行任何操作。換句話說,此運算子確保存在 Alpha 色版,而不會修改圖片當前在內存中的外觀。因此,此運算子本身不會顯示對圖片的任何更改,但在與其他運算子組合使用時會產生實際效果。因此,如果您使用Alpha 關閉關閉 Alpha 色版,然後使用Alpha 設置再次啟用它,則圖片將具有 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,但不應將其用於此目的。 只有當您先前出於某種原因特意關閉 Alpha,並且現在希望恢復該資料時,才應該使用 開啟 Alpha。 例如,在套用一些非常特定的運算子(例如「-shade」)之前,可以關閉然後開啟 Alpha 色板來保留 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」(提取)方法也會將「Off」(關閉)alpha,但它不會被清除,因此將 alpha 通道重新「On」(開啟)將重新建立原始影像的形狀遮罩。

  magick moon.png  -alpha extract -alpha on   alpha_extract_on.png
[IM Output]
請注意,所有原始顏色都將被替換為白色,邊緣周圍有各種深淺的灰色。如果我們使用白色背景移除透明度,我們可以看到這一點(請參閱下面的 Alpha Remove(移除 Alpha)方法)

  magick alpha_extract_on.png -background white -alpha remove alpha_edge.png
[IM Output]
這些「灰色」像素實際上在 從反鋸齒形狀提取邊緣輪廓 中得到很好的利用,以從影像形狀生成平滑的邊緣或輪廓。儲存 alpha 通道的這種副作用在使用 陰影運算子 時具有特殊的優勢,因為它不理解或不使用影像的 alpha 通道。請參閱子章節 遮罩陰影形狀

Alpha Copy(複製 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 形狀)

為了更容易使用灰階影像,「Shape」(形狀)方法不僅會建立形狀遮罩(根據 Alpha Extract(提取 Alpha)),還會使用當前的背景顏色為其著色。

  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 Remove(移除 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 開始,提供了一個「背景」方法,可以將完全透明像素的隱藏顏色設定為目前的背景顏色。通常這種顏色並不重要,因為只有在 關閉 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 顏色 -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 方法,快速且簡單地將透明度替換為背景顏色底色...

  magick a.png   -background skyblue  -alpha remove -alpha off a_remove.jpg
[IM Output]
嚴格來說,在這種情況下並不需要 關閉 Alpha,因為儲存為 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]
其他與上述方法密切相關的影像處理運算子也可以從影像中移除透明度。這些包括:馬賽克合併框架範圍 運算子也可以使用,並且允許您在移除透明度的同時擴展或裁剪影像,但前提是您知道所需最終影像的大小。您不必用純色替換透明度。如果您使用 DIY 合成(如上所示),您可以使用任何影像作為替換背景。一個簡單的例子是使用「composite」指令在原始影像「下方」平鋪 一個影像(使用 Dst_Over)。這種合成方法可確保保留原始影像的詮釋資料和大小。

  magick composite -compose Dst_Over -tile pattern:checkerboard \
                                               a.png  a_undertile.jpg
[IM Output]
上述許多方法都會受到影像可能具有的任何虛擬畫布資訊的影響,或是在處理過程中將其破壞。當涉及虛擬畫布時,您可能需要更仔細地查看個別運算子的細節。在許多情況下,虛擬畫布效果可能對您的整體影像處理很有用。

布林 Alpha 透明度

對於某些影像檔案格式,您不需要完全移除 Alpha 色版,只需要允許純開啟/關閉或布林透明度即可。索引 (調色盤) 影像檔案格式,例如 GIFPNG8,就是典型的例子。目前在 GIF 布林透明度 中可以看到一些範例,但最終應該會移到這裡。

輪廓或光暈透明度

有時,您會希望在包含透明度的影像周圍添加輪廓線。一種方法是使用 邊緣外擴形態學 快速取得原始影像的所有相鄰像素,為它們著色,然後使用 下方 (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」操作,因為確保灰階影像不包含不需要的透明通道至關重要。瞧,我們從原始影像中咬了一口。我們還可以重新添加我們移除的影像的一部分。例如,在這裡,我透過在遮罩上繪製白色區域,重新添加了從原始影像中移除的「咬痕」的一部分。然後使用 複製不透明度通道合成 將遮罩返回到原始影像。

  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 形狀 運算符,這與 Alpha 複製 完全相同,但有一個額外的步驟來為最終形狀著色。

  magick heart_mask.gif  -background Red -alpha Shape  heart_red.png
[IM Output]
請注意,生成的形狀圖像使用「PNG」圖像格式而不是 GIF,以避免 GIF 布林透明度 的問題。
在此之前,最簡單的解決方案是將 Alpha 遮罩反轉為遮罩 通道圖像,然後使用 組合 來生成形狀圖像。

  magick heart_mask.gif -negate  \
          -background Gold  -channel A  -combine   heart_gold.png
[IM Output]
在這種情況下,形狀遮罩的顏色由「-background」顏色定義,組合 用於填充新圖像中未定義的通道。一種較舊但更複雜的方法是使用「複製不透明度」合成方法將圖像的透明度設置為給定的遮罩,然後使用 均勻色彩著色 為生成的形狀著色。這很有效,並且長期以來一直是最好的技術,但現在不再推薦。

  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.dev.org.tw/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.dev.org.tw/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.dev.org.tw/Usage/compose/#mask
      and https://imagemagick.dev.org.tw/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」關閉區域時,提取的區域會在其提取的位置疊加到原始影像上。
區域的工作方式類似於使用影像堆疊運算子,儘管它在 ImageMagick 中存在的时间比這些運算子长得多。例如,它是 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 ...
「區域影像」實際上是如何疊加到「原始影像」上,這有點棘手... 如果原始影像沒有啟用透明度通道,則使用疊加合成來合成「區域影像」。這意味著區域影像中的透明區域將變為透明,讓您可以看到它後面的原始影像。例如,在這裡我特意關閉了原始影像中的透明度,但 kemudian 旋轉區域,以便在角落產生一些透明區域。

  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 圖像檔案格式 的一部分中有詳細討論,該格式只允許布林透明度。

遮罩簡單背景(floodfill)

當圖像背景是簡單的單一純色時,您通常可以透過 替換圖像中的顏色 來生成簡單的遮罩(和背景移除)。例如,以下是一個具有純色背景的圖像的直接 floodfill 遮罩。

  magick cyclops.png -alpha set -channel RGBA \
          -fuzz 1% -fill none -floodfill +0+0 white \
          cyclops_flood_1.png
[IM Output]
好吧,這不起作用,因為右上角的 floodfill「種子」點實際上並沒有到達圖像的所有部分!!!解決方案是稍微放大圖像,以便為 floodfill 提供一條到達圖像所有外邊緣的路徑。但是,為此,您需要知道背景的顏色。

  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]
此外,如果您確實設法使用了足夠高的模糊係數,您可能會遇到邊緣像素很少或「洩漏」到圖像中心的問題。最後,像這樣的直接 floodfill 不適用於不是簡單單一純色的背景。

裁剪帶邊框的物件

對於這些去背方法來說,具有單一顏色邊框的圖像具有明顯的優勢,因為邊框在圖像的「內部」和「外部」之間提供了一個明確的界限,這反過來又允許使用更好的方法來指定背景圖像的邊界。也就是說,我們可以指定哪些顏色標記了被遮罩對象的邊框,而不是指定哪些顏色應該被視為背景。此外,由於邊框顏色是已知的,因此圖像邊緣周圍只會混合兩種特定的顏色。也就是說,兩種顏色都是已知的,因此邊緣應該透明的程度也是非常清楚的。
施工中

移除已知背景

雖然將簡單背景移除到「布林」遮罩相對簡單,但當背景不那麼簡單時,事情就會變得更加複雜。但是,如果背景本身是已知的,則可以使用它來幫助從其他圖像中移除它。從 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]
-模糊度 1%
[IM Output]
-模糊度 3%
[IM Output]
-模糊度 6%
== [IM Output]
-模糊度 28%
[IM Output]
-模糊度 32%
[IM Output]
-模糊度 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} 或左上角像素)。這個公式並不簡單,非常感謝HugoRune在 IM 論壇討論撤銷複合溶解中確定了所需的數學方法。討論還繼續說明了所有步驟是如何工作的、是如何得出的,甚至是如何從任何兩個已知但不同的背景模式中提取覆蓋層。以下是所有步驟都在一個命令中的完整序列。

  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]
文字已被移除。這並不完美,因為該區域的顏色模糊使得顯然移除了一些東西。例如,如果您仔細觀察薩爾達頭部旁邊的窗框,您會看到模糊的效果。此外,該區域看起來比圖像的其餘部分「更平滑」,這在照片中尤其明顯。但這是一種廣泛使用且快速的技術,您經常會在視頻中看到這種技術,他們試圖移除一些電視廣播公司為防止版權而添加的標誌。隱藏移除的另一種方法是使實際移除變得明顯。例如,如果您想保護某人的匿名性
施工中
其他方法的鏈接。 調整大小模糊孔洞填充方法... 稀疏顏色,Shepard 方法(快速)。另請參閱 snibgo,填充孔洞 僅模糊邊緣像素...稀疏顏色作為填充運算符。另請參閱 snibgo,按優先順序填充孔洞 我想使用形態學運算符,在顏色通道中設置顏色,同時在隱藏的背景通道中計算距離。這應該會產生一個非常快速的無洩漏 Shepard 類似填充,稱為「顏色擴散」。請參閱論文 擴散曲線,其中大量使用了這種技術。在 IM 用戶論壇上有一個關於孔洞填充(文本移除)的大型且較早的討論 文本移除討論。一個更新的討論是 用邊界最近的顏色填充區域,這更多的是關於不模糊填充。其他一些非 IM 的「孔洞填充」方法來擦除圖像的部分顯示在 Stack Overflow,從 jpeg 中移除文本。例如,使用 Python Skimage。或者使用 Python OpenCV 圖像修復