ImageMagick 範例 --
影像轉換

索引
ImageMagick 範例 前言與索引
藝術風格轉換
電腦視覺轉換
Shade 3D 高光
使用 FX,DIY 影像運算器
Evaluate 和 Function,快速 FX 運算器
漸層數學
這些操作會對影像的整體外觀產生重大變化,以產生視覺效果或藝術效果。 然而,雖然影像的整體外觀發生了變化,通常是劇烈的變化,但原始影像本身通常在結果中仍然可見。

藝術風格轉換

凸起或凹陷邊框

-raise」運算器是一種非常簡單的影像轉換,幾乎不算。 它所做的只是為現有影像新增矩形斜角高光。

  magick rose: -raise 5  rose_raise.gif
[IM Output]
可以使用運算器的「加號」形式產生反轉的凹陷效果...

  magick rose: +raise 5  rose_sunken.gif
[IM Output]
此運算器有點像框住影像,但「-raise」運算器不會新增額外的像素作為邊框,而是重新著色影像的邊緣像素。 這使其成為影像轉換。
實際上,影像框住是透過新增邊框,然後將其凸起來實現的!
該運算器僅適用於矩形影像,並且對於具有透明背景的影像將會失敗,因為顏色修改也將是透明的。 基本上,這是一個相當笨拙的運算器!

新增內部邊框

使用者希望新增一個邊框來覆蓋影像的邊緣,而不是在影像外部新增邊框。 解決方案是在影像周圍繪製一個矩形。 由於內建的玫瑰圖尺寸為 70x46 像素,因此結果如下。

  magick rose: -fill none -stroke navy -strokewidth 11  \
          -draw 'rectangle 0,0 69,45'   inside_border.jpg
[IM Output]
新增邊框的寬度由矩形的「-strokewidth」控制。 也就是
{stroke width}  =  {border width} * 2 - 1
因此,上述 6 像素邊框需要 11 的「-strokewidth」。 如果您不知道圖像的大小,則可以先修剪圖像,然後再照常添加邊框。 這樣做可能更容易,但可能不像前一種方法那樣通用。

  magick rose: -bordercolor green -shave 6x6 -border 6x6 inside_border2.jpg
[IM Output]

隨機像素擴散

-spread」會將每個像素替換為來源圖像中附近隨機顏色的顏色。 這種隨機選擇是根據像素插值虛擬像素設定的使用方式做出的。
舉例來說...

  magick -size 80x40 xc:red xc:blue -append -spread 5 spread_interpolated.png
[IM Output]
如果您要檢查像素圖像,您會發現某些像素可能混合了紅色和藍色。 也就是說,它們是插值的,而不僅僅是擴散或交換的。 距離值越小,這種情況越明顯。
另請注意,「-spread」也會使用虛擬像素設定

  magick -size 80x80 xc: -virtual-pixel black -spread 10 spread_virtual.png
[IM Output]
如您所見,您會得到一個隨機邊框,大部分是純黑色的虛擬像素。 雖然有一些灰色像素是從圖像的真實像素和虛擬像素之間的邊界插值而來的。 若要獲得更傳統的擴散像素效果,您可以透過使用「-interpolate Nearest」強制特定像素的顏色查找來防止這種顏色混合。 為了避免虛擬像素和可能的「邊緣顏色偏差」問題,我建議您使用「-virtual-pixel Mirror」。 因此,這是一種更傳統的隨機像素「擴散」...

  magick rose: -interpolate nearest -virtual-pixel mirror \
                -spread 5   spread_rose.png
[IM Output]

建構中
上述方法的主要問題是您可能會丟失圖像中的一些像素數據。 也就是說,像素不是「交換」而是隨機複製的,這意味著圖像中的特定像素可能會被複製或丟失。 從 IM v6.9.2-2 開始,您可以使用「+spread」實際交換圖像中的像素,這意味著圖像中的任何像素都不會被複製或丟失。 原始圖像中的每個像素仍然存在,只是被移到了新的位置。 但是,由於像素的處理方式,像素可能會被「雙重交換」。 也就是說,一個特定的像素可能會被交換,但隨後又被選中與後面的像素交換。 這意味著一個特定的像素可能會漂移到超出 spread 參數所要求的距離。 這種雙重交換也意味著像素可能會進一步漂移到右下角。 當然,這種移動是平衡的,但大量像素會向左上角稍微漂移。
例如,我在這裡擴散像素,並將原始像素作為參考放在前面。

  magick -size 40x40 xc:red xc:blue -append \
          \( +clone +spread 5 \) +append spread_bias.png
[IM Output]
請注意一些紅色像素是如何向下擴散得更多,儘管您也會看到一些藍色像素向上擴散得比預期更多(儘管是朝向圖像的左側)。 當您使用較小的距離參數進行擴散時,此問題會更加明顯。 解決這個雙重交換問題並不容易,我們正在尋找一種「有限區域洗牌」算法來解決它。 但與此同時,您至少可以透過使用橫向(從左上角到右下角的對角線鏡像)扭曲進行兩次擴散來減輕方向偏差。

  magick -size 40x40 xc:red xc:blue -append \
          \( +clone +spread 5 -transverse -spread 5 -transverse \) \
          +append spread_no_bias.png
[IM Output]
當然,這確實會使擴散更加明顯,並且線性度降低,但至少它沒有方向偏差,也沒有像素複製/丟失。 上述添加內容是根據論壇討論開發的:t=28043 IM 論壇討論 重新排列垂直像素行

暈影照片轉換

一種特殊的運算子,用於使圖像呈圓形,並帶有柔和模糊的輪廓。

  magick rose: -background black -vignette 0x5  rose_vignette.gif
[IM Output]
透過使用零(或非常小)的 sigma 值,您可以移除模糊效果,並產生橢圓形或橢圓形的邊框。但請注意,它實際上並未使用最大可能的橢圓形,因此您可能需要自行調整。

  magick rose: -background black -vignette 0x0  rose_vignette_0.gif
[IM Output]
您可以將它與透明度(和 PNG 格式)一起使用……

  magick rose: -alpha Set -background none -vignette 0x3  rose_vignette.png
[IM Output]
另一種參數方法是對第二個 sigma 元件使用一個非常大的數字,然後使用第一個 radius 來定義模糊的擴散範圍。這會產生「線性」分佈,而不是暈影模糊中更常見的高斯分佈。

  magick rose: -background black -vignette 5x65000  rose_vignette_linear.gif
[IM Output]
另一種產生更矩形暈影、為圖像產生柔和邊緣的技術,在具有柔和邊緣的縮略圖 中有示範。

複雜的拍立得轉換

感謝 Timothy Hunter(RMagick 的作者)所做的工作,IM v6.3.2 中添加了一個「-polaroid」轉換運算符。
Polaroid® 是 Polaroid Corporation 的註冊商標。
例如,我在這裡為照片縮略圖賦予了拍立得的外觀。圖像向上看巴黎凱旋門內的螺旋樓梯(向下)。這是一個非常長的樓梯!

  magick spiral_stairs_sm.jpg -thumbnail 120x120 \
          -bordercolor white -background black  +polaroid  poloroid.png
[IM Output]
請注意,生成的圖像具有半透明陰影,因此您必須使用 PNG 格式的圖像,或者將結果「-flatten」到 GIF 或 JPG 格式的固定背景顏色上。
此運算符非常複雜,因為它會添加邊框(根據「-bordercolor」設定)、將紙張「捲曲」,並為陰影添加反向捲曲。陰影顏色可以通過「-background」顏色設定來控制。正如您在上面看到的,該運算符的加號形式將隨機旋轉結果。此運算符使照片索引比您通常獲得的結果更有趣且更具動態。
該運算符的減號形式允許您控制圖像的旋轉角度。

  magick spiral_stairs_sm.jpg -thumbnail 120x120 \
          -bordercolor AliceBlue -background SteelBlue4 -polaroid 5 \
          poloroid_5.png
[IM Output]
如果圖像具有「-caption」元數據,則該文字也會通過「caption:」圖像創建運算符添加到拍立得相框的下邊框中。也就是說,它會根據照片的寬度進行自動換行。

  magick -caption '%c %f\n%wx%h' spiral_stairs_sm.jpg -thumbnail 120x120 \
          -bordercolor Lavender  -background gray40  +polaroid \
          poloroid_captioned.png
[IM Output]
其他標準文字設定(根據「caption:」),允許您控制添加的標題的外觀。

  magick spiral_stairs_sm.jpg -thumbnail 120x120 -font Candice -pointsize 18 \
          -bordercolor Snow -background black -fill dodgerblue -stroke navy \
          -gravity center  -set caption "Spiral Stairs\!"  -polaroid 10 \
          poloroid_controls.png
[IM Output]
使用圖像元數據屬性「-caption」是由於內部使用「caption:」文字到圖像生成器。

另一方面,IM 命令「montage」使用「-label」,因為它使用不自動換行的「label:」文字到圖像生成器。
轉換使用旋轉波浪剪切變形來為照片圖像添加一點「捲曲」,這往往會在生成的圖像文本中產生水平模糊線。這是一個眾所周知的圖像失真問題(請參閱旋轉細線),可以使用超級採樣技術來解決。基本上,我們生成兩倍於我們真正想要的拍立得,然後將圖像調整為其最終的正常大小。圖像尺寸的減小有效地銳化了生成的圖像,更重要的是銳化了標題文本。但是,要使其正常工作,我們不僅需要至少兩倍於最終大小的圖像,而且我們可能需要為圖像添加更大的邊框,並以兩倍於其正常「-density」的密度繪製文本。不要增加字體的「-pointsize」,因為這不會以完全相同的方式放大文本。

  magick -caption 'Spiral Staircase, Arc de Triumph, Paris, April 2006' \
          spiral_stairs_sm.jpg  -thumbnail 240x240 \
          -bordercolor Lavender -border 5x5   -density 144  \
          -gravity center  -pointsize 8   -background black \
          -polaroid -15     -resize 50%     poloroid_modified.png
[IM Output]
如您所見,即使我們使用較小的字體大小,標題文字仍然非常清晰、銳利且易於閱讀。原始影像中可能存在的任何其他精細細節也是如此。唯一的缺點是,結果影像的陰影會比較小,而且比較不模糊。若要完全控制拍立得轉換,您可以自行完成所有步驟。原始技術記錄在 Tim Hunter 的網頁上,RMagick 拍立得效果。步驟如下:建立並附加標題、新增邊框、使用波浪捲曲照片、新增反轉的捲曲陰影,最後旋轉影像。如需更多範例和其他 DIY 方法,請參閱拍立得縮圖範例拍立得照片蒙太奇。您可能也會對RubbleWeb IM 範例,其他中的一些拍立得範例感興趣。

油畫,色彩斑點

-paint」運算子的設計目的是將圖片變成繪畫,方法是將厚厚的「顏料塊」塗抹到畫布上。結果是將鄰近的顏色合併成更大的單一顏色區域。

  magick rose: -paint 1   rose_paint_1.gif
  magick rose: -paint 3   rose_paint_3.gif
  magick rose: -paint 5   rose_paint_5.gif
  magick rose: -paint 10  rose_paint_10.gif
  magick rose: -blur 0x3 -paint 10  rose_blur_paint_10.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output] ==> [IM Output]
請注意,在顏料塊的半徑較大的情況下,顏料塊會開始呈現方形的外觀。這種效果可以透過事先稍微模糊影像來稍微平滑化,如上圖最後一張影像所示。這是一種有趣的效果,可以用來製作一些奇特而美妙的背景影像。例如,請參閱其在背景範例中的使用。最後的警告。雖然「-paint」應該產生單一純色的區域,但在半徑值較大的情況下,它往往會在某些區域產生垂直漸層。這非常惱人,而且可能是個錯誤。有人知道嗎?有其他方法可以使用「-paint」。一種方法是改用「-statistic Mode」,它會將每個像素指定為給定矩形鄰域內的「主要顏色」,並且可以產生更好的結果。

  magick rose: -statistic Mode 10 rose_paint_mode.gif
[IM Output]
另一種方法是使用一些形態學方法,更具體地說是彩色影像的強度變體。例如,以下是玫瑰上的「OpenIntensity」形態學。

  magick rose: -morphology OpenI Disk rose_paint_open.gif
[IM Output]
在這裡,我使用「CloseIntensity」和一個稍微小一點的「Disk」。

  magick rose: -morphology CloseI Disk:2.5 rose_paint_close.gif
[IM Output]
您不必使用「圓盤」,而是可以為其建立的斑點設計自己的「筆刷」形狀核心。例如,使用對角線筆刷如何?

炭筆,場景的藝術家素描

炭筆效果旨在模擬藝術家對給定影像的炭筆素描。「-charcoal」運算子在某些方面類似於電腦視覺中使用的邊緣檢測轉換。基本上,它會嘗試將影像中物件的主要邊界和邊緣變成鉛筆和炭筆的陰影。其中一個參數應該代表邊緣線的粗細。

  magick rose: -charcoal 1   rose_charcoal_1.gif
  magick rose: -charcoal 3   rose_charcoal_3.gif
  magick rose: -charcoal 5   rose_charcoal_5.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output]
如需在真實影像上使用炭筆轉換的更好範例,請參閱照片的炭筆素描
從技術上講,「-charcoal」運算子是一個「-edge」運算子,它對原始影像的灰階轉換應用了一些臨界值。

鉛筆素描轉換

-sketch」運算子基本上是將線條筆劃的圖案應用於影像,以產生看起來像藝術鉛筆素描的效果。參數控制筆劃的長度和角度。但是,最好將其應用於具有明顯陰影的較大影像。如需此運算子及其內部工作原理的完整範例,請參閱鉛筆素描

浮雕,創造金屬印象

-emboss」運算子嘗試在金屬板上產生灰階圖像的酸蝕效果。它在很多方面都與我們將在下方看到的「-shade」運算子非常相似,但沒有 3D 外觀的邊緣。它的參數是一個半徑/標準差,其中只有標準差很重要。我發現這個參數不是很有用,實際上可能有 bug。在 IM 的最新版本中,這個參數也發生了變化。我不知道發生了什麼事。如果可以的話,請幫我理解。

  magick rose: -emboss 0x.5  rose_emboss_0x05.gif
  magick rose: -emboss 0x.9  rose_emboss_0x09.gif
  magick rose: -emboss 0x1   rose_emboss_0x10.gif
  magick rose: -emboss 0x1.1 rose_emboss_0x11.gif
  magick rose: -emboss 0x1.2 rose_emboss_0x12.gif
  magick rose: -emboss 0x2   rose_emboss_0x20.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
該運算子是一個灰階運算子,這表示它將分別應用於三個色彩通道。因此,它應該只應用於灰階圖像。正如您在上面看到的,彩色圖像可能會產生一些奇怪的效果。

  magick rose: -colorspace Gray  -emboss 0x.5  rose_g_emboss_0x05.gif
  magick rose: -colorspace Gray  -emboss 0x.9  rose_g_emboss_0x09.gif
  magick rose: -colorspace Gray  -emboss 0x1   rose_g_emboss_0x10.gif
  magick rose: -colorspace Gray  -emboss 0x1.1 rose_g_emboss_0x11.gif
  magick rose: -colorspace Gray  -emboss 0x1.2 rose_g_emboss_0x12.gif
  magick rose: -colorspace Gray  -emboss 0x2   rose_g_emboss_0x20.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
 If anyone knows exactly what the emboss algorithm is supposed to do,
please let me know.

隱寫術,在一張圖像中隱藏一張秘密圖像

-stegano」運算子實際上更像是一個「有趣」的運算子。例如,它可以用於間諜在隨機圖像的「混亂」中隱藏信息。首先,一個警告...
不要在隱寫術中使用 JPEG、GIF 或任何其他「有損」圖像編碼
例如,讓我們生成一個您想發送給間諜同伴的加密信息(圖像)...

  magick -gravity center -size 50x40 label:"Watch\nthe\nPidgeon" message.gif
  magick identify message.gif
[IM Output]
[IM Text]
請注意,我們還需要信息圖像的大小(36x43 像素),因此在上面使用了 identify。接下來,將其放入一些圖像中,並帶有一些偏移量。使用的偏移量(和信息大小)是隱藏信息的密碼「密鑰」。

  magick composite message.gif rose: -stegano +15+2  rose_message.png
[IM Output]
現在,您可以將該圖像發送給您的同伴,他們可能已經知道信息大小和偏移量。我們可以恢復隱藏在圖像中的信息...

  magick -size 50x40+15+2 stegano:rose_message.png message_recovered.gif
[IM Output]
包含的圖像越大,恢復的圖像就越好,因此將小圖像隱藏在較大的圖像中比上面顯示的示例更好。為了向您展示隱藏信息是如何分佈在整個容器圖像中的,讓我們對組合圖像與原始圖像進行比較。

  magick compare -metric PAE rose: rose_message.png   rose_difference.png
[IM Output]
[IM Text]
這顯示了信息圖像是如何被加密並分佈在整個容器圖像中以隱藏起來的。此外,上面返回的「PAE」指標顯示,最大差異僅為該圖像使用的 8 位色彩值中的一個色彩值。也就是說,非常小。如此之小,以至於對圖像的微小更改或修改都會破壞隱藏在其中的信息。由於差異如此之小,您甚至不能使用具有有損壓縮的 JPEG 作為容器圖像的圖像格式,或任何其他有損圖像格式(包括 GIF)。此外,如果您使用了錯誤的「偏移密鑰」,您將無法獲得信息...

  magick -size 50x40+14+2 stegano:rose_message.png message_bad.gif
[IM Output]
您也可以使用區域設定來限制要隱藏訊息的影像區域。嘗試恢復訊息時,也需要相同的設定。這可能會讓在大型影像中尋找和解碼隱藏訊息變得更加困難,尤其是如果限制在一個「繁雜」的區域,難度可能會增加一個數量級。但請注意,這並不是一種非常安全的加密技術,尤其是在原始來源影像也 доступний 的情況下。對影像進行頻率分析通常會讓攻擊者知道其中隱藏了訊息。作為一種影像版權保護方法,Stegano 運算子 也是沒有用的,因為對影像的最小更改都會破壞訊息,從而降低其有效性。作為一種間諜工具,它也不是很好,因為對於合理大小的影像,「組合」的數量非常少。任何大致了解您在做什麼的人都可以很快破解它。最好還是堅持使用眾所周知且經過時間考驗的加密方法。它唯一真正的實際用途是作為一種有趣的工具,或者作為一種向現有影像添加少量雜訊的方法。

加密影像資料

-encipher」和「-decipher」運算子基本上會將影像資料加密成一堆亂碼。也就是說,在影像被解密之前,影像內容本身將完全無法辨識。例如,這可以用於保護公共服務上的敏感影像,以便只有擁有秘密通行碼的人才能查看它。但首先要提醒您的是……
不要將 JPEG、GIF 或任何其他「有損」影像編碼與加密一起使用
例如,讓我們使用儲存在一個不太「秘密」的檔案「pass_phrase.txt」中的通行碼來加密我們上面建立的秘密訊息影像。

  magick message.gif    -encipher pass_phrase.txt  \
          -depth 8 png24:message_hidden.png
[IM Output] ==> [IM Output]
加密後的影像假定它是使用 8 位元影像檔案格式儲存的。因此,建議在最終儲存到輸出檔案之前,透過設定「-depth 8」來強制執行該限制。

上面還需要「png24」,以確保輸出不是調色盤或顏色映射的「png8:」影像,因為這也無法正常工作。
如您所見,產生的影像看起來像是一堆垃圾,完全看不出影像的真實內容。現在,您可以在網路上發布該影像,只有知道確切原始通行碼的人才能恢復影像資料……

  magick message_hidden.png -decipher pass_phrase.txt message_restored.gif
[IM Output]
但請注意,如果影像資料以某種方式損壞,您將無法恢復它。這包括如果 PNG 使用灰度影像格式類型儲存。因此,只能使用無損影像格式,例如 PNG、MIFF、TIFF,甚至像素列舉文字。但是,使用有損影像格式(例如 JPEG、PNG8 和 GIF)會損壞影像資料,從而破壞最終的加密結果。請注意,任何可能描述影像的元數據都將保持清晰可見。這意味著,您可以使用影像自身的「註釋」字串作為通行碼來加密影像,或者使用經過一些較短密碼加密的註釋。這是一個簡單的想法,可以使通行碼更加多變。加密影像可能只是一個步驟。對結果進行進一步處理可以產生無法簡單解密的影像,而無需額外處理。例如,我在這裡使用了一些簡單的非破壞性變形來混淆任何試圖以正常方式解密影像的人。

  echo "password" | magick message.gif -encipher - \
                      -transpose  -depth 8   png24:message_obfuscate.png
  echo "password" | magick message_obfuscate.png -transpose \
                      -decipher -  message_restored_2.png
[IM Output] ==> [IM Output] ==> [IM Output]
如果您在上面的解密命令中沒有加入 "-transpose",圖片將無法正確解密。另請注意,由於使用了串流加密法(請參閱下方的專家說明),因此僅使用某種 "-roll" 並不能阻止圖片被解密,至少部分可以解密。請注意,在上面的例子中,我沒有使用檔案來儲存「密碼」,而是使用標準輸入將密碼輸入到 "magick" 命令中,這讓您可以使用其他程式或命令從使用者取得密碼、產生密碼或其他方法,而不必使用包含明文密碼的文字檔案。密碼也可以從其他可自由下載的檔案和圖片產生。例如,您可以使用知名且可自由下載的參考圖片的簽章或註釋字串來加密和解密 "message.gif" 圖片。例如,在這裡我使用 "rose.gif" 圖片的簽章來加密和解密 "message.gif" 圖片。

  magick identify -format %# rose.gif |\
    magick message.gif  -encipher - -depth 8    png24:message_signed.png
  magick identify -format %# rose.gif |\
    magick message_signed.png   -decipher -   message_restored_3.png
[IM Output]  + [IM Output] ==> [IM Output]  + [IM Output] ==> [IM Output]
從 IM v6.4.8-0 開始,"-encipher" 和 "-decipher" 使用的檔案可以是二進制檔案。因此,您甚至可以直接使用圖片本身作為密碼。

  magick message.gif   -encipher rose.gif  -depth 8  png24:message_binary.png
  magick message_binary.png   -decipher rose.gif   message_restored_4.png
[IM Output]  + [IM Output] ==> [IM Output]  + [IM Output] ==> [IM Output]
在 IM v6.4.8-0 之前,二進制檔案會在遇到第一個「NULL」字元時停止。如果使用 PNG 圖片,這種情況很快就會發生。
這種技術是精確的(除非某些資料在傳輸過程中遭到破壞)。因此,您可以使用它來加密包含其他隱藏資訊的圖片,例如 隱寫術圖片。這表示即使當局解密了圖片,或強迫您透露密碼,他們看到的也只是實際的圖片,而該圖片可能不是最終隱藏的圖片。
"-encipher" 和 "-decipher" 運算子是在 IM v6.3.8-6 中加入的,但需要您在建構設定中加入 "--enable-cipher" 選項。然而,從 IM v6.4.6 開始(什麼時候改的?),這個設定項目就不再需要了,它變成了標準設定。因此,您現在應該可以直接使用它了。
加密法是使用從區塊加密法實作的自同步串流加密法來實作的。

這表示即使圖片因為傳輸錯誤而遭到部分損壞,您仍然可以解密部分下載的圖片,即使圖片的某些部分可能已經損壞。您也不需要下載整個圖片才能解密和檢查成功下載的部分。

但您確實需要密碼才能成功解密圖片,因為這是一種非常強大的加密方式。

將圖片像素化

圖片像素化基本上是用來將圖片變成一組大型彩色「像素」,只顯示原始圖片的模糊輪廓。這兩種技術都涉及縮小圖片(以產生較少的像素),然後以某種方式放大它們,以便使用 縮放運算子取樣運算子 建立「像素區塊」來產生顏色區塊。決定使用什麼顏色的正是圖片縮小的方式。單一像素樣本或合併的平均顏色。

  magick rose: -sample 25%  -scale 70x46\!  rose_pixelate_sampled.gif
  magick rose: -scale  25%  -scale 70x46\!  rose_pixelate_scaled.gif
  magick rose: -resize 25%  -scale 70x46\!  rose_pixelate_resized.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output]
如您所見,「取樣」區域的「像素」會更加清晰(鋸齒狀),而其他兩個區域則使用合併或平均的顏色,這往往會產生更柔和但更準確的「像素」顏色表現。另請參閱 保護某人的匿名性,以瞭解如何僅在圖片的較小遮罩區域(例如人臉)上使用此功能。

像素網格

將影像網格化的過程與像素化影像非常相似。在這種情況下,我們只想放大影像,以產生影像細節的不同像素級視圖。通常是極小的影像。最簡單的方法就像先前的範例,只需縮放一個小影像,即可放大像素。

  magick rose: -crop 10x10+12+20 +resize  grid_input.png
  magick grid_input.png  -scale  1000%  grid_scale.png
[IM Output] ==> [IM Output]
簡單縮放的問題在於,在像素顏色相似的區域中,您可能難以看到個別的「像素塊」。我們需要在像素周圍添加邊框來分隔它們。為此,我們需要覆蓋生成的圖塊遮罩。請參閱使用記憶體中已有的影像進行平鋪,瞭解在單一命令中使用生成的平鋪影像的各種方法。
在這裡,我們生成一個黑白「網格」,並使用螢幕合成(覆蓋白色,同時保留黑色區域)進行覆蓋。

  magick -size 10x10 xc: -draw 'rectangle 1,1 9,9' -write mpr:block +delete \
          grid_input.png -scale 1000% -size 101x101 tile:mpr:block \
          +swap -compose screen -composite grid_blocks.png
[IM Output]
請注意,用於生成圖塊的大小是縮放比例*影像大小+間隙大小(在本例中為 10*10+1 => 101)。我還交換了兩個影像,以便最終影像大小來自圖塊影像,而不是來自大小縮小一個像素的縮放影像。然而,由於我使用圖塊影像作為目標,這可能會遺失原始影像中的任何影像中繼資料。
在這裡,我生成圓形「點」的顏色,但這次使用乘法合成(覆蓋黑色,同時保留白色區域)。

  magick -size 10x10 xc: -draw 'circle 5,5 1,3' -negate \
               -write mpr:spot +delete \
          grid_input.png -scale 1000% -size 101x101 tile:mpr:spot \
          +swap -compose multiply -composite grid_spots.png
[IM Output]
您也可以透過反轉圖塊覆蓋(黑色區域變為透明)並使用複製不透明度合成而不是乘法來使網格邊框透明。也可以添加其他顏色,但要使其生效,您必須使用實際包含真實透明度的圖塊影像。為此,您需要將黑白圖塊影像轉換為形狀遮罩
例如,在這裡,我使用基本形態運算子在彩色覆蓋中生成菱形「孔」。為此,繪製單個「種子」像素,並使用菱形形態核心進行擴展。

  magick -size 10x10 xc: -draw 'point 5,5' -morphology Erode:4 Diamond \
          -background Navy -alpha shape -write mpr:diamond +delete \
          grid_input.png -scale 1000% -splice 1x1+0+0 \
          -size 101x101 -background none tile:mpr:diamond \
          -alpha set -compose Over -composite grid_diamonds.png
[IM Output]
請注意,「tile:」編碼器會將影像中的任何透明度替換為目前的背景顏色。如果您想保留平鋪影像的透明度,請設置「-background none」或「-compose Src」。前者比較簡單。
請注意,從技術上講,Alpha 形狀可以在保存圖塊影像之前或在平鋪圖塊影像之後、覆蓋之前完成。您可以自行選擇。最後一種技術是使用不良的重新採樣濾波器來產生重新採樣失敗,以生成每個像素的別名圓圈。這不是一個很好的技術(錯誤地使用影像處理失敗),但它確實形成了一個像素網格。

間隔圖塊

一個類似的問題是在影像中間隔排列圖塊網格。這不僅僅是將單個像素放大為「像素塊」,而是在影像的矩形區域之間插入空間。也就是說,以規則的間隔將額外的像素拼接到影像中。目前最好的解決方案是將影像分解為行和列,並在每個圖塊上拼接額外的間距,然後再將圖塊附加在一起。舉例來說...

  magick rose: -background SkyBlue \
          -crop 10x0 +repage -splice 3x0 +append \
          -crop 0x10 +repage -splice 0x3 -append \
          grid_tile.png
[IM Output] ==> [IM Output]
這是另一種方法,它也将原始影像分成图块,但随后使用一些DIY FX 表达式从图块的旧位置计算其新位置。

  magick rose: -crop 10x10 \
          -set page '+%[fx:page.x+3*page.x/10]+%[fx:page.y+3*page.y/10]' \
          -background skyblue -layers merge +repage  grid_tile_fx.png
[IM Output]
上面程式碼範例中的數字 '3' 是要新增的間隔寬度,'10' 是區塊大小。您只需要在結果中新增邊框或其他邊緣。 只要稍加修改,您甚至可以為上述網格中每個區塊的放置新增一些隨機的「抖動」,以獲得較不規則的效果。 這兩種方法的問題在於,產生大量的小圖像,然後再將它們合併在一起會產生大量的工作。 尤其是對於非常小的區塊大小。 一個更好的方法是對「拼接運算子」進行特殊擴展,在 IM 論壇討論區的「拼接(新增區塊網格間隙)」中有提出。

電腦視覺轉換

邊緣偵測

-edge」運算子會突顯圖像中色彩漸層的區域。 它是一個灰階運算子,因此會分別應用於三個色彩通道。

  magick mask.gif -edge 1   mask_edge_1.gif
  magick mask.gif -edge 2   mask_edge_2.gif
  magick mask.gif -edge 3   mask_edge_3.gif
  magick mask.gif -edge 10  mask_edge_10.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output]
如您所見,邊緣僅新增到色彩漸層超過 50% 為白色的區域! 我不知道這是錯誤還是故意的,但这表示上面的邊緣幾乎完全位於原始遮罩圖像的白色部分。 在使用「-edge」運算子的結果時,這個事實可能非常重要。 例如,如果您要邊緣偵測包含黑色輪廓的圖像,「-edge」運算子會將黑色線條「孿生」,產生奇怪的結果。

  magick piglet.gif  -colorspace Gray  -edge 1 -negate  piglet_edge.gif
[IM Output] ==> [IM Output]
但是,透過在進行邊緣偵測之前反轉圖像,孿生線條會向內合併在一起,從而去除「孿生線條」效果。

  magick piglet.gif -colorspace Gray \
                 -negate -edge 1 -negate    piglet_edge_neg.gif
[IM Output]
我發現邊緣往往太過銳利,導致結果圖像的邊緣不平滑。 因此,我發現對結果進行非常輕微的模糊處理可以大幅改善外觀。

  magick piglet_edge_neg.gif  -blur 0x.5  piglet_edge_blur.gif
[IM Output]
在這裡,我已將邊緣偵測應用於彩色圖像和灰階版本,以向您展示其對照片類圖像的效果。

  magick rose:                  -edge 1  rose_edge.gif
  magick rose: -colorspace Gray  -edge 1  rose_edge_grey.gif
[IM Output] [IM Output]
如您所見,如果沒有將圖像轉換為灰階,則不同色彩通道的邊緣會完全獨立地產生。

Canny 邊緣偵測器

從 IM v6.8.9-0 開始,IM 現在支援 Canny 邊緣偵測器。 (請參閱 IM 論壇上的公告範例)。 這是一種非常先進的邊緣偵測演算法,可以在所有銳利邊緣產生非常強(二進制)的單像素寬線條,並且幾乎沒有雜訊干擾。 例如,在這裡,我們將其應用於我們上面使用的測試圖像。

  magick mask.gif           -canny 0x1+10%+30%  mask_canny.gif
  magick piglet.gif         -canny 0x1+10%+30%  piglet_canny.gif
  magick piglet.gif -negate -canny 0x1+10%+30%  piglet_canny_neg.gif
  magick rose:             -canny 0x1+10%+30%  rose_canny.gif
[IM Output] ==> [IM Output]
[IM Output] [IM Output] [IM Output]
如您所見,它產生的結果比上面的邊緣運算子清晰得多。 模糊的反鋸齒邊緣對結果幾乎沒有影響,產生了細的點陣圖線條。 此外,正如小豬圖像所示,它不像之前的邊緣運算子那樣放置在特定的一側。 因此,反轉輸入圖像沒有效果。 但是,與所有邊緣偵測器一樣,它在處理具有「繁忙」背景的真實世界圖像(例如內建的玫瑰圖像)時可能會出現問題。 這種乾淨的結果在後面的霍夫線變換中非常重要。

反鋸齒形狀的邊緣輪廓

一般邊緣偵測方法的最大問題是結果高度鋸齒狀。 也就是說,無論形狀是平滑的(反鋸齒)還是鋸齒狀的,它都會產生非常像階梯的像素效果。 例如,這裡有一個平滑的反鋸齒語音氣泡(「WebDings」字體字元 '(')。

  magick -size 80x80 -gravity center -font WebDings label:')' voice.gif
[IM Output]
以下是其邊緣偵測圖像...

  magick voice.gif -edge 1 -negate   voice_edge.gif
[IM Output]
如您所見,它看起來很糟糕,邊緣外部有一些輕微的反鋸齒,而線條內部則完全是鋸齒狀(階梯狀)的外觀。 反轉圖像會在圖像外部產生相似的輪廓,但線條外部也有強烈的鋸齒。

  magick voice.gif -negate -edge 1 -negate   voice_edge_negate.gif
[IM Output]
當你已經擁有一張具有反鋸齒邊緣的圖像時,另一種選擇是生成原始形狀「抖動」副本的差異圖像。例如,這裡我們找到了原始圖像和向右偏移(或抖動)1 像素的圖像之間的差異圖像。

  magick voice.gif \( +clone -roll +1+0 \) -compose difference -composite \
          -negate   voice_jitter_horiz.gif
[IM Output]
請注意,這不會為水平傾斜邊緣產生良好的邊緣。但是,通過組合水平和垂直抖動的差異圖像,我們可以獲得形狀的非常好的抗鋸齒輪廓。

  magick voice.gif \
          \( -clone 0 -roll +1+0 -clone 0 -compose difference -composite \) \
          \( -clone 0 -roll +0+1 -clone 0 -compose difference -composite \) \
          -delete 0  -compose screen -composite -negate  voice_jitter_edge.gif
[IM Output]
這種技術還具有無論遮罩是否被反轉都能工作的優點。但是請注意,結果相對於原始圖像有 1/2 像素的偏移,因此可能需要一些進一步的「變形」處理來重新對齊原始形狀或輪廓,如果需要組合兩者以獲得想要的結果。

點陣圖形狀的邊緣輪廓

點陣圖圖像要困難得多,因為它們沒有任何可以用於生成平滑輪廓的抗鋸齒像素。例如,這裡是一個從「WebDings」字體(字元「Y」)中提取的精美「心形」形狀。但是我特意將其生成為別名點陣圖,以模擬從網路上下載的糟糕點陣圖圖像。例如包含透明度的 GIF 圖像的輪廓。

  magick +antialias -size 80x80 -gravity center \
          -font WebDings label:Y   heart.gif
[IM Output]
所以我們有這張糟糕的圖像,但我們想找到圖像的輪廓而不是它的形狀。直接使用邊緣檢測只會在點陣圖形狀的外部生成一個純粹的點陣圖邊緣。

  magick heart.gif -edge 1 -negate   heart_edge.gif
[IM Output]
反轉邊緣會生成邊緣圖像,但用於黑色區域的內部。

  magick heart.gif -negate -edge 1 -negate   heart_edge_negate.gif
[IM Output]
通過添加以上兩者,你將獲得一個以點陣圖形狀邊緣為中心的 2 像素邊緣。

  magick heart.gif \( +clone -negate \) -edge 1 \
          -compose add -composite  -negate  heart_edge_double.gif
[IM Output]
如你所見,生成的圖像在輪廓中具有高度鋸齒狀的「階梯」狀效果,即使原始圖像本身在這方面還不錯。這不是一個好的解決方案。可以使用「EdgeIn」形態學方法或其他類似方法創建稍微好一點的邊緣。

  magick heart.gif  -negate -morphology EdgeIn Diamond -negate heart_edgein.gif
[IM Output]
並且只需使用調整大小以正確模糊邊緣,然後使用 Solarize 提取形成邊緣的中间灰色像素,就可以實現類似的效果。通過添加「-filter Cubic」設置或其他一些 重採樣濾鏡 可以生成更厚的邊緣。

  magick heart.gif -resize 400% -resize 25% \
          -solarize 50% -evaluate multiply 2 -negate heart_resize.gif
[IM Output]
或者,為了獲得更可控的模糊效果,你可以僅模糊形狀並以類似的方式提取邊緣。我發現「0.7」的模糊度最好,並且為了加快速度,將限制設置為 3 個像素。

  magick heart.gif -blur 3x.7 -solarize 50% -level 50%,0 heart_blur.gif
[IM Output]
請注意 Level Operator 的使用,它等同於上一個示例中使用的「-evaluate multiply 2 -negate」。使用抗鋸齒邊框,如果你只想平滑原始形狀而不是獲得其輪廓,現在可以重新添加原始形狀。請記住,輪廓精確定位在原始圖像的邊緣,因此其尺寸將比前面的示例大半分辨率。 * 你知道從形狀(抗鋸齒或點陣圖)生成抗鋸齒輪廓的任何其他方法嗎?如果是這樣,請發郵件給我或 IM 論壇。你將被記入功勞。*

使用光柵圖向量轉換器進行邊緣化

最理想的解決方案之一是使用非 IM 的「*點陣圖轉向量圖*」轉換程式,將此點陣圖形狀變為向量輪廓。可以做到這一點的程式包括:「ScanFont」、「CorelTrace」、Abobe 的「Streamline」和「Vector Magic」。然而,其中大多數都需要花費一些費用。「VectorMagick」和另一個追蹤程式「AutoTracer」則提供免費使用的線上影像轉換器。其他免費的解決方案包括「AutoTrace」或「PoTrace」。歡迎提供更多建議。這些追蹤程式使用起來很簡單,但通常需要對影像進行一些預先和後續的設定。它們支援的輸入格式有限,並且會輸出「平滑」輸入影像形式的向量影像。我偏好「AutoTrace」,因為它不會縮放產生的 SVG 資料,因此會產生標準線條粗細,但是您不能在「管道」中使用它。為了獲得最佳效果,最好確保我們只提供給它基本的點陣圖,我們可以透過在將輸入影像轉換為 AutoTrace 可以理解的影像格式時對其進行閾值處理來確保這一點。然後,我可以將該影像轉換為 SVG 向量影像。

  magick heart.gif -colorspace gray -threshold 50% heart_tmp.pbm
  autotrace -output-format svg -output-file heart.svg heart_tmp.pbm
  magick heart.svg heart_svg.gif
  rm -f heart_tmp.pbm
[IM Output] ==>
[IM Text]
==> [IM Output]
從 IM v6.4.2-6 開始,您可以使用「autotrace:」影像輸入委託直接執行上述步驟。這只需要安裝「autotrace」命令。例如:

  magick autotrace:heart.gif  heart_traced.gif
[IM Output]
如果您的 IM 是使用「AutoTrace」委託函式庫構建的,您也可以讓 IM 直接從記憶體中的影像產生 SVG 影像。有關詳細資訊,請參閱SVG 輸出處理。例如....

  magick heart.gif  heart_2.svg
[IM Text]
現在,SVG 輸出當然會呈現原始影像的平滑版本,這不是我們在此範例中真正想要的。但是,由於我們現在已經以*向量形式*獲得了點陣圖的形狀,因此我們可以簡單地調整 SVG「style」屬性,以便「stroke」(描邊)輪廓,而不是「fill」(填充)形狀。然後,可以將修改後的 SVG 重新輸入 ImageMagick,以重新建立乾淨的輪廓點陣圖。例如....

  cat heart.svg |
    sed 's/"fill:#000000[^"]*"/"fill:none; stroke:black;"/' |
      magick svg:- heart_outline.gif
[IM Output]
是的,這有點麻煩,但是平滑的抗鋸齒效果值得付出努力。如果可以將輪廓或其他修改指定為「autotrace」命令本身的選項,那就太好了,但目前尚不支援此功能。您還可以進一步修改 SVG 輸出以加粗邊緣,或指定其他筆畫或背景顏色,更改向量邊緣形狀的填充顏色。例如,在這裡,我們產生了一個形狀的較粗輪廓,並帶有紅色填充,所有這些都經過了良好的抗鋸齒處理。

  cat heart.svg |
    sed 's/"fill:#000000;[^"]*"/"fill:red; stroke:black; stroke-width:5;"/' |
        magick svg:- heart_outline_thick.gif
[IM Output]
如此完美的愛心不可能以任何其他方式從點陣圖形狀產生。我們也可以只提取「d="..."」路徑元素,直接用作SVG 路徑字串,用於繪製命令。這將允許您將任何其他 IM 繪製設定與該向量輪廓一起使用,讓您可以完全控制最終結果。有關使用「AutoTrace」程式的另一個範例,請參閱使用 AutoTrace 進行骨架化

霍夫線偵測器

霍夫線條偵測器("-hough-lines" 於 IM v6.8.9-1 版本加入)是一個非常複雜的轉換,包含許多階段(詳情請參閱維基百科:霍夫變換)。基本上,它旨在檢查圖像,在黑色背景上尋找白色線條,並嘗試返回圖像中存在的任何線段(線性像素序列)的確切位置。這對於移除圖像旋轉或確定圖像中的透視變換非常重要,因此可以重複或移除。以下是運算符的完整選項集

  -background {background} -stroke {line_color} -hough-lines {W}x{H}+{threshold}
顏色(*背景*和*線條顏色*)用於設置結果圖像中線條的顏色(如果您實際繪製它們)。霍夫運算符的參數(*W*}x{*H*}+{*門檻值*})用於定義用於在中間“搜尋圖像”中尋找“峰值”的濾波器的大小和門檻值。也就是說,它控制著它實際“找到”我們試圖檢測的線條的程度(見下文)。您可以調整這些參數以幫助找到線條。例如,讓我們嘗試在矩形圖像中找到線條。首先,我們需要使用Canny 邊緣偵測器將圖像簡化為線條,以便獲得清晰的結果。

  magick shape_rectangle.gif -canny 0x1+10%+30% rectangle.gif
[IM Output] ==> [IM Output]
現在讓我們將霍夫線條偵測器應用於此圖像。

  magick rectangle.gif -background black -stroke red \
          -hough-lines 5x5+20   rectangle_lines.gif
[IM Output]
如您所見,找到了 5 條線,其中 2 條非常靠近。出現額外線條的原因是圖像中的矩形並不完美。現在,雖然我顯示的是光柵(GIF)圖像結果,但霍夫運算符實際上生成的是Magick 向量圖形格式的向量圖像。這意味著您可以列出線條信息以供進一步處理。

  magick rectangle.gif -background black -stroke red \
          -hough-lines 5x5+20   rectangle_lines.mvg
[IM Text]
請注意,線條是從圖像的一個邊緣(使用浮點值)繪製到另一個邊緣的。從這裡您可以看到,第二條和第三條線是靠近的兩條線。MVG 輸出中的註釋提供了線條在圖像中“擊中”的累積像素數,因此可以很好地指示線條在圖像中的強度。該值始終大於您為“-hough-line”運算符提供的門檻值。由此可見,第一條和最後一條線(非常接近)的強度大致相等,因此很難選擇其中一條。如果發生這種情況,建議您嘗試改進邊緣檢測步驟。請注意,MVG 圖像沒有定義任何顏色。此示例中的顏色設置實際上並未使用。只有在將上述結果轉換為“光柵”圖像時實際“繪製”向量時,才會使用顏色,就像我們之前所做的那樣。
您還可以通過使用特殊的定義來查看中間“搜尋圖像”或“累加器”,它會在每個方向上尋找白色像素。

  magick rectangle.gif \
          -define hough-lines:accumulator=true -hough-lines 5x5+20 \
          -delete 0 -contrast-stretch 0.1% rectangle_accumulator.gif
[IM Output]
此定義只會將「搜尋影像」附加到影像結果中,在這種情況下,我們將其刪除。我們還對「累積值」應用了一些對比度,使其更加可見。這是霍夫偵測器參數正在搜尋的影像。影像始終為 180 像素寬(線條角度每度 1 像素),而高度則是影像對角線長度的兩倍。因此,峰值的位置將直接定義線條的角度,以及線條相對於輸入影像中心點的垂直距離。也就是說,X 坐標是以度為單位的角度,而 Y 坐標是從中心點到對角線距離的距離,範圍從負對角線距離到正對角線距離。如果仔細觀察右下角的峰值,您就會明白為什麼我們最終得到兩條線而不是一條線。這裡的峰值是「雙胞胎」,它們之間有一個小的間隙。該演算法基於 Fred Wienhaus 的「houghlines」腳本,但在「垂直距離」累積處理方面有所不同。

局部自適應閾值

建構中
-lat」運算子會嘗試根據周圍視窗中像素的值,自適應地對每個像素進行閾值處理。這通常用於對背景不均勻(即照明不均勻)的影像進行閾值處理。它基於一個假設,即一個小視窗中的像素將具有大致相同的背景顏色和大致相同的前景顏色。
For example.
   magick input.png -lat 17 output.png
在上面的例子中,使用一個 17 像素的方形「視窗」來確定每個點的影像平均顏色,如果像素比這個平均值暗,則將其設為黑色,如果比這個平均值亮,則將其設為白色。較小的視窗大小將使閾值對照明的微小變化更敏感,計算速度更快,但更容易受到影像雜訊的影響。
Example
較大的視窗大小將使閾值對照明的微小變化不太敏感,計算速度較慢,受影像雜訊的影響較小。這具有使閾值選擇對像素值的微小變化或多或少敏感的作用。
Example
The window does not need to be square.  for example...
  magick input.png -lat 15x25 output.png
您還可以提供一個偏移量,該偏移量將添加到計算出的平均顏色中,從而使每個像素的局部閾值變亮或變暗。例如,這可以用於減少雜訊的影響或像素值的微小變化的影響。
  magick input.png -lat 15x25+2%
當使用掃描器或數位相機獲取影像時,通常會發生這些微小的變化。使用正偏移值可以降低自適應閾值對像素值微小變化的敏感度。使用負閾值可以提高自適應閾值對像素值微小變化的敏感度。或者,可以在使用「-lat」處理影像之前降低影像中的雜訊。
In summary, each pixel is thresholded using the following logic:
  AVG = average value of each pixel in the window
  IF (input pixel is > AVG + OFFSET)
     Output pixel is BLACK
  else
     Output pixel is WHITE

---

An alternative is to subtract a blurred copy of the original image
using (Modulus) Subtraction, then thresholding.

   magick rose: -colorspace gray -lat 10x10+0% x:

is roughly equivalent to...

   magick rose: -colorspace gray \( +clone -blur 10x65535 \) \
           -compose subtract -composite -threshold 50%  x:

The special "-blur 10x65535"  is a linear averaging blur limiting itself to a
10x10 window.

The 'Subtract' composition being a mathematical modulus type of operation will
wrap the values that goes negative back round to a value greater than 50%.

If you want to include an offset you can do so by also subtracting a solid
color background image by using a -flatten...  for example

   magick rose: -colorspace gray -lat 10x10+10% x:

is roughly equivalent to...

   magick rose: -colorspace gray \( +clone -blur 10x65535 \) \
           -compose subtract -background gray10 -flatten -threshold 50%  x:

以上內容修改自 D Hobson <dhobson@yahoo.com> 提供的初始筆記。
   -adaptive-sharpen
        Sharpen images only around the edges of the images

   -segment cluster-threshold x smoothing-threshold
         Segmentation of the color space (not image objects)
         This can produce very verbose output.
         This applies the "fuzzy c-means algorithm" if you want to know more.

Also related is -despeckle. to remove single off color pixels.

Generate a 3d stereogram of two images (one for each eye)
This is also known as an anaglyph
  magick composite left.jpg right.jpg -stereo anaglyph.jpg


陰影 3D 高光

陰影使用

我一直認為「-shade」運算器是 ImageMagick 所提供最有趣的運算器之一。此運算器的說明文件只粗略地提示了它的功能。我做了很多個人研究才了解這個運算器的意義,甚至找出如何最好地利用它為 IM 使用者提供的功能。基本上,這個運算器的作用是假設給定的圖像是所謂的「高度場」。也就是說,一個灰階圖像代表了某個物體或地形的表面。顏色「白色」代表圖像中的最高點,而「黑色」代表最低點。這種表示方法來自 1980 年的電腦視覺研究,當時使用了一張具有強烈「相機光」的照片,使近處的點變亮,而遠處的點變暗。
由於「-shade」需要灰階圖像,該運算器會自動移除輸入圖像中的任何顏色。同樣地,圖像中可能存在的任何透明度對運算器來說完全沒有用,並且會被忽略。
現在「-shade」會將這個灰階高度場照亮。其結果就是所產生光影的呈現。請記住,您必須將輸入圖像想像成一個「表面」,才能理解輸出結果。為了進行演示,我們需要一個「高度場」圖像,讓我們來繪製一個。

  magick -font Candice -pointsize 64 -background black -fill white \
          label:A  -trim +repage -bordercolor black -border 10x5 \
          shade_a_mask.gif
[IM Output]
這個圖像也等同於形狀的「遮罩」,它不僅經常被用作「-shade」的輸入,也被用於遮罩圖像,以便從陰影結果中裁剪出相同的形狀。請參閱下面的遮罩陰影圖像。對於「-shade」運算器來說,這個圖像看起來像一個黑色的平面,上面有一個白色的高原垂直向上。因此,只有這個圖像的邊緣才會產生有趣的效果。為此,這兩個參數定義了光線照射的方向。第一個參數是光線來自的*方向*。因此,角度「0」度將來自東方(左側),「90」度是從北方(或頂部)逆時針方向,依此類推。例如...

  magick shade_a_mask.gif   -shade    0x45   shade_direction_0.gif
  magick shade_a_mask.gif   -shade   45x45   shade_direction_45.gif
  magick shade_a_mask.gif   -shade   90x45   shade_direction_90.gif
  magick shade_a_mask.gif   -shade  135x45   shade_direction_135.gif
  magick shade_a_mask.gif   -shade  180x45   shade_direction_180.gif
你應該明白了。光線可以來自任何方向。另一個參數是*仰角*,代表光源與地面的夾角。您可以將其想像成白天太陽的高度,因此「0」是黎明,「90」是正上方。
[diagram]

  magick shade_a_mask.gif   -shade  90x0    shade_elevation_0.gif
  magick shade_a_mask.gif   -shade  90x15   shade_elevation_15.gif
  magick shade_a_mask.gif   -shade  90x30   shade_elevation_30.gif
  magick shade_a_mask.gif   -shade  90x45   shade_elevation_45.gif
  magick shade_a_mask.gif   -shade  90x60   shade_elevation_60.gif
  magick shade_a_mask.gif   -shade  90x75   shade_elevation_75.gif
  magick shade_a_mask.gif   -shade  90x90   shade_elevation_90.gif
如您所見,當 仰角 為 '0' 時,形狀僅在其光線照射的一側被突出顯示。其他所有部分都是黑色的,因為沒有光線照射到任何其他表面。我稱之為「黎明高光」,它有其特殊的用途。這就帶我們到第一個需要注意的事項。一張被「-shade」處理過的圖像,其陰影或暗部區域通常比高光區域多。陰影分佈不均勻。隨著光線在「高度場」圖像上越來越高,圖像的整體亮度會變得更白,直到「正午」或 仰角 為 '90' 時,任何平坦區域都呈現亮白色,只有斜坡和邊緣呈現灰色陰影,其中最大值為中灰色,或「懸崖狀」的坡度變化。這種「正午」圖像是另一種特殊情況,有點像邊緣偵測系統,儘管對於銳利邊緣,它的寬度介於 2 到 4 個像素之間。我過去曾使用這種圖像為「-shade」圖像的斜角邊緣生成遮罩,以便使平坦區域變得透明。如果 仰角 超過 '90' 度,您將獲得與光線來自另一個方向時相同的結果。因此,參數 '0x135' 將產生與 '180x45' 完全相同的結果。負 仰角 也會產生相同的結果,就好像光線是從下方照射到「半透明」的表面上一樣。因此,'0x-45' 將與 '0x45' 相同。換句話說,對於特定的陰影,通常還有其他四個參數也會產生相同的結果。根據以上所述,我認為 '120x45' 的參數最適合直接使用陰影輸出。例如,在這裡它會創建一些斜角文字…

  magick -size 320x100 xc:black \
          -font Candice -pointsize 72 -fill white \
          -draw "text 25,65 'Anthony'" \
          -shade 120x45  shade_anthony.jpg
[IM Output]
-shade」 的主要問題之一是實際產生的斜角厚度。像我上面使用的銳利邊緣始終會產生大約 4 個像素寬的斜角,包括遮罩區域內外。除了在使用「-shade」運算符之前和之後調整圖像大小之外,沒有辦法調整此厚度。如果您想確切了解特定 仰角 照明角度下「平面區域」的亮度,則可以使用以下命令對平面純色表面進行陰影處理。

  magick -size 50x50 xc:white -draw 'circle 25,25 20,10' \
          -blur 0x2  -shade 0x45   -gravity center -crop 1x1+0+0 txt:-
[IM Text]
如您所見,'45' 度的 仰角 產生的平面顏色相當明亮,約為 70% 的灰色,這是一個適合一般觀看的合理灰度。但是,如果您打算使用陰影為各種形狀生成 3D 高光,那麼實際的灰度級別就變得非常重要。我們將在稍後的 創建疊加高光 中看到這一點。基本上,「-shade」運算符就是這樣。然而,有效地使用它會帶來一系列我們接下來要探討的技術和可能性。

遮罩陰影形狀

如上所述,簡單的「遮罩」形狀通常與「-shade」一起使用,以從簡單的形狀生成複雜的 3D 效果。例如,讓我們對直接陰影遮罩圖像執行此操作。

  magick shade_direction_135.gif  shade_a_mask.gif \
          -alpha Off -compose CopyOpacity -composite   shade_beveled.png
[IM Output]  + [IM Output] ==> [IM Output]
請注意,「-shade」運算符生成的大約一半的斜角實際上落在了遮罩區域之外。換句話說,遮罩時直線斜角會減半。另一方面,垂直或「正午」陰影圖像(使用 '90' 度 仰角)可用於僅提取斜角邊緣,使圖像中心保持中空。

  magick shade_direction_135.gif \
          \( shade_elevation_90.gif -normalize -negate \) \
          -alpha Off -compose CopyOpacity -composite   shade_beveled_edge.png
[IM Output]  + [IM Output] ==> [IM Output]
請注意,'midday' 陰影圖像雖然提供了一種遮罩「-shade」運算子效果位置(和強度)的方法,但實際上並未完全涵蓋這些效果。通過將 'midday' 陰影圖像與原始遮罩組合,您可以稍微增加該遮罩的大小,以產生更好的遮罩斜面圖像。
[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]

  magick shade_direction_135.gif \
          \( shade_elevation_90.gif -normalize -negate \
             shade_a_mask.gif -compose screen -composite \) \
          -alpha Off -compose CopyOpacity -composite   shade_beveled_plus.png
[IM Output]
請記住,使用 IM v6,您可以在同一個命令中生成我之前生成的「陰影」圖像。因此,以上內容可以完全從頭開始生成。舉個例子。

  magick -font Candice -pointsize 72 -background black -fill white \
          label:X  -trim +repage -bordercolor black -border 10x5 \
          \( -clone 0 -shade  135x45 \) \
          \( -clone 0 -shade  0x90  -normalize -negate \
             -clone 0 -compose screen -composite \) \
          -delete 0 -alpha Off -compose CopyOpacity -composite \
          shade_beveled_X.png
[IM Output]

陰影形狀影像

Alpha 提取運算子 不僅可以從形狀圖像中提取 Alpha 色版作為灰度遮罩,還可以保留「關閉」Alpha 色版中的形狀。由於它是「關閉」的,因此它不會被許多圖像處理運算子觸及,包括「-shade」,從而保留其細節。這意味著,對於形狀圖像,您可以提取形狀,進行處理,然後在完成所有圖像處理後,只需再次打開 Alpha 即可恢復透明度!例如,我在這裡在透明背景上繪製一個「心形」,對圖像進行一些模糊和陰影處理,然後恢復圖像的原始形狀輪廓。

  magick -size 100x100 -gravity center -background None \
          -font WebDings label:Y \
          -alpha Extract -blur 0x6 -shade 120x21 -alpha On \
          -normalize +level 15%  -fill Red -tint 100%    shade_heart.png
[IM Output]
我只能說,哇,真是省時!比之前的命令簡單多了,它需要進行所有額外的處理和圖像克隆。

圓角陰影邊緣

正如您在上一個示例中所見,通過模糊圖像形狀遮罩,邊緣「懸崖」的「坡度」將變得平滑,就好像被時間磨損了一樣。這會在陰影圖像中產生良好的圓潤效果。

  magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
          shade_circle_mask.gif
  magick shade_circle_mask.gif            -shade 120x45  shade_blur_0.gif
  magick shade_circle_mask.gif -blur 0x1  -shade 120x45  shade_blur_1.gif
  magick shade_circle_mask.gif -blur 0x2  -shade 120x45  shade_blur_2.gif
  magick shade_circle_mask.gif -blur 0x3  -shade 120x45  shade_blur_3.gif
  magick shade_circle_mask.gif -blur 0x4  -shade 120x45  shade_blur_4.gif
  magick shade_circle_mask.gif -blur 0x5  -shade 120x45  shade_blur_5.gif
如您所見,模糊不僅可以使邊緣變圓,還可以使光照效果變暗。您可以通過對結果進行歸一化來最大程度地提高對比度,以便將最亮和最暗的點分別恢復為純白色和黑色。

  magick shade_blur_3.gif   -normalize  shade_blur_3n.gif
[IM Output] ==> [IM Output]
這樣做的唯一缺點是,這通常也會使陰影圖像變暗。這是我們在 建立疊加高光 中需要考慮的事情。讓我們通過直接遮罩陰影圖像來完成它。

  magick shade_blur_3n.gif shade_circle_mask.gif \
          -alpha Off -compose CopyOpacity -composite   shade_blur_3n_mask.png
[IM Output] ==> [IM Output]
如您所見,模糊遮罩圖像可以很好地使所得形狀的邊緣變圓。

建立疊加高光

-shade」運算子的輸出非常出色,但您實際上很少需要形狀的純灰度圖像。需要的是一些顏色。然而,這並不容易,因為添加顏色的兩種主要方法,顏色著色中間調 只是對灰度重新著色,或「疊加」Alpha 合成,將灰色區域替換為圖像,這兩種方法都依賴於特殊形式的灰度圖像。也就是說,完美的中间灰色('grey50')被顏色或圖像替換,而較亮或較暗的灰色則適當地變亮和變暗顏色或圖像。這些特殊的灰度「疊加高光」圖像,其中未修改區域具有完美的中间灰色,使用「-shade」建立起來並不那麼簡單。但是,以下是我發現的一些更簡單的方法。使用「-shade」的 30 度仰角光照是為被著色形狀的平坦區域產生完美中间灰色的一種方法。例如,我在這裡為圖像著色,然後提取左上角像素以檢查圖像「平坦」部分的結果顏色。
[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]

  magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
          -blur 0x2  -shade 120x30           shade_30.png
  magick shade_30.png   -gravity center -crop 1x1+0+0 txt:-
[IM Image]
[IM Text]
不幸的是,更改上述命令中「-blur」的圓角效果也會改變陰影圖像的結果高光強度。也就是說,使用較大的模糊值不僅會產生邊緣圓潤的外觀,還會使高光變得非常暗淡,幾乎看不見。這意味著您需要為「-shade」圖像輸出的對比度添加更多內容,才能使高光作為疊加圖像有效。為了修正這個問題,我們需要一種從圓角調整中移除這種對比度效果的方法。典型的做法是對圖像進行「-normalize」處理,但是對 30 度的陰影圖像執行此操作會導致「平面」區域不再是完美的灰色。例如...

  magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
          -blur 0x2  -shade 120x30 -normalize   shade_30_norm.png
  magick shade_30_norm.png   -gravity center -crop 1x1+0+0 txt:-
[IM Image]
[IM Text]
然而,經過進一步的實驗,我發現使用 21.78 度的陰影仰角,在標準化後,會產生所需的完美中間灰色調,以及良好的強高光效果。

  magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
          -blur 0x2  -shade 120x21.78 -normalize   shade_21_norm.png
  magick shade_21_norm.png   -gravity center -crop 1x1+0+0 txt:-
[IM Image]
[IM Text]
由於陰影圖像現在通過「-normalize」運算符運行,因此用於「圓角」的「-blur」值將不再影響結果的最終強度。這是一種更好的方法。總之,對陰影圖像進行 標準化 會使中間色調偏離完美的灰色。現在,我們可以調整高光的輸出強度,使其完全獨立於其他調整。通常,由於標準化結果很極端,因此我們需要一個受控的去標準化或反差控制來將高光降低到所需的水平。調整結果高光的​​最簡單方法是用完美的灰色對圖像進行 著色。這會將圖像中的所有顏色級別都移向中心的純中間灰色。例如...

  magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
          \( +clone -blur 0x2 -shade 120x21.78 -normalize  \) \
          +swap -alpha Off -compose CopyOpacity -composite  shade_tint_0.png
  magick shade_tint_0.png -fill grey50  -colorize 10%  shade_tint_10.png
  magick shade_tint_0.png -fill grey50  -colorize 30%  shade_tint_30.png
  magick shade_tint_0.png -fill grey50  -colorize 50%  shade_tint_50.png
  magick shade_tint_0.png -fill grey50  -colorize 80%  shade_tint_80.png
線性著色高光的​​替代方法是使用 S 形非線性對比 來降低其整體效果,同時保留高光的​​極端亮/暗點。這應該為高光效果提供更「自然」的外觀,並且可以使高光更亮,就好像表面更具反射性一樣。但是,為了使此技術更有效,我們需要確保陰影結果中沒有純白色和黑色。這可以通過首先使用「0%」的「-contrast-stretch」而不是「-normalize」來實現,並且像我們上面所做的那樣,將結果去標準化一點。這似乎只是增加了生成高光疊加圖像的複雜性,但強調高光中的亮點使額外的處理變得值得。例如...

  magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
          \( +clone -blur 0x2 -shade 120x21.78 -contrast-stretch 0% \) \
          +swap -alpha Off -compose CopyOpacity -composite shade_sig_0.png

  magick shade_sig_0.png  -sigmoidal-contrast 10x50%  shade_sig-10.png
  magick shade_sig_0.png  -sigmoidal-contrast  5x50%  shade_sig-5.png
  magick shade_sig_0.png  -sigmoidal-contrast  2x50%  shade_sig-2.png

  magick shade_sig_0.png  +sigmoidal-contrast  2x50%  shade_sig+2.png
  magick shade_sig_0.png  +sigmoidal-contrast  5x50%  shade_sig+5.png
  magick shade_sig_0.png  +sigmoidal-contrast 10x50%  shade_sig+10.png
正如您所看到的,整體高光強度降低了,但反射光產生的亮點仍然保持亮度,只是尺寸減小了。結果是形狀具有更自然的「閃亮」外觀。這種技術的唯一缺點是也會產生陰影「斑點」,儘管這通常不太明顯。最後,我們可以將「高光點」與一般的 高光 降低相結合,以產生一組高度可配置的 高光 疊加生成器控件...
[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output]
[IM Output] [IM Output] [IM Output] <== [IM Output] ==> [IM Output] [IM Output] [IM Output]

  magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
          \( +clone -blur 0x4 -shade 120x21.78 -contrast-stretch 0% \
             +sigmoidal-contrast 7x50% -fill grey50 -colorize 10%  \) \
          +swap -alpha Off -compose CopyOpacity -composite shade_overlay.png
[IM Output]
總之,上面的例子有四個獨立的控件...
blur」:對形狀邊緣進行圓角處理 (0.001=斜面 2=平滑 10=圓角)
shade」:光線來自的方向 (120=左上方 60=右上方)
"sigmoidal" : 表面反射控制亮點 (1=平坦 5=良好 10=反射)
"colorize" : 亮點的整體對比度 (0%=明亮 10%=良好 50%=昏暗)
請注意,雖然以上範例已塑造成原始的「圓形」,但透明度應該在套用「覆蓋」合成「之後」才恢復,而不是之前。此外,如果您打算在相同形狀上重複使用一個亮點(在執行任何旋轉之後),您可以為您打算使用的每個形狀預先生成亮點覆蓋,並儲存結果以供多次重複使用。在 IM 討論區 中,從平面來源影像產生 3D DVD 封面就是重複使用陰影覆蓋的例子。我也強烈建議您試驗上述技巧,因為它們是讓您的平面形狀影像看起來更逼真的關鍵。如果您想出其他亮點的構想,請告訴我。
FUTURE:
   Color Tinting the Overlay image
   Overlay Alpha Composition with an Image

使用黎明陰影高光

在上面的「遮罩陰影影像」中,我們展示了「正午」或「正午」陰影影像(使用「90」的「仰角」)對於遮罩以及「-shade」產生的效果的位置和範圍非常有用。但是,形狀的水平或「黎明」陰影影像(使用「0」的「仰角」)也非常有用。例如,它可以用作白色或黑色影像的遮罩,以在形狀上產生單獨的亮點和陰影效果。這也可以用於確保形狀獲得大致相等的亮區和暗區(甚至是不相等的數量),因為我以完全可控的方式分別產生它們。
FUTURE: more detail here
請參閱第一個 進階 3D 標誌 以獲取使用此技巧的範例。

使用 FX,DIY 影像運算子

影像清單運算子「-fx」是一個通用的 DIY 運算子,它不屬於任何特定類別的 IM 運算子,因為它可以用於建立幾乎任何影像操作。這些頁面中介紹了它的使用方法,但在此我們將專門探討它的功能以及如何使用它們。這個指令的功能非常強大,它可以
  • 建立畫布、漸層、數學色彩映射。
  • 在影像和通道之間移動顏色值。
  • 以幾乎任何可以想像的方式調整影像顏色。
  • 平移、翻轉、鏡像、旋轉、縮放、剪切和一般扭曲影像。
  • 合併或合成多個影像。
  • 以奇特的方式平鋪影像。
  • 捲積或合併相鄰像素。
  • 產生影像度量或「指紋」。
  • 以不尋常的方式比較影像。
當然,其中許多技巧已經是 IM 的一部分,可以產生更快、更靈活的結果。但是,如果它不是內建的,「-fx」允許您產生自己的所需操作版本。事實上,我和其他人經常使用它來建立稍後會內建到 IM 核心程式庫中的新操作原型。例如,請參閱 DIY 新有序抖動替換,其中我使用「-fx」開發了「-ordered-dither」運算子的修訂版本。該運算子本質上允許您對一個或多個影像執行自由格式的數學運算。如需此指令的官方摘要,請參閱 ImageMagick 網站 上的 FX,特效影像運算子

FX 基本用法

這個命令接受一個圖像序列作為輸入,您可以輸入任意數量的圖像,通常是一或兩張。它會將所有輸入圖像替換為第一張圖像的副本,並根據「-fx」函數的結果進行修改。也就是說,第一張圖像中的任何中繼資料都將保留在「-fx」運算式的結果中。為了便於數學運算,所有提供的顏色值都被標準化為 0.0 到 1.0 的範圍。結果預計也在此範圍內。這包括透明度或 Alpha 色板,範圍從 0.0(表示完全透明)到 1.0(表示完全不透明)。這些值代表「Alpha 透明度」,實際上是 IM 內部儲存透明度的相反值(作為消光值)。然而,這種形式在數學上更正確,也更容易使用。「-channel」設定定義了第一張(也稱為「第零張」或「u」)圖像中的哪些色板將被「-fx」運算式的結果替換。預設情況下,這僅限於原始圖像的顏色色板(「RGB」)。除非更改「-channel」設定以包含 Alpha(「A」)色板,否則該圖像中的任何現有透明度都不會被修改。運算式會針對每個像素執行一次,也會針對正在處理的像素中的每個顏色色板執行一次。此外,由於運算式每次執行時都會重新解析,因此複雜的運算式在處理大型圖像時可能會花費一些時間。例如,在這裡我們定義了一個黑色圖像,但將藍色色板設定為半亮,以形成「海軍藍」顏色。

  magick -size 64x64 xc:black -channel blue -fx '1/2' fx_navy.gif
[IM Output]
在這裡,我們採用一個黑白漸層,然後將藍色和綠色色板設定為零,使其變成黑紅漸層。

  magick -size 64x64 gradient:black-white \
           -channel blue,green    -fx '0'    fx_red.gif
[IM Output]
為了使「-channel」設定更像「-fx」運算式,它將接受字母「RGBA」的任意組合來指定運算式要限制其作用的色板。

這意味著要將「-fx」的輸出限制為僅藍色和綠色色板,您現在可以使用「-channel BG」而不是更長的「-channel blue,green」。
雖然我們不使用 "-fx" 也能產生以上範例,但它能套用在現有影像上,使其成為強大的影像運算符。 實際上,此函數可以讀取和使用記憶體中目前影像序列中任何影像的任何像素或特定顏色。 第一張「零」影像被賦予特殊名稱 "u"。 第二張影像為 "v"。 記憶體中的其他影像可以使用索引來參考。 因此,"u[3]" 是目前影像序列中的第四張影像,而 "u[-1]" 是序列中的最後一張影像。 這是與影像列表運算符相同的索引方案,因此您應該不會感到陌生。 如果沒有給出其他限定詞,則使用的顏色值與指定影像中使用的顏色相同。 也就是說,除非您明確說明要使用紅色,否則它將使用該指令當時正在處理的顏色通道的顏色值。 也就是說,它會在處理藍色通道時套用藍色值的運算式。 除非另有說明,否則它會處理每個 RGB 顏色值(由預設的 "-channel" 設定設定),適用於影像中的每一個像素。 也就是 3*w*h 個計算,它會根據給定的運算式修改影像中的所有值。 例如,這裡我們採用 IM 內建的 "rose:" 影像,並將所有像素值乘以 50%。

  magick rose: -fx 'u*1.5'    fx_rose_brighten.gif
[IM Output]
在上述範例中,每個紅色、綠色和藍色值分別乘以 1.5。 如果結果值超出 0 到 1 的範圍,它將被限制在適當的界限(在這種情況下為 1.0),除非您使用預設的HDRI 版本的 ImageMagick。 在數學顏色調整直方圖曲線中探討了許多其他用於重新著色影像的 "-fx" 公式。 由於我們也可以參考目前影像序列中的任何影像,作為修改第一張影像的運算式的一部分,因此我們可以按照我們想要的任何方式合併兩個甚至更多影像。 在這裡,我們透過將藍色通道從黑色-藍色漸層(旋轉)複製到我們上面生成的黑色-紅色漸層中來生成黑色-紅色-藍色色表影像。

  magick -size 64x64 gradient:black-blue -rotate -90  fx_blue.gif
  magick fx_red.gif  fx_blue.gif \
          -channel B  -fx 'v'    fx_combine.gif
[IM Output]  + [IM Output] ==> [IM Output]
當然,我們可以直接使用通道複製合成方法,這樣會快很多。 但這不是重點。

反之亦然。 幾乎所有 IM 影像操作都可以用等效的 FX 函數來代替。

現在,上面第二張影像僅用作來源影像。 真正發生的是 "-fx" 首先建立第一張影像的副本。 然後,它根據公式修改該影像,並使用給定的所有其他影像。 最後,它會丟棄所有輸入影像,將它們替換為第一張影像的修改副本。 您也可以根據影像中每個像素的位置來計算值。 值 'i,j' 是正在處理的像素的當前位置,而 'w,h' 則表示影像的大小(第一張影像,除非給定了特定的影像限定詞)。 例如,這裡我們生成一個DIY 漸層影像

  magick rose: -channel G -fx 'sin(pi*i/w)' -separate   fx_sine_gradient.gif
[IM Output]
或者使用 'i,j' 位置值的更複雜的東西。

  magick -size 80x80 xc: -channel G -fx  'sin((i-w/2)*(j-h/2)/w)/2+.5'\
          -separate fx_2d_gradient.gif
[IM Output]
在生成灰階漸層時,您可以讓 -fx 運算子速度提高約 3 倍,只需讓它只處理一個顏色通道,例如上述範例中的「G」或綠色通道。然後,可以分離此通道以產生最終的灰階影像。這可以大幅提升速度,尤其是在使用非常複雜的「-fx」公式時。如需更多 FX 生成的漸層,請參閱範例 自訂漸層 您可以使用位置資訊,透過「p{x,y}」語法從來源影像中查找特定像素。例如,您可以輕鬆建立自己的「鏡像」類型函式(例如「-flop」影像運算子),它會將每個像素替換為原始來源「鏡像」位置的顏色值。

  magick rose: -fx  'p{w-i-1,j}'  fx_rose_mirror.gif
[IM Output]
這種「影像扭曲」類型透過以影像形式建立 扭曲影像映射 或其他類型的值查找表而變得更加強大。在 DIY 抖動模式和臨界值映射 中提供了執行此操作的範例,其中 FX 用於將特定顏色替換為其他影像中的圖案。 現在,FX 表達式產生的最終影像大小與給定的第一個影像相同,因此若要產生更大的影像,您需要將第一個影像設定為所需的大小。在此類情況下,第二個影像(甚至第三個影像)可以用作顏色來源(因此在下一個範例中使用 交換)。例如,這裡我們調整了玫瑰影像的大小(使用 插值縮放或調整大小)以產生更大的影像。

  magick rose:  -size 120x80 xc: +swap  \
           -fx 'v.p{  (i+.5)*v.w/w-.5, (j+.5)*v.h/h-.5  }' \
           fx_scaled.png
[IM Output]
請注意像素查找是如何執行的,它看起來可能很複雜,但這是縮放(扭曲)影像的正確方法。基本上,添加到表達式的所有額外的「0.5」值都是為了在用於輸入座標「i,j」的 像素座標 和位置查找「v.p{...}」之間正確地進行轉換,而實際的數學計算(縮放)則需要更數學上正確的 影像座標。以上實際上是任何形式的 影像扭曲 所使用的確切方法。您可以透過開啟 詳細扭曲摘要 來查看大多數扭曲的 FX 等效項。這會報告大多數影像扭曲的 FX 等效項,作為一種雙重檢查扭曲是否按預期執行的途徑。使用 FX DIY 運算子 進行影像扭曲,顯示了此運算子的強大功能。如果不是因為這個運算子,我懷疑許多新的操作,例如扭曲、稀疏顏色或有序抖動,是否會被添加到 ImageMagick 核心庫中。這裡有一個更簡單的例子,交換了玫瑰影像的紅色和藍色通道。看看您是否能弄清楚它是如何工作的。

  magick rose: \( +clone -channel R -fx B \) \
          +swap -channel B -fx v.R     fx_rb_swap.gif
[IM Output]
一種更快、更好的方法是使用「-separate」和「-combine」)。請參閱 組合 RGB 通道影像。或者,您也可以使用「-color-matrix」更快地完成同樣的事情。

您看到這裡的趨勢了嗎?
做為預設的「-channel」設定,它將「-fx」運算子的輸出限制為僅限於三個色彩通道。這表示如果您想影響 Alpha 或透明度通道,則必須透過變更通道設定來明確指定它。例如,讓我們透過將所有 Alpha 通道值設定為一半來製作半透明的「rose:」影像。

  magick rose: -alpha set  -channel A  -fx '0.5'    fx_rose_trans.png
[IM Output]
請注意,為了使上述操作正常運作,我需要確保「rose:」實際上有一個 Alpha 通道,以便「-fx」可以使用。我使用Alpha 通道控制運算子來做到這一點。「-fx」運算子能夠操控影像的 RGBA 通道,這使得它非常適合操控通道和遮罩。
從 IM 6.2.10 開始,您可以將變數賦值添加到「-fx」運算式中,這允許您降低某些運算式的複雜性,否則這些運算式基本上是不可能實現的。例如,我在這裡根據與特定點(賦值給變數「xx」和「yy」)的距離建立漸層。如果不使用變數,這個公式可能會變得非常難以閱讀。

  magick -size 100x100 xc:  -channel G \
          -fx 'xx=i-w/2; yy=j-h/2; rr=hypot(xx,yy); (.5-rr/70)*1.2+.5' \
          -separate  fx_radial_gradient.png
[IM Output]
由於「-fx」使用的簡單詞法分析處理,變數名稱只能包含字母,並且不能包含數字。此外,由於許多單個字母用於訪問影像資訊的內部變數,因此建議變數名稱至少包含兩個字母。因此,我使用「xx」和「yy」而不是僅使用「x」或「y」。
-fx」函數「rr=hypot(xx,yy)」已添加到 IM v6.3.6 中,以加速非常常用的運算式「rr=sqrt(xx*xx+yy*yy)」。

當然,如果您需要距離的平方,則應避免使用「hypot()」函數及其隱含的 sqrt() 函數。
有關一些非常複雜的運算式的更多範例,請參閱更複雜的 DIY 漸層,如果沒有多個敘述賦值,這將是不可能實現的。透視變形的 FX 形式也是如此。從 IM 版本 6.3.0-1 開始,「-fx」運算式的複雜性開始需要外部檔案,因此現在可以使用標準的「@filename」從檔案中讀取運算式。

   echo "u*2" | magick rose: -fx "@-"  fx_file.png
[IM Output]
這也意味著您可以使用更複雜的腳本來為特定作業生成特定的 FX 運算式。在內部,檔案只是被讀入字串並像往常一樣被解釋。對「-fx」很重要的其他設定是「-virtual-pixel」和「-interpolate」。虛擬像素設定允許您設定當查找座標超出輸入影像涵蓋的區域時應返回的顏色或影像結果。這允許您設定邊緣效果(例如模糊),以及在更大的區域上平鋪影像。插值設定允許您指定當查找座標(浮點值)落在輸入影像中像素的整數座標之間時,IM 應如何混合相鄰像素的顏色。有關更多資訊,請參閱插值像素查找
在不同時間添加了一些其他函數
IM v6.3.6:hypot()
IM v6.7.3-4:while()、not()、guass()、squish()

FX 除錯

debug(expr)」本質上是一種在每次計算 FX 表達式時列印浮點數值的方法。這反過來提供了一種除錯表達式的方法。但是,您可以使用三元 if-else 表達式來限制「debug()」的輸出。例如,這將列印內建「rose:」圖像中像素 10,10 的浮點顏色值。通過使用「NULL:」圖像處理器,實際的圖像結果將被忽略。

  magick rose: -fx 'i==10&&j==10?debug(u):1; u' null:
[IM Output]
請記住,輸出是在標準錯誤輸出上,而不是標準輸出上,這樣您就可以在命令管道中使用它,而不會出現問題。請注意 FX 表達式是如何執行三次的,每個通道一次,僅針對那一個像素。將其乘以像素數,您可以想像如果「debug()」不限於一個像素,即使對於這個小圖像,輸出的長度也會有多長。

類似 FX 的內建操作

-fx 運算符代表一種開發 ImageMagick 中以前不存在的新圖像處理函數的方法。用戶進行此類開發的結果是允許 ImageMagick 擴展新的函數和方法,例如 顏色查找表(「-clut」)。然而,一般來說,一旦使用「-fx」穩定了一種新方法,該表達式就會轉換為更快的內建操作,通常作為一組類似運算符的一部分添加。這些包括以下通用圖像運算符及其方法...
-evaluate 直接像素、顏色值、通道修改函數。
(請參閱下面的 Evaluate)。
-function 更複雜的像素、顏色值、通道修改函數。
(請參閱下面的 Function)。
-evaluate-sequence 以數學方式合併多圖像序列。
(請參閱下面的 Evaluate-Sequence)。
-sparse-color 通用圖像重新著色運算符。
(請參閱 稀疏顏色漸變)。
-compose 通用多圖像組合和疊加方法。
(請參閱 Alpha 合成)。
-distort 使用反向像素映射的通用圖像扭曲運算符。
(請參閱 Distort 運算符)。
-morphology 通用區域效應卷積/形態學函數。
(請參閱 Morphology 運算符Convolve 運算符)。
當人們開發新型圖像操作時,他們通常首先使用「-fx」運算符對其進行原型設計。當他們完成該「方法」後,就會將其轉換為 ImageMagick 核心庫中新的超快速內建運算符。歡迎用戶貢獻他們自己的「-fx」表達式(或其他定義的函數),他們認為這些表達式將成為 IM 的有用補充,但尚未被其他圖像運算符覆蓋,如果它們可以由上述其中一個通用運算符處理,則添加它們應該相當容易。例如,我自己需要一個「如果顏色相似則遮罩」類型的操作來比較兩個圖像。這已被添加為新的「-compose」方法「ChangeMask」。這反過來又允許我為 GIF 動畫添加更複雜的 透明度優化。如果「-fx」的速度和複雜性開始成為問題,那麼最好轉向 API 腳本語言,例如 PerlMagick。使用 PerlMagick 的示例「pixel_fx.pl」是該 API 發行版的一部分。

FX 表達式作為格式和註釋轉義

從 IM 版本 6.2.10 開始,您現在可以在「-format」和「-annotate」參數所使用的圖像屬性轉義字串中使用FX 表達式。轉義序列「%[fx:...]」會被替換為一個浮點值,並針對目前圖像序列中的每個圖像計算一次。然而,FX 表達式在處理過程中會稍微修改。具體來說...
  • 目前的像素座標「i」、「j」固定為值 0,因此單獨一個圖像變數只會返回像素 0,0 的值,除非使用「p{}」索引。
  • 除非選擇了顏色通道,否則只會返回紅色通道值。
  • 預設圖像參考「s」設定為目前正在註釋或識別的圖像。
  • 索引「t」返回「s」所參考圖像的索引。
在 IM v6.6.8-6 之前,「t」圖像索引和「n」圖像總數的 FX 表達式值都已損壞,並且對於所有圖像分別只返回 0 和 1 的值。等效的百分比轉義符「%p」和「%n」也是如此。
例如,這裡我使用每個圖像左上角的顏色「-annotate」每個圖像。

  magick -size 150x25 xc:DarkRed xc:Green xc:Blue \
          -fill white -gravity center \
          -annotate 0 '%[fx:t] / %[fx:n] : %[fx:r],%[fx:g],%[fx:b]' \
          annotate_fx_%d.gif
[IM Output] [IM Output] [IM Output]
請注意,由於「r」實際上等於「s.p{0,0}.r」,因此寫入的文字對於每個圖像都不同。「g」和「b」顏色通道值也是如此。當然,每一個都返回一個介於 0.0 到 1.0 之間的標準化值。為了更容易輸出特定像素顏色值,在 IM v6.3.0 中還添加了「%[pixel:...]」轉義符。此運算符會針對每個圖像中的每個通道調用一次給定的 FX 表達式,並將返回的值格式化為 IM 可以處理為顏色參數的顏色。

  magick -size 300x100 gradient:yellow-limegreen \
          -gravity NorthWest  -annotate 0 '%[pixel:s.p{0,0}]' \
          -gravity Center     -annotate 0 '%[pixel:s.p{0,50}]' \
          -gravity SouthEast  -annotate 0 '%[pixel:s.p{0,99}]' \
          annotate_pixel.gif
[IM Output]
您可以使用「-format」和「identify」命令直接輸出結果。

  magick identify -format '%[fx:atan(1)*4]' null:
[IM Output]
這將以數學方式計算並返回 PI 的值,儘管此值可作為內建變數「pi」使用。您可以產生亂數。例如,要產生介於 -5 到 10 之間(含)的整數。這裡我使用「info:」來等效於「magick identify」命令。

  magick xc: -format '%[fx:int(rand()*16)-5]' info:
[IM Output]
如需更多方法,請參閱識別替代方案:文字輸出選項。另請參閱帶圓角的邊框,它使用FX 表達式根據圖像寬度和高度資訊產生繪製字串。您可以使用 FX 公式計算圖像位置,甚至可以使用其他圖像的大小和位置進行定位(請參閱增量計算位置)。您還可以在檔名百分比轉義符中使用FX 轉義符來根據計算值產生新檔案。如需範例,請參閱拼貼裁剪中的最後一個範例。
以上所有內容基本上都會針對目前圖像序列中的每個圖像運行「-format」,因此任何包含FX 表達式的內容都會運行一次。「-print」運算符的工作方式與「-identify」非常相似,只是它只會運行一次,並且可以訪問目前圖像序列中的所有圖像。與上述不同的是,使用此運算符,您可以使用「u[{i}]」來訪問任何圖像的值。
Fx 表達式可以應用於其他色彩空間中的圖像,因此我可以例如找出三種不同顏色的「色調」值(在「紅色」通道中)。

  magick xc:red xc:green xc:blue -colorspace HSL \
          -format '%[fx: s.r ]\n' info:
[IM Output]
您也可以使用 IM 進行一些直接的色彩數學運算,例如找出「gold」、「yellow」和「khaki」的平均顏色。

  magick xc: -format '%[pixel:(gold+yellow+khaki)/3]' info:
[IM Output]
雖然這顯示了與三種來源顏色相比的顏色樣貌...

  magick xc:gold xc:yellow xc:khaki +append \
          \( xc: -fx '(gold+yellow+khaki)/3' \) \
          -scale 90x30\! -append fx_hues.png
[IM Output]
您也可以使用「-print」來列印資訊。這只會對整個影像序列套用一次。這表示您可以使用此運算子來計算涉及多個影像的更複雜的「%[fx:...]」運算式。

從其他影像存取資料

然而,使用 FX 跳脫運算式有一個嚴重的問題。當您在建立影像時,IM 無法直接存取目前影像序列中的其他影像。這在典型的影像建立過程中通常並非必要,因為新的影像通常不依賴於先前的記憶體內影像。基本上,如果您想收集與您正在繪製的影像不同的影像中特定像素的顏色(如上所述),或者正在建立新的影像,則 IM 核心函數沒有直接連結到所需的資訊。例如,如果您嘗試使用內建「rose:」影像像素 12,26(藍色像素)的顏色建立標籤,則直接方法將會失敗!

  magick rose: label:'%[pixel:p{12,26}]' -delete 0 label_fx_direct.gif
[IM Output]
嗯,玫瑰影像實際上不包含任何黑色像素,因此上述結果是錯誤的。解決此問題的方法是提取所需的資訊並將其儲存到全域 IM 中繼資料中。這會傳遞到程式庫核心中的所有子常式,包括用於影像建立的子常式。

  magick rose: -set option:mylabel '%[pixel:u.p{12,26}]' -delete 0 \
          label:'%[mylabel]'    label_fx_indirect.gif
[IM Output]
這並不直觀,但我們現在得到了正確的結果。特殊的「option:」標籤告訴「-set」選項,您希望將給定的設定儲存為全域 Artifact,而不是作為影像「屬性」或「屬性」字串,就像「-define」一樣。然而,「-set」形式允許您在設定 Artifact 時展開 百分比跳脫,而「-define」則不允許。當「label:」運算子展開其百分比跳脫時,會先將給定的「鍵」作為每個影像的「屬性」或「特性」來尋找,但如果找不到任何內容,則會在全域 Artifact 設定中尋找「鍵」。因此,即使在建立 Artifact 時該影像已不存在,也會使用我們從先前影像建立的全域「artifact」。基本上,「Artifact」設定在「magick」命令的生命週期內是全域的,因此可用於將資訊從一個影像傳遞到另一個影像。對於程式化的 API,可以避免這種情況,因為您可以直接從影像讀取所需的資料並自行產生標籤字串,而不需要 IM 以如此複雜的方式儲存該資訊。

評估和函數、自由形式通道修飾符

因為 FX 運算子 是一個解譯的運算式處理器,所以添加了「-evaluate」運算子,讓您可以更快地進行簡單的影像修改。後來在 IM v6.4.8-8 中添加了一個更複雜的「-function」運算子,以便在複雜的影像調整中提供更大的靈活性。這兩個運算子以及其他 影像級別調整運算子(例如「-negate」、「-level」)可能最適用於在套用灰階影像之前對其進行微調。特別是在用於 背景移除高光和陰影疊加 以及 影像地圖 的產生和微調的灰階影像中。

Evaluate,簡單的數學運算

-evaluate」運算子基本上是「-fx」運算子的快速但非常簡單的版本(實際上比它加入 IM 早了幾個月)。然而,它僅限於使用單一使用者提供的常數進行一個簡單的操作。您可以使用以下方法找出已內建到 evaluate 中的函數

  magick -list evaluate
這包括針對常數值的典型數學函數「add」、「subtract」、「multiply」和「divide」。與 -fx 運算子不同,這些值不會標準化到 0 到 1 的範圍,而是保留圖像的實際顏色值。因此,在 Q8 IM 中減去 50 的值(請參閱品質和深度)將導致較大的減法,但對於 Q16 版本的 IM,這只是一個幾乎難以察覺的微小變化。但是,如果您在參數中添加「%」,則該參數將代表最大顏色值的百分比(稱為「QuantumRange」,等於(「2quality-1」)。這意味著您可以通過適當使用百分比來使您的「-evaluate」參數與 IM 品質等級無關。 例如,要將圖像中的所有顏色值替換為 50% 的灰色非常簡單快捷,使用「Set

  magick rose: -evaluate set 50%  rose_set_gray.gif
[IM Output]
-evaluate」運算子還包括典型的數學函數「add」、「subtract」、「multiply」和「divide」。 例如,要將圖像的對比度減半,您可以將其「divide」(除以)「2」,然後「add」(加上)「25%」以將其重新置中於完美灰色。

  magick rose: -evaluate divide 2 -evaluate add 25%  rose_de-constrast.gif
[IM Output]
這比直接使用「-fx」運算子和「u/2+.25」快幾個數量級。因此,如果可能的話,您應該優先使用此運算子而不是「-fx」。「-evaluate」的主要問題是所有結果都被裁剪到 0 到「QuantumRange」的限制(除非您使用的是HDRI 版本的 ImageMagick),因為每個修改後的值都會保存回圖像數據中。這意味著在任何單個「-evaluate」操作之後,這些值可能會被「QuantumRange」裁剪。 因此,如果您嘗試直接應用對比度增強函數(相當於「-fx '2*u-.25' 」),您將無法獲得正確的結果,因為加倍的值將在進行減法之前被裁剪。

  magick rose: -evaluate multiply 2  -evaluate subtract 25% \
          rose_contrast.gif
[IM Output]
首先,「multiply」(乘法)會將所有較大的顏色值裁剪為最大值,然後「subtract」(減法)會裁剪較低的值。結果是上界被錯誤地裁剪,產生了黑暗和顏色失真的結果。 直接的解決方案是先「subtract」(減去)適當的常數(對下界進行最終但正確的裁剪),然後再進行乘法,有效地使用等效公式「(u-.125)*2

  magick rose: -evaluate subtract 12.5%  -evaluate multiply 2 \
          rose_contrast2.gif
[IM Output]
然而,針對這個「裁切」問題,有很多替代方案。第一個合乎邏輯的是更新的 多項式函數方法(見下文)。其他替代方案還包括使用 色階調整運算子,甚至是 依顏色調整色階,只需指定要延伸的原始顏色值,即可填滿整個顏色範圍。基本上,在使用多個 "-evaluate" 方法時,請注意顏色值的裁切問題。
"-evaluate" 運算子和 "-fx"(以及大多數其他低階 IM 運算子)一樣,會受到 "-channel" 的影響。這讓您可以將圖像的 Alpha 透明度與色彩通道分開控制。是的,和 "-fx" 一樣,透明度被視為「Alpha 值」而不是「遮罩」值。例如,若要將圖像設定為 50% 透明度,作為 溶解 類型操作的一部分。

  magick rose: -alpha set  -channel A -evaluate divide 2   rose_transparent.png
[IM Output]
結果會產生半透明圖像,這表示顯示時,您看到的一半顏色是網頁的背景顏色。因此,顯示的圖像會朝著背景顏色變暗。我還經常發現,在將各種通道分離成單獨的圖像以用於特定目的之前,在個別顏色通道上使用 "-evaluate" 通常更容易(請參閱 分離通道)。例如,我在這裡使用它來執行快速但不尋常的灰階化形式。基本上,我將每個通道乘以適當的數量,然後將這些通道分離並加總在一起,以產生使用特定顏色比率進行灰階化的圖像。

  magick test.png -channel R -evaluate multiply .2 \
                   -channel G -evaluate multiply .5 \
                   -channel B -evaluate multiply .3 \
                   -channel RGB -separate -background black -compose plus -flatten gray_253.png
[IM Output]

Evaluate 數學函數

在 Evaluate 中,還包含一組特殊用途的數學函數。實作這些函數通常是為了使用標準化顏色值(範圍從 0 到 1),而輸出也會再次標準化,以符合圖像的完整顏色範圍。Sigmoidal 對比 函數也是此類數學函數擬合的範例。

冪次方

例如,「Pow」函數(新增於 IM v6.4.1-9)使用標準化顏色值,並允許使用者修改圖像亮度。它完全等同於 pow() C 函數(在 0 到 1 的範圍內使用標準化顏色值)
    value = pow(value, constant) 
因此,若要建立「拋物線」漸層,您可以使用參數「2」。或者使用「0.5」值來建立「平方根」漸層。例如...

  magick -size 20x600  gradient: -rotate 90  gradient.png
  magick gradient.png  -evaluate Pow  2   eval_pow_parabola.png
  magick gradient.png  -evaluate Pow 0.5  eval_pow_sq_root.png
[IM Output] [IM Output] [IM Output]
[IM Output] ==> [IM Output] [IM Output]
下方的三張圖像顯示了產生的漸層的輪廓,包括圖形和原始圖像本身。這讓我們更容易看出一個漸層圖像是如何被修改成另一個漸層圖像的。它是使用 IM 範例中 腳本 目錄下的腳本「im_profile」,透過 Gnuplot 圖形繪製程式產生的。
這實際上等同於 Gamma 調整 運算子,但參數是反向的。例如,「-gamma 2」運算相當於「-evaluate pow 0.5」或「平方根」運算函數。同樣地,「-gamma 0.5」等同於使用「-evaluate pow 2」進行平方運算。透過執行一些特殊的漸層操作,您可以使用此方法將線性漸層變更為複雜的圓弧。

  magick -size 20x300  gradient: -rotate 90 \
          -evaluate Pow 2 -negate -evaluate Pow 0.5 \
          -flop \( +clone -flop \) +append  eval_circle_arc.png
[IM Output]
[IM Output]
對於想要弄清楚這一點的人來說,上面第二行相當於FX 表達式 'sqrt(1-u^2)'。這會生成單個四分之一圓弧,然後將其翻轉,並附加在一起,以生成半圓弧。它也比使用FX 表達式快得多,即使它需要更多單獨(更小)的步驟。另請參閱更進階的多項式函數

對數

Log」函數(IM v6.4.2-1 中新增)也適用於標準化值(加上 1.0 以避免無限大),給定的常數用作對數基數。因此,實際公式(使用標準化值)為...
    value = log(value*constant+1.0)/log(constant+1.0) 
舉例來說...

  magick gradient.png -evaluate Log 10  eval_log.png
[IM Output]
[IM Output]
這看起來可能與之前的Pow 評估方法非常相似,但並不完全相同。「Log」在接近「0」時會產生明顯的斜率,而「Pow」會產生垂直斜率。該值控制斜率。對數函數也與指數函數密切相關,指數函數目前僅作為S 形對比度調整運算符實現。這包含了您在上述對數曲線中可以看到的相同斜率特徵。這解釋了為什麼「-sigmoidal-contrast」是增強涉及低光照條件的圖像的比Gamma 調整或「冪次方」曲線更好的技術。

正弦和餘弦

從 IM v6.4.8-8 開始,添加了「sin」和「cos」方法。這些方法採用圖像中給定的值並將其標準化為角度,因此整個範圍將覆蓋一個完整的角度圓。結果給予 50% 的偏差並縮放以再次適合正常的數值範圍。常數用作值的乘數(以及角度),因此「N」表示函數將在整個值範圍內繞圓「N」次。具體來說,它將這些函數(使用標準化值)定義為...
   value = 0.5 * sin( constant*value*2*PI ) + 0.5
   value = 0.5 * cos( constant*value*2*PI ) + 0.5 
從本質上講,這些函數的作用是將圖像值(通常是灰度值)重新映射到正弦/餘弦曲線中。例如,這裡我採用漸變圖像並使用這些評估方法對其進行修改。

  magick gradient.png  -evaluate sin 1  eval_sin_1.png
  magick gradient.png  -evaluate cos 1  eval_cos_1.png
[IM Output] [IM Output]
[IM Output] ==> [IM Output] [IM Output]
現在,由於常數參數是角度乘數,因此賦予評估方法的值將在圖像內的整個漸變上創建那麼多個峰值。

  magick gradient.png -evaluate cos 5  -negate  eval_cos_5.png
[IM Output]
[IM Output]
這非常適合許多任務,從產生漣漪或分散效應到產生看起來像漣漪的位移曲線。通過使用「0.5」的乘數常數,您可以簡單地將線性漸變變成正弦曲線漸變,它仍然具有與原始漸變相同的斜率。通過否定結果,您可以確保漸變也正確傾斜。

  magick gradient.png -evaluate cos 0.5  -negate  eval_cos.5.png
[IM Output]
[IM Output]
這對於生成用於重疊照片的平滑漸變非常有用。然而,最後這兩種「-evaluate」方法很少使用,因為它們已被更通用的正弦函數(見下文)所取代,後者提供了更多控制選項,超出了簡單頻率選項。

Function,多參數 Evaluate

以上波形產生器被證明是非常有用的,特別是與 扭曲影像映射 一起使用時。但是我們發現需要對函數進行更精細的控制,需要多個參數。因此,在 IM v6.4.8-9 中添加了「-function」運算符。基本上,「-function」是「-evaluate」的多參數形式。但是,與 評估運算符 不同,這些運算符(如數學運算符)的所有上述函數僅作用於圖像的標準化通道值(0.0 到 1.0 範圍),這在多數情況下使它們更易於使用。

多項式函數

polynomial」方法將接受任意數量的值,並根據給定的精確表達式修改圖像中的顏色值,其速度比 FX 運算符 快得多。
-function   Polynomial   a,b,c,...
每個值將用作從最高階到最低階的係數,以產生具有給定項數的多項式。例如,參數「4,-4,1」將生成等效於「-fx」表達式「 4*u^2 - 4*u + 1 」的多項式表達式。如果您了解高中數學,那麼您應該知道,這個多項式函數會在輸入(「u」)顏色範圍 0.0 到 1.0 上產生一條拋物線,從 1.0 到 0.0 然後回到 1.0。也就是說,它會使黑色和白色變成「白色」,並使完美的灰色變成「黑色」。

  magick gradient.png -function Polynomial 4,-4,1  func_parabola.png
[IM Output]
[IM Output]
您甚至可以製作更複雜的漸變,例如四次多項式,它是使用一組「級別控制點」生成 曲線級別調整 的結果。這通常用於調整圖像的顏色以賦予其各種陰影效果。

  magick gradient.png -function Polynomial '-25, 53, -36, 8.3, 0.2' \
          func_quartic.png
[IM Output]
[IM Output]
當然,也可以進行簡單的線性修改,就像您使用 級別運算符 時一樣...

  magick gradient.png -function Polynomial '4, -1.5' func_linear.png
[IM Output]
[IM Output]
但是請注意,您不能使用「Polynomial」來執行完整的 閾值 運算,因為這樣做需要無限的係數,儘管您可以非常接近。單個值自然只是一個常數,並且會導致直接賦值該值。換句話說,它就像「-evaluate Set 」方法一樣,在這種情況下為 33% 的灰度值。

  magick gradient.png -function Polynomial 0.33 func_constant.png
[IM Output]
[IM Output]
通過將「Polynomial」與其他數學函數組合,您可以創建更複雜的漸變修改。例如,通過取多項式的平方根,我可以在線性漸變上創建一個真正的圓弧。等效的「-fx」表達式為「sqrt( -4*u^2 + 4*u + 0 )」...

  magick gradient.png -function Polynomial -4,4,0 -evaluate Pow 0.5 \
          func_circle_arc.png
[IM Output]
[IM Output]
另請參閱 Pow 評估方法 以獲取上述方法的替代方法。

正弦函數

Sinusoid」函數方法是「-evaluate」方法「sin」和「cos」的更高級版本,實際上可以複製這些函數,但您可以更好地控制它如何修改圖像中的顏色值。
-function   Sinusoid   frequency,phase,amplitude,bias
並使用以下公式實現...
  value = ampl * sin(2*PI( freq*value + phase/360 ) ) + bias
這看起來可能很複雜,但它確保了該函數易於使用。只需要第一個值「頻率」(其工作原理與上述完全相同),所有其他參數都是可選的。默認情況下,它將生成一條正弦曲線。

  magick gradient.png -function Sinusoid 1    func_sine.png
[IM Output]
[IM Output]
通過添加一個以度為單位的「相位」參數,您可以指定曲線的起始角度。允許您將默認的正弦曲線變成餘弦曲線。

  magick gradient.png -function Sinusoid 1,90   func_cosine.png
[IM Output]
[IM Output]
通過調整「頻率」和「相位」,我可以直接將線性漸變變成平滑的正弦漸變,從黑色到白色(沿正弦曲線從最小值到最大值)。有關不太直接的方法,請參閱 評估餘弦方法

  magick gradient.png -function Sinusoid 0.5,-90 func_sine_grad.png
[IM Output]
[IM Output]
接下來的兩個可選值「amplitude」和「bias」控制著正弦曲線的尺度和中心線。例如,我在這裡建立一個在白色和灰色之間震盪的波浪(負餘弦曲線)(值介於 0.75 ±0.250.5 到 1.0 之間),開始和結束都是白色。

  magick gradient.png -function Sinusoid 5,90,.25,.75  func_sine_bias.png
[IM Output]
[IM Output]
請小心使用這些最後的參數,因為它們很容易導致波形超出色彩值範圍的界限,從而被裁剪(除非您使用的是 HDRI 版本的 ImageMagick)。

反正弦函數

反反正弦函數「Arcsin」已添加到 IM v6.5.3-0 中。這是一條特殊的曲線,用於生成 圓柱位移貼圖。其參數為...
-function   Arcsin   width,center,range,bias
並使用以下公式實現...
  value = range/PI * asin(2/width*( value - center ) ) + bias
預設值(如果未定義)「1, 0.5, 1, 0.5」確保函數居中,以便涵蓋從 0,01,1 的整個色彩範圍。

  magick gradient.png -function Arcsin 1    func_arcsin.png
[IM Output]
[IM Output]
將結果曲線的「寬度」減半,您將得到...

  magick gradient.png -function Arcsin 0.5    func_arcsin_width.png
[IM Output]
[IM Output]
中心」將讓您根據輸入灰度值重新定位曲線。

  magick gradient.png -function Arcsin 0.4,0.7 func_arcsin_center.png
[IM Output]
[IM Output]
範圍」參數允許減少色彩值的輸出範圍,「偏移」將調整該範圍的中心。

  magick gradient.png -function Arcsin 0.5,0.5,0.5,0.5  func_arcsin_range.png
[IM Output]
[IM Output]
請注意如何處理函數導致的無效值。這允許在位移中使用函數時更好地控制,並提供清理它們的方法。使用的實際值是「偏移 ±範圍/2」,如您所料。請注意,如果「寬度」或「範圍」為負數,則函數的斜率將因該負值而翻轉。

  magick gradient.png -function Arcsin -1    func_arcsin_neg.png
[IM Output]
[IM Output]

反正切函數

Arctan」方法已添加到 IM v6.5.3-1 中。其參數為...
-function   Arctan   slope,center,range,bias
並使用以下公式實現...
  value = range/PI * atan(slope*PI*( value - center ) ) + bias
如您所見,它與「Arcsin」函數幾乎完全相同,只做了一點小改動以使其更有用。它甚至具有相同的預設值集(如果未定義)「1, 0.5, 1.0, 0.5」。這意味著如果您指定斜率值為「1.0」,則直方圖變化的斜率將在純灰色周圍產生 1:1 的變化(無縮放),同時使白色和黑色變為更灰的值。例如

  magick gradient.png -function Arctan 1 func_arctan.png
[IM Output]
[IM Output]
也就是說,漸變的中間部分實際上保持不變,只有黑色和白色兩端變得不那麼對比。隨著曲線的「斜率」變大,中心的漸變將變得更強(在中間更壓縮)。

  magick gradient.png -function Arctan 10 func_arctan_10.png
[IM Output]
[IM Output]
這在許多方面都與 Sigmoidal 對比度色彩修改運算符非常相似。但是,「Arctan」函數永遠不會真正達到純黑色和白色的輸出範圍限制。它會接近這些限制,但永遠不會越過它們。與前面的函數(和 Sigmoidal 對比度)類似,第二個參數將調整曲線相對於輸入漸變值的位置。

  magick gradient.png -function Arctan 10,.7 func_arctan_center.png
[IM Output]
[IM Output]
最後兩個參數「範圍」將讓您調整將生成的值的輸出範圍。例如,通過稍微擴展此值,您可以確保它完全覆蓋所有可能值的範圍。

  magick gradient.png -function Arctan 5,0.7,1.2 func_arctan_range.png
[IM Output]
[IM Output]
但是,如果您真的想以這種方式生成曲線來修改圖像的整體對比度,則更典型的方法是使用 Sigmoidal 對比度運算符,它是為此目的而設計的。「Arctan」漸變函數的更典型用途是創建一條曲線,該曲線將非常快地接近特定值,但不會超過該值。「範圍」和「偏移」參數控制著這些限制值。例如,此曲線將修改圖像中的漸變,以在輸入灰度級 0.7 周圍產生非常清晰的閾值,但值在 0.5 和 1.0 的範圍限制之間變化

  magick gradient.png -function Arctan 15,0.7,0.5,0.75 func_arctan_typ.png
[IM Output]
[IM Output]
這是 Sigmoidal 對比度無法生成的。

漸變圖像的數學運算

現在,上述函數為漸變圖像提供了一些非常基本的變換。但是,如果您想對兩個或多個漸變圖像進行一些數學運算,那該怎麼辦呢?也就是說,使用另一個圖像的漸變來修改一個漸變。為此,您需要使用特殊的數學合成方法(例如“加法”和“除法”)。然而,在我們開始之前,我想給你一個警告。如果您的漸變圖像是純灰階圖像,沒有 alpha 通道,則可以直接使用數學合成方法。但是,如果您想將這些方法限制在特定的通道,或者將其應用於 alpha(透明度)通道,則需要確保設置了適當的“-channel”設置,並且沒有特殊的“Sync”通道標誌。有關詳細資訊,請參閱使用圖像合成進行圖像數學運算。通常,使用數學合成方法並不難。當您擁有的漸變也包含“偏差”時,就會出現複雜情況。也就是說,漸變應該在“50% 灰色”處表示“零”值,並且涵蓋從 -1(黑色)到 +1(白色)的範圍。此類圖像通常用於失真圖像映射。因此,對“偏差漸變”執行數學運算是真正的問題,我們將在此處更具體地研究這個問題。

衰減偏差漸變

例如,在這裡我想創建一個正弦波,但它開始時很小,然後振幅變大。這稱為“衰減”偏差漸變。或者換句話說,將偏差漸變乘以另一個絕對漸變。這也是 AM 無線電中的“調幅”的工作原理!所以首先我們需要一個正弦波,我們可以簡單地從線性漸變生成它……

  magick -size 5x300 gradient: -rotate 90   math_linear.png
  magick math_linear.png  -evaluate sine 12  math_sine.png
[IM Output] ==> [IM Output]
現在要衰減它,我們使用乘法 alpha 合成將正弦波與線性漸變相乘……

  magick math_sine.png  math_linear.png  \
          -compose Multiply -composite  math_sine_2.png
[IM Output] X [IM Output] ==> [IM Output]
但是,要在例如水波紋、位移貼圖中使用它,波浪必須保持以完美灰色為中心。為此,我們需要為原始圖像添加偏差。這恰好是我們用來乘以原始圖像的函數,取反並除以二……

  magick math_linear.png -negate -evaluate divide 2  math_bias.png
  magick math_sine_2.png  math_bias.png \
          -compose Plus -composite  math_attenuated.png
[IM Output] X [IM Output] ==> [IM Output]
因此,我們得到了一個線性衰減的正弦波漸變,適用於位移貼圖。

當然,您可以使用一個命令完成整個過程,並且它也不必是簡單的線性衰減。例如,在這裡我使用負餘弦波而不是線性漸變來衰減高頻正弦波。


  magick math_linear.png  -evaluate cos 1 -negate  math_cosine_peak.png
  magick math_sine.png  math_cosine_peak.png \
          \( -clone 0,1 -compose multiply -composite \) \
          \( -clone  1  +level 50%,0 \
             -clone  2  -compose plus -composite \) \
          -delete 0--2  math_cosine_atten.png
[IM 輸出] 衰減 [IM 輸出] ==> [IM 輸出]
從 IM v6.5.4-3 開始,現在可以使用特殊的數學合成方法在一個合成方法中完成上述所有步驟。基本上通過認識到衰減運算是公式 Sc*Dc-.5*Sc+.5 或參數“1,-.5,0,.5”。

  magick math_sine.png  math_cosine_peak.png \
          -compose Mathematics -set option:compose:args 1,-.5,0,.5 \
          -composite  math_attenuate.png
[IM Output]
也可以通過首先使用多項式函數調整衰減漸變,然後使用排除合成運算符合併圖像來實現相同的結果。

  magick math_sine.png \( math_cosine_peak.png -function polynomial -.5,.5 \) \
          -compose Exclusion -composite  math_poly_excl.png
[IM Output]

乘以偏置漸層

但如果兩個函數都有偏差,因此完美的灰色表示零,而黑色和白色表示 -1 到 +1 的範圍呢? 這有點複雜,因為您不能僅僅將它們相乘並期望它出來正確,因為乘法可能包含負值。 這需要一些注意,以確保您最終不會剪掉值並在生成的圖像中獲得正確的曲線反轉。 訣竅是將乘法分解為多個步驟。 也就是說   A × B   也可以寫成   A × abs(B) × sign(B)。 通過這樣做,您可以避免乘以負值,這在普通漸變圖像中無法存儲。 因此,我們需要做的就是採用其中一個偏差漸變並將其分成兩部分,以便可以將它們適當地應用於另一個漸變。 有偏差漸變的“sign()”,或獲取哪些部分為負的蒙版,可以使用 臨界值 在偏差級別的漸變上提取。 您可以稍後使用 合成差異 有選擇地否定另一個漸變,使用該臨界值圖像。 有偏差漸變的“abs()”可以使用 曝光 輕鬆提取,然後否定並加倍(使用 級別)以獲得從 0.0 到 1.0 的漸變絕對值。 由於我們還需要偏差偏移作為乘法的一部分(根據上面的 衰減),因此您可以直接使用否定和半比例的曝光輸出,然後再將其轉換為漸變絕對值。 讓我們將一個漸變變成這三個組成部分。

  magick math_cosine_peak.png  -threshold 50% -negate  math_m_sign.png
  magick math_cosine_peak.png     -solarize 50%        math_m_bias.png
  magick math_m_bias.png          -level 50%,0         math_m_abs.png
[IM Output] 漸變符號
白色 = 負數
[IM Output] ==> [IM Output] 偏差偏移
[IM Output] 絕對值
現在我們有了其中一個漸變圖像的這三個部分,我們可以將它們與另一個漸變合併。 為此,我們乘以絕對值,重新添加偏差,然後否定應該變為負數的部分。

  magick math_sine.png   math_m_abs.png \
          -compose Multiply -composite    math_m_1.png
  magick math_m_1.png   math_m_bias.png \
          -compose Plus -composite        math_m_2.png
  magick math_m_2.png   math_m_sign.png \
          -compose Difference -composite  math_multiply.png
[IM Output] X [IM Output] ==> [IM Output]
+ [IM Output] ==> [IM Output]
符號 [IM Output] ==> [IM Output]
這就是兩個偏差漸變圖像的完美乘積! 這裡又是全部合而為一...

  magick math_sine.png  math_cosine_peak.png \
          \( -clone  1  -threshold 50% -negate \) \
          \( -clone  1      -solarize 50%      \) \
          \( -clone  3      -level 50%,0       \) \
          \( -clone 0,4 -compose multiply   -composite \
             -clone  3  -compose plus       -composite \
             -clone  2  -compose difference -composite \) \
          -delete 0--2    math_multiply_2.png
[IM Output] X [IM Output] ==> [IM Output]
最後要注意的是,與 衰減 不同,這種有偏差漸變的乘法是可交換的。 也就是說,交換輸入圖像不會影響最終結果。 由於上述等同於公式 2*Sc*Dc-Sc-Dc+1,從 IM v6.5.4-3 開始,您可以使用參數“數學”將上述複雜步驟實現為單個“數學”合成方法 "2,-1,-1,1"。

  magick math_sine.png  math_cosine_peak.png \
          -compose Mathematics -set option:compose:args 2,-1,-1,1 \
          -composite  math_bias_multiply.png
[IM Output]
也就是說,比沒有這種參數化合成方法所需的十幾個步驟更容易、更快的方法。 碰巧的是,當我看到那個公式時,我意識到這恰好是“排除”合成方法的否定。 奇怪但真實。 因此,以下內容也將生成相同的零偏差倍數。

  magick math_sine.png  math_cosine_peak.png \
          -compose exclusion -composite -negate  math_excl_neg.png
[IM Output]

新增偏置漸層

隨著“數學”合成方法的出現,添加偏差漸變也相對容易。 等效的 FX 公式是“u+v-0.5”或合成參數“0,1,1,-.5”。 例如,以下是我手動生成的 傅立葉變換示例,需要添加 3 個偏置正弦曲線和一個恆定直流值。

  magick math_linear.png -function sinusoid 3.5,0,.25     wave_1.png
  magick math_linear.png -function sinusoid 1.5,-90,.13   wave_2.png
  magick math_linear.png -function sinusoid 0.6,-90,.07   wave_3.png

  magick wave_1.png wave_2.png wave_3.png -background gray40 \
          -compose Mathematics -set option:compose:args 0,1,1,-.5 \
          -flatten  added_waves.png
[IM Output]  + [IM Output]  + [IM Output] ==> [IM Output]
請注意,在上面我如何使用帶有“-background”設置的“-flatten”運算符來實現多圖像合成。 或者在這種情況下是所有給定圖像加上背景常數的“偏差和”。

頻率調變

通過將函數直接應用於另一個函數的輸出,您不會產生簡單的結果。 原因是所有這些數學函數都應用於單個像素的漸變“值”,而不是針對漸變中像素的 x 值。 例如....

  magick gradient.png  -evaluate sin 0.5 -normalize \
                        -evaluate cos  8  math_cos_var.png
[IM Output]
[IM Output]
這會產生一個非常複雜的函數,它實際上等同於:
cos( 8 * sin( {value}/2 ) )
換句話說,這是一個變頻,其中頻率隨著第一個正弦曲線的梯度而變化。基本上,原始圖像中梯度變化越快,峰值之間的距離就越小。然而,峰值的高度(振幅)不會改變。這實際上就是「頻率調變」的工作原理,一個看似簡單的函數產生了非常複雜的結果。
建構中
Miscellaneous Image Transformation Techniques.

These have not been exampled yet, but are some basic IM developed transforms
that may provide useful.  If you have an interesting effect please contribute.

   pixelize an image
      resize an image down 10 then scale the image 10 to produce blocks
      of roughly averaged color.
      For example...
         magick input.jpg -resize 10% -sample 1000% output.jpg

  De-skew slightly rotated images

    -deskew {threshold}
       straighten an image. A threshold of 40% works for most images.

    Use -set option:deskew:auto-crop {width} to auto crop the image. The set
    argument is the pixel width of the image background (e.g 40).

    Programmically we auto crop by running a median filter across the image
    to eliminate salt-n-pepper noise.  Next we get the image bounds of the
    median filter image with a fuzz factor (e.g. -fuzz 5%).  Finally we
    crop the original image by the bounds.  The code looks like this:

      median_image=MedianFilterImage(image,0.0,exception);
      geometry=GetImageBoundingBox(median_image,exception);
      median_image-DestoryImage(median_image);

      print("  Auto-crop geometry: %lux%lu%+ld%+ld",
                geometry.width,geometry.height, geometry.x,geometry.y);
      crop_image=CropImage(rotate_image,&geometry,exception);

    See Trimming 'Noisy' Images

  Segmentation
    look at scripts
       divide_vert
       segment_image
    for some simple scripts I wrote to segment well defined images into
    smaller parts.   I hope to get simple segmentation functions like this
    into the core library, to allow for things like automatic sub-division of
    GIF animations, and seperating images and diagrams from scanned documents.