ImageMagick 範例 --
色彩修改

索引
ImageMagick 範例 前言與索引
將色彩轉換為灰階
影像色階調整
使用直方圖修改進行調整 (變更影像的直方圖)
自訂色階調整 (通用色調運算子)
為影像的中間色調上色 (通用色調運算子)
全局色彩修改器
使用查詢表重新著色影像
在這裡,我們將探討修改影像中所有顏色的技巧。無論是讓影像變亮或變暗,還是更劇烈的色彩修改。
為了探索這些技巧,我們需要一個測試影像...
不用擔心我是如何實際產生這個影像的,這對練習來說並不重要。我設計它包含一系列的顏色、透明度和其他功能,特別是為了在使用時讓 IM 能夠好好發揮。
[IM Output]
如果您真的對用於產生此影像的命令感興趣,可以查看我用來建立它的特殊腳本「generate_test」。
警告:以下色彩處理流程通常假設影像使用的是線性色彩空間。然而,大多數影像都是使用 sRGB 或伽瑪校正色彩空間儲存的,因此,為了正確處理,也應該先套用色彩空間校正。

將色彩轉換為灰階

灰階影像在很多用途上都非常實用,例如,進一步處理原始影像或用於背景合成。將影像轉換為灰階的最佳方法是讓 IM 將影像變為灰階 色彩空間 表示。

  magick test.png  -colorspace Gray   gray_colorspace.png
[IM Output] ==> [IM Output]
請注意,藍色比紅色暗得多,這是因為加權以匹配人眼看到的強度。也就是說,「red」與看起來較暗的「blue」相比,是一種相當明亮的顏色。
這相當於對專用的「-grayscale」運算子使用「rec709luma」轉換公式(新增於 IM v6.8.3-10)。

  magick test.png  -grayscale rec709luma  gray_grayscale.png
[IM Output]
rec709luma」值只是已定義用於「-intensity」設定的眾多灰階公式之一(見下文)。
例如,以下是另一個常見的灰階公式「rec601luma

  magick test.png  -grayscale rec601luma  gray_grayscale_601.png
[IM Output]
如您所見,不同紅色、綠色和藍色通道的強度級別略有不同。
然而,還有許多其他方法和「灰階」的含義...
例如,您可以使用 調變運算子,將所有色彩飽和度級別設定為零,從而去除影像中的所有顏色。

  magick test.png  -modulate 100,0  gray_modulate.png
[IM Output]
這實質上是將影像轉換為 HSL 色彩空間,並從該色彩空間中提取灰階「亮度」值。但是,使用「-define modulate:colorspace」,您可以指定要使用的其他色彩空間模型。請參閱下方的 在其他色彩空間中調變。請注意,我在測試影像中用於中心彩色圓盤的 IM「green」顏色實際上並不是純綠色,例如彩色彩虹中使用的綠色,而是新的 SVG - 可縮放向量圖形 標準定義的半亮綠色。如果您需要純 RGB 綠色,則可以使用顏色「lime」。如需更多詳細資訊,請參閱 顏色名稱衝突
另一種方法是使用 FX DIY 運算子 對三個通道求平均值,以獲得灰階的純粹數學含義。

  magick test.png -fx '(r+g+b)/3' gray_fx_average.png
[IM Output]
sRGB 通道值的平均值也等於「OHTA」色彩空間(紅色通道)的強度通道。或 HSI 色彩空間的「I」通道。
另一種技術是簡單地將所有三個通道加在一起(一種稱為曼哈頓距離的顏色度量),雖然生成的影像不會因「量子舍入」效應而丟失資訊,但您可能會丟失有關最亮顏色的資訊。遺憾的是,您也會丟失透明度通道。

  magick test.png -separate \
          -background black -compose plus -flatten   gray_added.png
[IM Output]
您可以使用相同的通道相加技術來控制各個顏色通道的權重。例如,這是一個您可以使用的 DIY 公式...

  magick test.png -fx '0.3*r+0.6*g+0.1*b' gray_diy.png
[IM Output]
如果您希望在「-fx」運算子中具有相同的含義,則也可以使用「intensity」。

  magick test.png  -fx intensity  gray_intensity.png
[IM Output]

但是,由於 FX DIY 運算子 是被解釋的,因此它的運行速度可能會非常慢。對於更複雜的操作,您可以使用更簡單的 評估運算子-evaluate」。例如,以下是 2/5/3 比例的灰階影像,不過我再次沒有嘗試保留原始影像的透明度通道。

  magick test.png -channel R -evaluate multiply .2 \
                   -channel G -evaluate multiply .5 \
                   -channel B -evaluate multiply .3 \
                   -channel RGB -separate -compose add -flatten gray_253.png
[IM Output]
對於以「Q8」品質級別 編譯的 ImageMagick,上述內容會受到「量化」效應的影響。這是因為「-evaluate」的結果將被儲存在用於影像值的 8 位元小整數中。只有在之後,這些值才會被加在一起,從而導致準確性下降。

使用 'Q16' 編譯的 ImageMagick,或者更好的 HDRI 品質編譯選項,將會產生更精確的結果。另一個新的替代方案是 Poly - 加權影像合併運算子,它會在單一操作中完成分離通道影像的加權和加法,從而避免「量子舍入」效應。

類似的技術可以用於產生純數學灰階,方法是直接平均三個 RGB 通道。

  magick test.png -separate -evaluate-sequence mean  gray_average.png
[IM Output]
然而,正如您所見,我沒有嘗試保留結果影像的 Alpha 通道。另一個快速的替代方案是使用「-recolor」色彩矩陣運算子,它允許您指定三個色彩通道的權重。

  magick test.png -recolor '.2 .5 .3
                             .2 .5 .3
                             .2 .5 .3'   gray_recolor.png
[IM Output]
這不會影響透明度,但它是一種使用特定權重轉換色彩的更好方法。基本上,第一行數字是結果影像紅色通道的通道權重,接下來三個是綠色通道的權重,最後三個數字是藍色通道的權重。
您也可以使用「-type」來告訴 IM 在讀取或寫入影像時將其視為灰階。

  magick test.png  -type GrayScaleAlpha  gray_type.png
[IM Output]
-type」設定通常僅在讀取或寫入影像到檔案時作為指導。因此,它的動作會延遲到影像的最終寫入。它的效果也高度依賴於所涉及的影像檔案格式的功能,並用於在該過程中覆蓋 ImageMagick 的正常判定。有關更多資訊,請參閱 類型 範例。
在 IM v6.3.5-9 之前,由於錯誤,以上操作會移除寫入影像中的任何透明度(相當於「-type Grayscale」)。當我注意到這個問題並回報後,它就被修復了。(這裡有一個教訓 :-)

一個更有趣的技術是透過從影像的各種 色彩空間 表示中提取適當的 色彩通道 來提取各種不同的亮度含義。範例請參見 從色彩空間表示中提取灰階通道

影像色階調整

您可以對影像進行的最基本的調整形式稱為「色階」調整。這基本上意味著獲取個別的 RGB 色彩值(甚至 Alpha 通道值)並調整它們,以便拉伸或壓縮這些值。由於只調整通道值,因此它們最適合在灰階影像上展示,而不是彩色影像。但是,如果您將影像的所有色彩通道調整相同的量,則可以將它們與彩色影像一起使用,以便增強或調整影像。不要將此與我們將在下一個主要範例章節 正規化調整 中看到的更自動化的色階調整形式混淆。無論影像的實際內容如何,此函數都將執行完全相同的操作。影像的亮度、暗度或藍色或黃色色調並不重要。這些操作對實際的影像內容視盲。 [IM 圖表] 在演示這些操作時,我會使用一個修改過的「gnuplot」圖表,如右圖所示,我使用一個特殊的腳本「im_graph」來產生它。圖表中有一條紅線,將給定的原始「x」值(代表最上方漸層的灰階值)映射到顯示的「y」值。產生的顏色漸層也會顯示在輸入的線性漸層下方。右圖顯示的是 IM 的「-noop」運算子,它實際上不會對圖像進行任何操作。因此,每個圖像的顏色值都被映射到完全相同的值,而不會發生變化。因此,下方的漸層與上方的漸層相同。

圖像負片

您可以進行的最簡單、最基本的全域層級調整是使用「-negate」圖像運算子來反轉圖像。基本上,這會使白色變成黑色,黑色變成白色,並調整所有顏色以符合。也就是說,它會將紅色變成其互補色青色,藍色變成黃色,依此類推。您可以在下方顯示的映射圖表中看到這一點,因為我在「測試」圖像和標準 IM「玫瑰」內建圖像上都使用了「-negate」運算子。請注意映射圖表圖像中的下方漸層現在是如何反轉的,黑色和白色交換了位置,並且在負片「測試」圖像中也出現了相同的反轉。

  magick test.png  -negate  test_negate.png
  magick rose:    -negate  rose_negate.gif
[IM Output]
[IM Output]
==> [IM Graph] ==> [IM Output]
[IM Output]
實際上,負片運算在內部相當簡單。它會獨立處理三個顏色通道,並且預設情況下會忽略 Alpha 通道。如果不是這樣,您將會得到如下圖所示的非常奇怪的結果...

  magick test.png -channel RGBA  -negate  negate_rgba.png
[IM Output] ==> [IM Output]
您可以看到圖像被負片化了,因為半透明的顏色漸層。但是由於透明度通道也被負片化了,所以您會失去圖像中所有不透明的顏色。這就是為什麼「-channel」的預設設定是「RGB」的原因。有關更多資訊,請參閱色彩通道。您可以將負片化限制在一個通道,例如綠色通道。這看起來可能不是很有用,但在某些時候卻非常重要。

  magick test.png -channel green  -negate  negate_green.png
[IM Output] ==> [IM Output]
-negate」運算子實際上是它自己的反函數。使用相同的「-channel」設定進行兩次負片化會互相抵消。

  magick negate_green.png  -channel green  -negate  negate_restore.png
[IM Output] ==> [IM Output]
負片化在圖像處理中非常常見,特別是在處理灰階圖像時,作為其他處理選項之前或之後的一個步驟。因此,我建議您嘗試一下,並在進行任何操作時牢記這一點,因為處理負片圖像可以解決一些原本很困難的問題。

直接層級調整

-level」運算子是一個更通用的色階調整運算子。您基本上需要給它兩個值:「black_point」(黑點)和「white_point」(白點),以及一個可選的第三個值(伽瑪調整),我將在稍後討論。它的作用是將圖像中任何等於或小於「black_point」的顏色值映射為黑色(或 0 值)。同樣地,任何等於或大於「white_point」的顏色值都將變為白色(或最大值)。然後將這兩個點之間的顏色線性「拉伸」以填充整個值範圍。這樣做的效果是提高對比度,增強圖像中的色彩。例如,以下是我們測試圖像的 25% 對比度增強,使用了與圖表中所示相同的值。由於您通常會從 0%100% 的數量中以相同的量調整黑色和白色點,因此您只需指定「black_point」即可。白點將向內調整相同的量。

  magick test.png  -level 25%,75%  test_level.png
  magick rose:    -level 25%      rose_level.gif
[IM Output]
[IM Output]
==> [IM Graph] ==> [IM Output]
[IM Output]
請注意,25% 對任何圖像來說都是一個巨大的對比度增強,但它清楚地顯示了它的作用。您不必同時更改「黑色」和「白色」點。您可以只調整顏色範圍的一端。例如,我們可以製作一張非常亮或非常暗的玫瑰圖像。

  magick rose: -level 0,75%     rose_level_light.gif
  magick rose: -level 25%,100%  rose_level_dark.gif
[IM Graph] ==> [IM Output]  [IM Graph] ==> [IM Output]
然而,我再次警告您,超出給定範圍的顏色將被「裁剪」或「燒毀」,因此將不再可用於以後的圖像處理。這是使用「-level」運算子的最大問題。 [IM 圖表] 通過使用負值,您可以對圖像進行一些粗略的去對比度處理。這意味著,您不是為要映射到「黑色」和「白色」的值提供顏色值,從而拉伸它們之間的顏色,而是壓縮顏色值,以便將假想的負顏色映射到黑色或白色。結果是圖像的整體灰度化。

  magick rose: -level -25%  rose_decontrast.gif
[IM Output]

然而,這種降低圖像對比度的方法非常不準確,不推薦使用,除非您使用的 IM 版本早於 6.4.2,而該版本無法使用新的反向色階運算子 [IM 圖表] 您可以使用「-level」運算子來反轉圖像(如上所示,只需交換給定的「黑色」和「白色」點值,使用「-level 100%,0」)。

  magick rose: -level 100%,0  rose_level_neg.gif
[IM Output]

[IM 圖表] 或者通過將它們設置為相同的值,您可以有效地將圖像中的所有顏色值都設置為閾值。使用「-level」對圖像進行閾值處理與使用該值的閾值運算子完全相同。右側顯示的映射圖顯示了「-level 50%,50%」操作的結果,以及它對灰度漸變的影響。

  magick rose: -level 50%,50%  rose_level_thres.gif
[IM Output]

請注意,與「-threshold」不同的是,當與預設的「-channel」設定一起使用時,圖像不會自動轉換為灰階圖像。使用 level 線性修改圖像的通用性,使得「-level」運算子非常適合一般的灰階圖像修改和遮罩調整。此外,您可以修改單獨的通道(使用「-channel」設定),而不是整個圖像,這使其成為 IM 用戶可用的最佳色彩修改運算子之一。
請注意,您也可以使用評估和函數運算子對顏色值進行更直接的數學修改,以實現與 -level + 和 - 形式相同的結果。
請注意,「-level」運算子將透明度通道視為「遮罩」值。因此,100% 是完全透明的,0% 是不透明的。在對模糊的形狀圖像使用「-level」時,請考慮這一點。這通常在模糊「形狀」圖像後完成,以擴展和拉伸結果。有關這方面的示例,請參見柔邊陰影輪廓

反轉色階調整-- 降低圖像對比度

從 IM 版本 6.4.2 開始,Level 運算子已擴展為提供「反轉」形式「+level」(請注意「加號」)。或者,您可以使用運算子的原始「-level」形式,但在給定的 level 參數中添加「!」(對於較舊的 API 介面)。此變體的參數完全相同,但它不是拉伸值以將「黑點」和「白點」映射到「黑色」和「白色」,而是將「黑色」和「白色」映射到給定的點。換句話說,「+level」與「-level」完全相反。例如,在這裡,我們使用兩種指定「反轉」形式的方法,將「黑色」映射到 25% 灰色,將白色映射到 75% 灰色,從而以非常精確的方式降低圖像的對比度。

  magick test.png   +level 25%    test_level_plus.png
  magick rose:     -level 25%\!  rose_level_plus.gif
[IM Output]
[IM Output]
==> [IM Graph] ==> [IM Output]
[IM Output]
如果將上述「+level 25%」操作與我們之前展示的負對比度降低「-level -25%」運算子進行比較,您會發現它們並不相同。「加號」版本會產生對比度降低得多的圖像(更灰),但它通過映射到您為運算子提供的精確值來實現,而不是「減號」形式使用的「虛擬」值。這種精確的值使用非常重要,也是添加「加號」形式運算子的原因之一。當然,「25%」又是一個非常大的值,不建議在典型的圖像處理中使用。請注意,「-level」和「+level」在給定相同參數時實際上互為相反。也就是說,一個將值映射到範圍的極值,而另一個從範圍的極值映射。例如,在這裡,我們使用「+level」壓縮測試圖像的顏色,然後使用「-level」再次解壓縮它們,以便將圖像恢復到接近其原始外觀。

  magick test.png  +level 20%  -level 20%  test_level_undo.png
[IM Output] ==> [IM Graph] ==> [IM Output]
這兩張圖片看起來非常非常相似,因為我使用的是高 品質 的「Q16」版本 IM,您將很難注意到任何差異。 但是,這些值可能不完全相同,因為您實際上已將圖像的顏色值壓縮到較小的整數範圍,然後又將其恢復。 在極端情況下,這可能會導致 量子捨入效應。 以相反的順序執行這兩個操作(拉伸,然後壓縮顏色值)將產生 量子限幅效應。 「+level」運算符的另一個有用之處是,您可以將圖像中的所有顏色值完全壓縮到相同的灰度級。

  magick test.png  +level 30%,30%  test_level_const.png
[IM Output] ==> [IM Graph] ==> [IM Output]
通過根據每個單獨通道的特定顏色的值指定級別,您可以有效地將灰度梯度變為特定顏色梯度。 但是,這很難計算和執行。 因此,還提供了一個「-level-colors」運算符,它允許您根據特定顏色而不是「級別」值來指定黑白點。 請參閱下面的按顏色分級

級別伽瑪調整

上面的兩個「-level」變體也允許您使用第三個設定。 「伽瑪」調整值。 默認情況下,它設置為值 1.0,它不會對結果圖像進行任何中間色調調整,從而產生從舊圖像到新圖像的值的純線性映射。 但是,通過增大此值,您將彎曲結果線以使圖像變亮,而縮小該值將使圖像變暗。 例如,在這裡我只使用「伽瑪」設定來增亮和變暗圖像的中間色調。

  magick rose: -level 0%,100%,2.0   rose_level_gamma_light.gif
  magick rose: -level 0%,100%,0.5   rose_level_gamma_dark.gif
[IM Graph] ==> [IM Output]  [IM Graph] ==> [IM Output]
值通常從極亮的圖像的 10 到非常暗的圖像的 0.2 不等。 如前所述,值 1.0 將不會對圖像進行「伽瑪」更改。 但是,可以使用特殊值「2.0」(見上文)來獲得圖像歸一化顏色的平方根。 「-level」運算符的兩個版本都以相同的方式處理「伽瑪」。 這意味著您可以將「黑色」和「白色」端的級別調整與非線性「伽瑪」調整相結合。 您也只能調整圖像的單個通道。 例如,在這裡,我們在藍色通道的黑色端給予圖像微妙的色彩,同時使用伽瑪來保留圖像的中間色調顏色級別。

  magick test.png  -channel B +level 25%,100%,.6 test_blue_tint.png
[IM Output] ==> [IM Graph] ==> [IM Output]
這個具體示例可用於為氣象衛星照片著色,其中只有海洋是純黑色的,而陸地是灰色的。 下面的DIY 數學非線性調整中給出了此藍色通道調整的其他替代方案。

伽瑪運算調整

還提供了「-gamma」運算符,它與「-level」運算符中的「伽瑪」設定具有完全相同的效果。 但是,它也允許您調整每個單獨通道的「伽瑪」調整級別。 它的真正用途是在對圖像執行線性運算之前調整圖像的「伽瑪」函數。 有關更多詳細信息,請參閱人類顏色感知和伽瑪校正。 我們還可以使用此函數為每個單獨的 RGB 通道以不同的方式增亮圖像。

  magick rose: -gamma 0.8,1.3,1.0  gamma_channel.gif
[IM Output]
如您所見,這可用於對圖像進行一些細微的著色和顏色調整,或校正包含過多特定顏色的圖像。
關於為何您應該使用這個函數的原因,請參見 Gamma 校正

這個函數實際上等同於 Evaluate POW 函數,但參數是反向的。因此,「-evaluate POW 2.2」實際上會執行「-gamma 0.45455」(0.45455 等於 1/2.2)運算,這與「-gamma 2.2」相反。
-gamma」較不為人知的一個用途是將特定影像通道歸零(請參見 歸零色彩通道)。或者將影像完全著色為「黑色」、「白色」或其他原色(請參見 原色畫布)。

依顏色調整色階

-level-colors」運算符是在 IM v6.2.4-1 中新增的。本質上,它與我們上面討論的 色階運算符 完全相同,但每個通道的值都指定為顏色值。也就是說,「-level-colors」選項會將給定的顏色映射到「黑色」和「白色」,並線性拉伸它們之間的所有其他顏色。這有效地從影像中移除給定的顏色範圍。雖然這樣做有效,但並不是特別有用,因為它很容易在某些通道中具有共同值的顏色上失敗。例如,顏色「DodgerBlue」和「White」在藍色通道中具有相同的顏色值。因此,「-level-colors DodgerBlue,White」可能無法始終將這些顏色魔術般地變為黑色和白色。在這種情況下,更好的技術是使用差異最大的通道(例如紅色)提取灰階影像,並對該通道進行色階調整或標準化。警告:請注意「透明」顏色。
另一方面,運算符的加號形式「+level-colors」非常有用,因為它會將「黑色」和「白色」映射到給定的值,並線性壓縮所有其他顏色以適應您給定的兩種顏色。例如,讓我們將「black」和「white」映射到「green」和「gold」...

  magick test.png  +level-colors green,gold   levelc_grn-gold.png
[IM Output] ==> [IM Output]
如您所見,灰階漸層被重新映射到由給定顏色界定的漸層中,並且儘管灰階範圍之外的顏色也被修改,但它們也將遵循指定的顏色範圍的基本樣式。這使得「+level-colors」運算符成為一個非常有用的運算符,尤其是在映射灰階影像時。如果您只提供一種顏色名稱但包含逗號,則缺少的顏色將根據需要預設為「black」或「white」。

  magick test.png  +level-colors ,DodgerBlue   levelc_dodger.png
  magick test.png  +level-colors ,Gold         levelc_gold.png
  magick test.png  +level-colors ,Lime         levelc_lime.png
  magick test.png  +level-colors ,Red          levelc_red.png

  magick test.png  +level-colors Navy,         levelc_navy.png
  magick test.png  +level-colors DarkGreen,    levelc_darkgreen.png
  magick test.png  +level-colors Firebrick,    levelc_firebrick.png
[IM Output] [IM Output] [IM Output] [IM Output]
[IM Output] [IM Output] [IM Output]
這使得將灰階影像魔術般地變成您喜歡的任何顏色的漸層變得容易。例如,在這裡我將黑白漸層重新映射到紅白漸層,(請注意參數中的「,」)...

  magick cow.gif   +level-colors red,   cow_red.gif
[IM Output] ==> [IM Output]
這不僅將「黑色」替換為「紅色」,而且還將所有反鋸齒灰色重新映射到「紅色」和「白色」的適當混合,從而產生非常平滑的結果。[IM 輸出]如果我只是執行一個簡單的 直接顏色替換 將純黑色轉換為紅色,我最終會得到可怕的影像(如右圖所示)。請參見 模糊因素 以獲取用於生成該影像的範例。當然,如果您希望將其中一種顏色設為透明,則最好使用 -alpha 形狀 運算符,因為這需要您將漸層轉移到 Alpha 通道中。
如果您只指定一種顏色,而不使用任何「逗號」分隔符,則該顏色將同時用於黑色和白色點。這意味著影像中的所有顏色都將重置為該顏色。(根據目前的「-channel」設定限制)。

  magick test.png  +level-colors dodgerblue  levelc_blue.png
[IM Output]
這與使用「-fill DodgerBlue -colorize 100%將影像彩色化(見下文)的結果相同。如果您也想設定影像的透明度,則需要設定「-channel」以包含透明度通道,或者使用「-alpha opaque」或「-alpha off」將Alpha 通道設定為完全不透明。

  magick test.png -channel ALL +level-colors dodgerblue levelc_blue2.png
[IM Output]
另請參閱清空現有影像。以下是一些使用此功能調整或「著色」彩色影像(而非灰階影像)的範例。

  magick rose: +level-colors             navy,lemonchiffon  levelc_faded.gif
  magick rose: +level-colors        firebrick,yellow        levelc_fire.gif
  magick rose: +level-colors 'rgb(102,75,25)',lemonchiffon  levelc_tan.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output]
總之,「+level-colors」是一種漸變顏色替換,一種線性著色運算子,也可以完全重置顏色。

Sigmoidal 非線性對比度

在關於「影像處理基礎」的 PDF 論文中(第 44 頁),他們提出了一種使用伽瑪校正(稱為「S 形非線性對比度控制」)來替代線性對比度控制(級別)的方法。其結果是在整個色彩範圍內產生非線性、平滑的對比度變化(在數學上稱為「S 形函數」),保留了白色和黑色,更適合於照片色彩調整。論文中的確切公式非常複雜,甚至還有一個錯誤,但基本上需要兩個調整值。對比度函數要集中的閾值級別(通常集中在「50%」),以及對比度因子(「10」非常高,「0.5」非常低)。
對於感興趣的人,「S 形非線性對比度控制」的修正公式如下...
( 1/(1+exp(β*(α-u))) - 1/(1+exp(β*(α)) ) / ( 1/(1+exp(β*(α-1))) - 1/(1+exp(β*α)) )
其中 α 是閾值級別,β 是要應用的對比度因子。

這是使用中間變數的公式的替代版本。
x = exp(β * (α - u)) y = exp(β + 1 結果 (x / y + 1) * (1 / (x + 1) - 1 / y)
該公式實際上是非常簡單的指數曲線,上述公式的大部分內容旨在確保 0 保持為零,1 保持為一。也就是說,圖形始終穿過點 0,0 和 1,1。而最大的變化梯度位於給定的閾值處。
例如,以下是上述公式的「-fx」實現,其結果是對比度值非常高,為「10」,閾值為「50%」。這些值已轉換為浮點常數,以加快函數的執行速度。

  magick test.png  -fx '(1/(1+exp(10*(.5-u)))-0.006693)*1.013567' \
              sigmoidal.png
[IM Output] ==> [IM Graph] ==> [IM Output]
幸運的是,IM v6.2.1 將此複雜函數內建為新的運算子「-sigmoidal-contrast」,從而可以更輕鬆地應用。

    magick test.png  -sigmoidal-contrast 10,50% test_sigmoidal.png
[IM Output]
此外,IM 還提供了逆函數,即「S 形對比度降低」函數(作為運算子的加「+」形式),如果使用相同的參數應用,則可以恢復原始影像(幾乎完全相同)。

    magick test_sigmoidal.png +sigmoidal-contrast 10,50% \
                                             test_sigmoidal_inv.png
[IM Output]
在這裡,我們將其應用於玫瑰影像...

    magick rose: -sigmoidal-contrast 10,50%  rose_sigmoidal.gif
[IM Output]
我確實說過「10」是一個非常大的對比度因子。實際上,任何高於此值的值都可以被認為更像是模糊閾值運算,而不是對比度增強。有關使用此運算子的實際範例,請參閱高級「凝膠」效果範例,其中它用於銳化添加到形狀區域顏色的明亮區域。

其他對比度運算子

建設中
   -contrast  and   +contrast
         Rather useless minor contrast adjustment operator

-threshold
   Threshold the image, any value less than or equal to the given value is
   set to 0 and anything greater is set to the maximum value.

   Note that like level, this is a channel operator, but if the default
   'channel setting' is used only the gray-scale intensity of the image is
   thresholded producing a black and white image.

   magick rose: -threshold 45%  x:

   You can force normal channel behaviour, where each channel is thresholded
   individually buy using "-channel All"

   magick rose: -channel All -threshold 45%  x:

-black-threshold
-white-threshold
   This is like -threshold except that only one side of the threshold value is
   actually modified.

   For example, here anything that is darker than 30% is set to black.

   magick rose: -black-threshold 30%  x:
   magick rose: -white-threshold 50%  x:

   These operators however do not seem to be channel effected, so may only be
   suitable for gray-scale images!


使用直方圖修改進行調整

本節由 Fred Weinhaus 與 Anthony Thyssen 共同撰寫。 直方圖是一種特殊的圖表,它簡單地將圖像中像素的顏色級別排序到固定數量的「區間」中,每個區間涵蓋一定範圍的值。因此,每個區間都包含圖像中落入該範圍的顏色級別(像素值)的計數。結果便呈現出構成圖像的顏色值的分佈情況,從左邊的黑色到右邊的白色。
可以分別為每個通道生成直方圖,也可以生成查看所有通道組合值的全局直方圖。結果通常顯示為條形圖的圖像。在 IM 中,這是使用特殊的 直方圖: 輸出格式完成的。例如...

  magick rose: histogram:histogram.gif
[IM Output]
但它也可以顯示為線條圖,其中線條連接條形的頂部。這將在下面的討論中稍後演示。有關此特殊輸出格式的更多詳細信息,請參閱 直方圖:。建議您現在閱讀此內容,因為這是使用 IM 提取圖像直方圖信息的最佳方式。直方圖的實際高度幾乎沒有實際意義,因為它通常會縮放到最高峰接觸圖像頂部。因此,每個「條形」的高度並不重要。更重要的是整個範圍內的直方圖分佈,以及整個圖表中相對高度之間的關係。在查看直方圖時,您需要考慮以下因素。
  • 直方圖是否形成了一個寬的數值帶?這意味著圖像充分利用了色彩空間,因此具有良好的對比度。
  • 或者它是否都集中在中間或範圍的一端?這意味著圖像的對比度較低,使其看起來「模糊」或「灰濛濛」,或者可能過亮或過暗。
  • 它是否形成兩個或多個峰值?由於圖像中存在高度不同的區域或區域。
  • 大多數像素在哪裡?在左側,表示圖像非常暗。或者在右側,表示它非常亮。還是分佈在中間附近?
  • 各個條形之間是否有規則的間隙或空白?這通常意味著圖像的像素非常少,因此無法完全填充整個直方圖,或者圖像的顏色減少了或以某種方式進行了修改,從而產生了這些間隙。
本質上,直方圖是圖像的更簡單表示,因此更容易根據其直方圖更改或調整圖像。幾乎所有應用於圖像的數學顏色變換通常都會導致圖像及其直方圖發生變化。這些包括線性運算(例如色階運算符)或非線性運算(例如伽瑪運算符)(見上文)。我們上面看到的映射圖表示圖像中的灰度級,從而表示圖像的直方圖將如何轉換。例如,讓我們創建一個低對比度圖像來演示。但是,最終結果是它不僅修改了圖像,而且是通過修改圖像的直方圖(通過壓縮它)來實現的。

  magick chinese_chess.jpg -contrast -contrast -contrast -contrast \
          chinese_contrast.png

  magick chinese_chess.jpg     histogram:chinese_chess_hist.gif
  magick chinese_contrast.png  histogram:chinese_contrast_hist.gif
[IM Output] ==> [IM Output]
[IM Output] ==> [IM Output]
在上述情況下,「-contrast」是一個簡單的色階類型的運算子,僅為圖像添加一點對比度。結果是直方圖本身更加分散,使其更好地覆蓋整個可能的顏色範圍。您也可以從前後的直方圖中看到,由於拉伸的執行方式,顏色最終也會在「區間」之間出現間隙和孔洞。具體來說,它會創建一個「直方圖」,將所有顏色放入「區間」中。然後將這些「分箱」的顏色作為一個整體進行修改,導致圖像顏色被組合在一起。這並不是一種特別好的處理圖像顏色的方法。然而,這個運算子是盲目工作的,它不了解圖像內容或顏色分佈。因此,它不能沒有用戶的控制,因為這個運算子很容易使任何應用它的圖像變得更糟,而不是更好。在本節中,我們將研究將圖像的直方圖作為其決策過程一部分的圖像處理運算子。然後,它使用這項研究的結果來修改圖像,以增強圖像顏色分佈的某些品質。由於這些運算子利用了來自正在處理的圖像的實際信息,因此它們通常可以在許多圖像上更全局地使用,而無需用戶進行太多檢查。這種類型的運算子包括自動線性「色階」類型的運算子,例如「-normalize」、「-contrast-stretch」和「-linear-stretch」,但也包括非線性的運算子,例如「-equalize」,以及其他可能最終包含在 ImageMagick 中的運算子,例如Fred Weinhaus 的腳本「redist」。

直方圖拉伸

最簡單的技術,就像前面的示例一樣,只是將圖像的直方圖向外拉伸以改善顏色範圍。但是,它們不是盲目地為色階操作選擇黑點白點,而是根據圖像直方圖選擇點。基本上,它們從兩端向內計算每個直方圖箱中顏色值的数量,直到達到某个閾值。然後,這些點將用作直方圖(色階)拉伸的黑點白點需要圖表基本上,直方圖計數提供了拉伸將強制為黑色和白色的灰度值。這意味著圖像中所有落在從純黑色到所選黑點箱的相應灰度級的箱範圍內的像素最终都將變為純黑色。同樣,圖像中落在從純白色到白點箱的相應灰度級的箱範圍內的像素最终都將變為純白色。但是,位於這些點之外的像素將被拉伸到可能的顏色值範圍之外,因此它們將被簡單地設置為範圍限制。也就是說,這些像素在轉換為純黑色或純白色的極端顏色值時會被“裁剪”“燒錄”。結果,如果選擇黑點白點的“閾值”限制設置得太高,您將在圖像中看到許多黑色和白色區域,導致直方圖在極端端的箱中具有很大的計數(高條)。嚴重燒錄的示例 - 中國象棋圖像? “拉伸”運算符的摘要... -contrast-stretch 和 -linear-stretch 都會生成直方圖(使用 1024 個箱)來確定要拉伸的顏色位置。因此,它不是“精確的”。另一個區別是如何處理“零”,以及 -linear-stretch 實際上執行 -level 操作來進行拉伸,而 -contrast-stretch 使用直方圖箱值進行顏色替換拉伸(這會引入 1024 量子舍入效應。-normalize 在內部使用 -contrast-stretch。一個數學上完美的歸一化拉伸運算符是 -auto-level。雖然“僅限白點”或“僅限黑點”的完美版本是可能的,但目前尚未實作。

自動色階 - 完美的數學歸一化

-auto-level” 會在圖像中找到最大和最小的值,用於將圖像拉伸到完整的量子範圍。絕不會因為直方圖被拉伸到值範圍之外而導致值被“裁剪”或“燒錄”。“-channel” 設置將決定所有通道是“同步”地(使用所有通道上的最大值和最小值)還是單獨地(每個單獨的通道作為一個單獨的實體)進行拉伸。目前,完全透明像素的隱藏顏色也用於確定色階,這在涉及透明度時可能會導致一些問題。這被認為是一個錯誤。
FUTURE: We actually need three modes of operation...
  synced color channels with 'alpha' (and 'read') masking.
  synced channels (as defined by channel)       (current default)
  individual separate channels   (currently if -channel is set by user)
它是一種純粹的數學直方圖拉伸,就像手動色階運算符一樣。也就是說,最小值將調整為零,最大值將調整為量子範圍,並使用線性方程式調整圖像中的所有其他值。它不使用其他方法可能用於確定要使用的色階或其他直方圖調整的“直方圖箱”或任何其他“值的組合”。

標準化

-normalize」運算符是這三個運算符中最簡單的一個。它只是簡單地擴展灰度直方圖,使其佔據灰度值的完整動態範圍,同時在直方圖的低端(黑色)裁剪或燃燒 2%,在高端(白色)裁剪或燃燒 1%。也就是說,圖像中最暗的 2% 灰度將變為黑色,最亮的 1% 灰度將變為白色。這在大多数圖像中並不會造成很大的損失,而且總體結果是圖像的對比度(強度範圍)將自動最大化。*這裏需要一個理想化的示意圖!* *可以用中國象棋作為例子?* 在這裡,我們創建一個灰度梯度,並將其擴展到完整的黑白範圍。

  magick -size 150x100 gradient:gray70-gray30 gray_range.jpg
  magick gray_range.jpg  -normalize  normalize_gray.jpg
[IM Output] ==> [IM Output]
出於 JPEG 色彩不準確(有關詳情,請參閱JPEG 色彩失真)和掃描圖像噪聲的實際原因,「-normalize」並不會擴展最亮和最暗的顏色,而是在這些值之外稍微擴展一點。也就是說,它相當於「-contrast-stretch」,其值為「2%,99%」(見下文)。

這意味著,如果最高和最低顏色值非常接近,「-normalize」將失敗,並且不會執行任何操作。

如果您真的想將最亮和最暗的確切顏色值擴展到其極限,請改用「-auto-level」。
在 IM 6.2.5-5 版之前,「-normalize」僅作為灰度運算符工作。也就是說,紅色、綠色、藍色和 Alpha 通道根據「-channel」設置獨立擴展。從 IM 6.2.5-5 版開始,如果僅提供默認的「+channel」設置,則「-normalize」會將所有顏色通道綁定在一起,並將它們全部標準化為相同的值。這確保了圖像內的像素顏色不會偏移。但是,這也意味著您可能無法獲得純白色或純黑色的像素。例如,在這裡,我們在標準化測試圖像中添加了一些額外的顏色(從藍色到海軍藍的漸變)。

  magick -size 100x100 gradient:gray70-gray30 \
          -size  50x100 gradient:blue-navy  +append  color_range.jpg
  magick color_range.jpg -normalize  normalize.jpg
[IM Output] ==> [IM Output]
從最後一個示例中可以看出,對於彩色圖像,「-normalize」會將所有通道一起最大化,因此一個通道的值為零,而另一個通道的值為最大值。也就是說,沒有生成黑色像素,因為所有添加的藍色在“紅色”和“綠色”通道中已經包含“零”值。因此,圖像的下限沒有擴展。
如果您希望使用舊的「-normalize」行為(IM v6.2.5-5 之前),則需要指定任何非默認的「-channel」設置。對於不包含 Alpha(或遮罩)通道的圖像,您可以僅使用「all」通道設置。

  magick color_range.jpg -channel all  -normalize   normalize_all.jpg
[IM Output]
或者,您可以使用「-separate」運算符(從 IM v6.2.9-2 開始)將每個通道標準化為單獨的圖像,然後使用「-combine」將它們重新組合成一個圖像。

  magick color_range.jpg -separate -normalize -combine normalize_sep.jpg
[IM Output]
在最後兩個示例中,我們看到圖像的灰度區域變成了黃色,因為“red”和“green”通道變亮了,而“blue”通道僅略微變暗。這為我們帶來了一個重點
標準化和其他直方圖運算符實際上是灰度運算符,
在彩色圖像中使用它時需要格外小心。
事實上,「-normalize」只是更通用的「-contrast-stretch」的一個子集,其中黑點預設值為 2%,白點預設值為 1%。那麼「-contrast-stretch」是什麼?

contrast-stretch(對比度拉伸)

-contrast-stretch」運算子(IM v6.2.6 中新增)類似於「-normalize」,不同之處在於它允許用戶指定要剪裁或燒錄的像素數量。也就是說,它讓您可以控制直方圖拉伸時使用的「黑點」和「白點」選擇。因此,用戶可以指定圖像中最暗的灰色像素數量(或百分比),這些像素將變為黑色,以及最亮的灰色像素數量(或百分比),這些像素將變為白色。例如,這會將頂部和底部 15% 的顏色替換為其極端值(白色和黑色),並適當拉伸其餘 70% 的顏色。最終結果是嘗試改善圖像的整體對比度。

  magick gray_range.jpg  -contrast-stretch 15%  stretch_gray.jpg
[IM Output] ==> [IM Output]
您也可以輕鬆地在上述漸層的頂部和底部看到「燒錄」和「剪裁」效果,因為這些灰色被拉伸到遠遠超出顏色範圍的限制。
在這裡,我有意「燒錄」了 90% 的較暗灰色,僅留下 10% 的最亮像素在圖像頂部拉伸成緊密的線性漸層。

  magick gray_range.jpg  -contrast-stretch 90%x0%  stretch_black.jpg
[IM Output]
這在尋找圖像中最亮的「N」個像素時非常有用,因為它們將是唯一沒有被「燒錄」為零值的像素。(更好的方法是使用「-threshold-black」)「-contrast-stretch」的一個重要方面是對黑點白點閾值計數使用零。在這種情況下,「-contast-stretch 0」將定位圖像直方圖中的最小和最大區間。由於計數實際上是從這些區間開始的,因此結果只是將最小和最大區間拉伸到完全黑色和完全白色。這將導致對比度拉伸,剪裁量最少或可能為零,並且這些「區間」中的所有值都變為 0 和最大值。
 
建設中

線性拉伸

在許多方面,「-linear-stretch」與之前的「-contrast-stretch」運算子非常相似。這兩個函數都可以接受黑點和白點參數,可以是原始計數或涉及的像素總數的百分比。但是,有幾個重要的區別。一個區別與如何計算默認的黑點和白點有關。使用「-contrast-stretch」。如果只提供一個值(黑點),則白點將是相同的值。因此,「-contrast-stretch 1」等同於「-contrast-stretch 1x1」,而「-contrast-stretch 1%」等同於「-contrast-stretch 1x1%」。但是,使用「-linear-stretch」,如果只提供一個值(黑點),則白點將是補數值。也就是說,如果黑點被指定為原始計數,則白點將是圖像中的總像素減去黑點計數。同樣,如果黑點被指定為百分比計數,則白點將是 100% 減去黑點百分比計數。因此,「-linear-stretch 1%」將等同於「-linear-stretch 1x99%」。第二個區別與計數開始的位置有關。考慮一個具有 256 個 bin(一些“bin”可能計數為零)的直方圖,從灰階 0 到灰階 255。在「-contrast-stretch」中,計數從零開始,圖像中最低(最小)和最高(最大)填充的 bin(在直方圖中可能是或不是 bin 0 或 bin 255)。因此,10% 的黑點將累積從最小 bin 之後的所有 bin 的計數,直到達到 10%,並從該灰階拉伸黑色側。因此,在直方圖的黑色側燒錄的量最終將是 10% 加上之前在較暗的“bin”中發現的量。從直方圖的亮側計數也是如此。使用「-linear-stretch」,計數從直方圖的末端開始,即在 bin 0 和 bin 255 處。因此,在暗側燒錄的量將始終是黑點值,而在亮側燒錄的量將始終是白點值。舉個例子,讓我們取一個 100 像素的漸變,並查看其直方圖。

  magick -size 1x100 gradient: \
          -depth 8 -format "%c" histogram:info:
[IM Text]
正如預期的那樣,每個 bin 都平均填充了一個像素,產生了 1 的計數。(要查看完整列表,請單擊上面的輸出文本圖像)。現在讓我們在使用「-contrast-stretch 10x10%」後執行相同的操作

  magick -size 1x100 gradient:   -contrast-stretch 10x10%  \
          -depth 8 -format "%c" histogram:info:
[IM Text]
現在是「-linear-stretch 10x10%」。

  magick -size 1x100 gradient:   -linear-stretch 10x10%  \
          -depth 8 -format "%c" histogram:info:
[IM Text]
因此,我們確認對於「-contrast-stretch 10x10%」,我們在每一端獲得 11 個像素。也就是說,等於末端 bin 中的計數加上圖像像素的 10%,等於 10 個像素。所以燒錄了 10+1=11 個像素。另一方面,在「-linear-stretch」中,末端 bin 最終只包含 10 個像素或圖像的 10%。上述差異的一個結果是,「-contrast-stretch 0x0」可能會改變圖像,如果最低和/或最高填充的 bin 不是 0 和 255 處的末端 bin。在這種情況下,圖像將在與這些 bin 相對應的灰階之間拉伸。另一方面,「-linear-stretch 0x0」永遠不會改變圖像。例如,讓我們取漸變並將其灰階在每一端壓縮 10%。也就是說,我們將黑點向上移動 10% 到灰階 26,將白點向下移動 10% 到灰階 230。

  magick -size 1x100 gradient:   +level 10x90%  \
          -depth 8 -format "%c" histogram:info:
[IM Text]
現在,讓我們將「-contrast-stretch 0x0」應用於上述去對比度的漸變

  magick -size 1x100 gradient: -level 10x90%  -contrast-stretch 0x0  \
          -depth 8 -format "%c" histogram:info:
[IM Text]
現在是「-linear-stretch 0x0

  magick -size 1x100 gradient: -level 10x90%  -linear-stretch 10x10% \
          -depth 8 -format "%c" histogram:info:
[IM Text]
因此我們可以看到原始影像的直方圖沒有涵蓋從 0 到 255 的完整動態範圍。它只在灰階 26 到 230 之間。但在套用「-contrast-stretch 0x0」之後,它被拉伸到完整的動態範圍。另一方面,「-linear-stretch 0x0」對結果直方圖沒有任何改變。第三個區別是「-contrast-stretch」對通道敏感,而「-linear-stretch」則否。這意味著使用「-contrast-stretch」可以更改任何一個或多個通道,而不會影響其他通道。因此,如果沒有指定通道,則將使用所有通道的整體直方圖以相同的方式修改所有通道,以便不會產生顏色偏移。但是,如果指定了「-channel RGB」,則每個通道將單獨拉伸,結果將取決於每個通道中的末端 bin。如果它們不同,則會在結果影像的各個通道之間產生顏色偏移。使用「-linear-stretch」時,所有通道都將以相同的方式處理,從而確保不會產生通道之間的顏色偏移。所以讓我們來看看一張真實影像的詳細資訊和直方圖。

  magick port.png  -verbose -identify +verbose  histogram:port_hist.gif
[IM Text] [IM Output]
[IM Output]
我們可以看到,上述影像的通道都沒有涵蓋完整的動態範圍。另請注意,每個通道的數值範圍都不同。現在讓我們在沒有「-channel」設定的情況下套用「-contrast-stretch 1x1%」。

  magick port.png -contrast-stretch 1x1% \
          -write histogram:port_cs1_hist.gif   port_cs1.png
[IM Output] [IM Output]
在上述結果中,影像在所有通道上都一致地拉伸。因此,通道之間沒有顏色偏移。現在讓我們使用「-channel RGB」來做同樣的事情。

  magick port.png  -channel RGB  -contrast-stretch 1x1% \
          -write histogram:port_cs1rgb_hist.gif    port_cs1rgb.png
[IM Output] [IM Output]
在上述結果中,因為我們設定了「-channel RGB」,而不是使用預設通道設定,所以影像在每個通道上的拉伸方式都不同。這會導致通道之間的顏色偏移。現在讓我們在沒有「-channel」設定的情況下套用「-linear-stretch」。

  magick port.png   -linear-stretch 1x1% \
          -write histogram:port_ls1_hist.gif \
          port_ls1.png
[IM Output] [IM Output]
在上述結果中,影像在所有通道上都一致地拉伸。所以通道之間沒有顏色偏移。現在讓我們使用「-channel RGB」來做同樣的事情。

  magick port.png  -channel RGB  -linear-stretch 1x1% \
          -write histogram:port_ls1rgb_hist.gif    port_ls1rgb.png
[IM Output] [IM Output]
在上述使用「-linear-stretch」的結果中,影像在所有通道上都一致地拉伸,並且「-channel RGB」被忽略。因此,通道之間沒有顏色偏移,結果與上述沒有「-channel RGB」的結果相同。 

直方圖重新分配

直方圖重新分配是一種非線性技術,它重新分配直方圖中的 bin 以實現某些特定的形狀。兩種最常見的形狀是均勻(平坦)和高斯(鐘形),儘管雙曲線和瑞利分佈也是其他類型的分佈。

均衡化 - 均勻直方圖重新分配

對於均勻分佈的情況,直方圖 bin 會被移動、間隔和組合,以便平均而言,直方圖在整個範圍內具有平坦或恆定的高度。這稱為直方圖均衡化。IM 函數「-equalize」就是這樣做的。遺憾的是,它分別對每個通道進行操作,而不是對所有通道套用相同的操作。因此,當它被套用於 RGB 色彩空間時,可能會出現顏色偏移。以下是一個使用 IM 函數 -equalize 進行直方圖均衡化的範例。請注意,各個通道獨立均衡化後,色彩平衡會發生變化。

  magick zelda.png  -write histogram:zelda_hist.gif \
          -equalize  -write histogram:zelda_equal_hist.gif \
          zelda_equal.png
[IM Output] ==> [IM Output]
[IM Output] ==> [IM Output]
您可能會注意到直方圖看起來不太均勻。但如果我們將結果影像轉換為灰階並顯示其直方圖,則與原始影像的灰階直方圖相比,其直方圖看起來更均勻一些。

  magick zelda.png  -colorspace gray   histogram:zelda_ghist.gif

  magick zelda_equal.png  -colorspace gray \
          histogram:zelda_equal_ghist.gif
[IM Output] ==> [IM Output]
另一種重新分配 bin 的方法是使用從每個通道的單獨累積直方圖和所需的積分分佈曲線生成的轉換查找表。 如果不希望通道之間有任何顏色偏移,則使用圖像所有通道的組合直方圖。 一種近似方法是簡單地使用將圖像轉換為灰度後的直方圖。 Fred Weinhaus 開發了一個名為「redist」的腳本,它正是這樣做的。 它將圖像的直方圖重新分佈到均勻分佈中,同時將相同的更改應用於所有顏色通道。

  redist -s uniform zelda.png  zelda_uniform.png

  magick zelda_uniform.png   histogram:zelda_uniform_hist.gif
[IM Output] ==> [IM Output]
[IM Output] ==> [IM Output]
請注意結果與內建 IM「-equalize」運算子的不同之處。 具體來說,所有顏色都保留了,沒有您之前看到的顏色偏移。 腳本的作用是處理灰度直方圖,然後將其應用於所有顏色通道,以便所有顏色都保持在一起。 為了與 IM「-equalize」直方圖進行比較,我們也將在此處顯示灰度直方圖結果。 請注意,重新分佈的直方圖似乎比 IM equalize 的直方圖更平坦(平坦或均勻)。

  magick zelda.png  -colorspace gray   histogram:zelda_ghist.gif

  magick zelda_uniform.png  -colorspace gray \
          histogram:zelda_uniform_ghist.gif
[IM Output] ==> [IM Output]
未來:添加在其他色彩空間中均衡的示例! 也就是 HSL、HSB 和 CMYK 色彩空間中的灰度通道。

高斯重新分配

均衡直方圖並不是改變圖像直方圖分佈的唯一方法。 實際上,它通常不是很有用,除非在電腦視覺應用中。 這是同一張圖像,但經過轉換後其直方圖具有高斯(鐘形)分佈。 此處使用的值是 60% 的灰色均值,在該均值的任一側具有 60 sigma 的滾降。

  redist -s gaussian 60,60,60  zelda.png \
         zelda_gaussian.png

  magick zelda_gaussian.png -colorspace gray \
          histogram:zelda_gaussian_ghist.gif
[IM Output] ==> [IM Output]
[IM Output] ==> [IM Output]
從產生的灰度直方圖中,您可以看到圖像經過修改,使其顏色遵循高斯鐘形曲線類型的分佈。 對於照片,這會產生更「自然」的效果。 圖像不僅會進行對比度優化,還會調整亮度,因此圖像中的大多數像素都具有大約 60% 的灰度亮度。

直方圖重新分配方法

那麼這種直接直方圖調整是如何工作的呢? 基本上,它計算當前圖像的直方圖和所需分佈的直方圖。 然後,它計算出每個「bin」的灰度值需要如何更改,以便 bin 中的計數最符合所需的分佈。 一些 bin 可能會變暗,而另一些 bin 可能會變亮。 這實際上是一個相當複雜的過程,所以讓我們一步一步地來看看。
首先,我們需要從 ImageMagick 獲取實際的直方圖數據,而不是直方圖的圖形圖像。 請注意,數據來自所有顏色值,並組合成灰度。 這樣做是為了將所有通道一起分佈,並調整整體圖像亮度以遵循所需的曲線。

  magick zelda.png -colorspace gray \
         -depth 8 -format "%c" histogram:info:- |\
    tr -cs '0-9\012' ' ' |\
      awk '# collect the histogram data.
           { bin[$2] += $1; }
           END { for ( i=0; i<256; i++ ) {
                   print bin[i]+0;
                 }
               } ' > zelda_hist_data.txt

  # get the maximum count for any one histogram 'bin'
  max_count=`sort -n zelda_hist_data.txt | tail -n 1`

  # magick histogram into a profile graph of the data
  echo "P2 256 1 $max_count" | cat - zelda_hist_data.txt |\
    im_profile -s - zelda_hist_graph.gif
[IM Output] ==> [IM Output]
為了收集資料,我從直方圖圖像中提取「註釋」元數據,IM 正是為此目的而包含這些元數據。然後使用一個名為「tr」(「translate」(轉換)的縮寫)的程式清除數據,僅留下原始數字。然後將這些原始數據提供給另一個名為「awk」的實用程式,該程式用於收集每個 bin 的實際直方圖計數。為了讓我們能夠查看結果,我還將直方圖計數處理成漸變圖像(通過 NetPBM,PGM 文本灰度 圖像文件格式),並使用「im_profile」腳本將其顯示為折線圖。從本質上講,這只是生成直方圖圖像的另一種方式,儘管這次是直接從數值數據文件生成的。現在我們已經在文本文件中獲得了直方圖數據,我們還需要我們希望重新分配的數據匹配的函數的直方圖。在這種情況下,它是具有平均值 153(60% 灰色)和標準差 60 的高斯分佈。這兩個值都在直方圖「bin」的 256 範圍內。

  awk '# AWK to generate gaussian distribution graph
        BEGIN { mean = 153;   sigma = 60;
                fact = 1/(2*(sigma/256)^2);
                expo = exp(1);
                for ( i=0; i<256; i++ ) {
                  print int(65535*expo^(-(((i-mean)/256)^2)*fact));
                }
              }' /dev/null  > gaussian_hist_data.txt

   # magick gaussian data into a profile graph
   echo "P2 256 1 65535" | cat - gaussian_hist_data.txt |\
     im_profile -s -b - gaussian_hist_graph.gif
[IM Output]
上面的直方圖很有趣,反映了圖像的原始直方圖分佈和直方圖的期望狀態。但就轉換而言,這種形式的直方圖雖然便於我們理解,但對我們的目的而言並不太有用。實際上,我們真正需要的是累積直方圖。這些直方圖與普通直方圖非常相似,只是直方圖中的每個「bin」都是其「bin」加上之前所有「bin」的計數,從 0 開始。也就是說,每個「bin」都是所有較暗「bin」的「累積」或計數。這些實際上更容易直接從原始圖像生成。因此,讓我們重複該過程,但要計算和保存「累積」計數。

  magick zelda.png -colorspace gray \
         -depth 8 -format "%c" histogram:info:- |\
    tr -cs '0-9\012' ' ' |\
      awk '# Collect the cumulative histogram for an image
               { bin[$2] += $1; }
           END { for ( i=0; i<256; i++ ) {
                   cum += bin[i];
                   print cum;
                 }
               } ' > zelda_cumhist_data.txt

  total_count=`tail -n 1 zelda_cumhist_data.txt`
  echo "P2 256 1 $total_count" | cat - zelda_cumhist_data.txt |\
    im_profile -s - zelda_cumhist_graph.gif

  awk '# AWK to generate gaussian distribution cumulative graph
        BEGIN { mean = 153;   sigma = 60;
                fact = 1/(2*(sigma/256)^2);
                expo = exp(1);
                for ( i=0; i<256; i++ ) {
                  gas[i] = expo^(-(((i-mean)/256)^2)*fact);
                  total += gas[i]
                }
                for ( i=0; i<256; i++ ) {
                  cum += gas[i];
                  print int(65535*cum/total);
                }
              }' /dev/null  > gaussian_cumhist_data.txt

  total_count=`tail -n 1 gaussian_cumhist_data.txt`
  echo "P2 256 1 $total_count" | cat - gaussian_cumhist_data.txt |\
    im_profile -s -b - gaussian_cumhist_graph.gif
[IM Output]
圖像累積
直方圖
[IM Output]
高斯累積
直方圖
現在我們需要做的是將圖像的累積直方圖轉換為高斯累積直方圖。為此,輸入圖像中的每個灰度值都用於找到其「歸一化」累積值。然後將其映射到高斯分佈中的相同累積值,然後找到其對應的灰度值。此圖應使映射過程更清晰...
[diagram]
以下命令會查找每個可能的 8 位顏色值,以生成顏色查找表或 CLUT。然後可以使用此特殊圖像將原始圖像中的顏色值映射到重新分配圖像直方圖所需的新值。

  # Generate a CLUT to Redistribute the Histogram
  paste  zelda_cumhist_data.txt   gaussian_cumhist_data.txt |\
    awk '# AWK to generate gaussian distribution graph
              { bin[NR] = $1;   gas[NR] = $2;  }
          END { k=0;  # number of pixels less than this value
                print "P2 256 1 65535";
                for ( j=0; j<256; j++ ) {
                  while ( k<255 &&
                            gas[k]/gas[255] <= bin[j]/bin[255] ) {
                    k++;
                  }
                  print 65535*k/255;
                }
              }' |\
      magick pgm:- gaussian_clut.png

  magick zelda.png   gaussian_clut.png -clut   zelda_redist.png
[IM Output] ==> [IM Output]
[IM Output] ==> [IM Output]
如您所見,將圖像的直方圖轉換為嘗試遵循特定的分佈函數(例如高斯鐘形曲線)是一個相當複雜且高度數字化的過程。這裡是一個相當長且複雜的命令...

  magick zelda.png -colorspace gray \
         -depth 8 -format "%c" histogram:info:- |\
    tr -cs '0-9\012' ' ' |\
      awk '# AWK to generate gaussian distribution graph
            { # just read in image histogram into a 'bin' table
                  bin[$2] += $1;
                }
            END { # Generate Gaussian Histogram
                  mean = 153;   sigma = 60;
                  fact = 1/(2*(sigma/256)^2);
                  expo = exp(1);
                  for ( i=0; i<256; i++ ) {
                    gas[i] = expo^(-(((i-mean)/256)^2)*fact);
                  }
                  # Convert normal histograms to cumulative histograms
                  for ( i=0; i<256; i++ ) {
                    gas[i] += gas[i-1];
                    bin[i] += bin[i-1];
                  }
                 # Generate Redistributed Histogram
                 k=0;  # number of pixels less than this value
                 print "P2 256 1 65535";
                 for ( j=0; j<256; j++ ) {
                   while ( k<255 &&
                            gas[k]/gas[255] <= bin[j]/bin[255] ) {
                     k++;
                   }
                   print 65535*k/255;
                 }
                }' |\
        magick zelda.png   pgm:-  -clut   zelda_gaussian_redist.png
[IM Output] ==> [IM Output]
關於上述技術的最後幾句話。
  • 使用「awk」進行計算以加速 Fred Weinhaus 的「redist」腳本是由 Anthony Thyssen 建議和貢獻的。
  • 要應用上述重新分配技術來生成「均勻」或「均衡」分佈,函數直方圖只是一個常數。這反過來會導致積分分佈只是公式 y = x,或者只是一條對角直線。應用相同的轉換技術會產生一個 CLUT 圖像,該圖像與輸入圖像的累積直方圖相同。換句話說,對於直方圖的均衡化,您可以簡單地將圖像的累積直方圖轉換為 CLUT 並將其直接應用於圖像。
  • 大多數影像處理軟體包,包括目前的 ImageMagick,都是直接將轉換公式套用至影像本身的值,而不是產生中間的 CLUT。然而,由於直方圖和累積直方圖的大小有限(通常為 256 個「區間」),這可能會導致嚴重的錯誤,因為影像色彩值在處理過程中可能會被四捨五入。然而,使用 ImageMagick,我們會產生一個中間 CLUT(包含相同的四捨五入誤差),然後使用值的線性插值,透過準備好的 CLUT 對原始未四捨五入的影像值進行魔術處理。由於這種插值,新影像的色彩值會更加準確,因為它們在處理過程中沒有被四捨五入或「分箱」。
以上內容希望最終能整合到 ImageMagick 中。與此同時,Fred Weinhaus 的「redist」腳本可用於執行此任務。您可能也對 Fred 的「retinex」腳本感興趣,該腳本嘗試對影像的局部區域(而不是像此技術那樣在全局範圍內)進行類似的自動增強。

DIY 色階調整

數學線性直方圖調整

上述各種基本形式的 色階調整 以線性方式調整影像的色彩。這些變化也可以透過數學方式套用。例如,透過將影像乘以特定顏色,我們可以將所有純白色區域設定為該顏色。所以我們只需讀取影像,建立包含所需顏色的影像,然後使用 IM 自由格式「-fx」或 DIY 運算子 將原始影像與此顏色相乘。

  magick test.png  -size 1x1 xc:Yellow \
          -fx 'u*v.p{0,0}'    fx_linear_white.png
[IM Output] ==> [IM Output]
透過讓「-fx」從第二個「v」影像讀取顏色,可以輕鬆更改顏色,而無需將顏色轉換為 RGB 值以供數學運算使用。如果您使用的是「Gimp」和「Photoshop」等花哨的圖形影像處理軟體包,則上述操作將透過調整影像色彩直方圖的「曲線」套用至影像。 [IM 輸出] 例如,右側是由「gnuplot」生成的圖表(請參閱腳本「im_histogram」),顯示了三個 RGB 通道中只有一個通道發生的情況的數學公式。原始顏色(綠線)線性地重新映射為較深的顏色(紅線)。線性著色黑色也很簡單。例如,要將「黑色」線性映射為類似金色的顏色「rgb(204,153,51)」(同時保持「白色」為「白色」),則需要以下數學公式...
          result = 1-(1-color)*(1-intensity)
此公式會反轉顏色,將影像與所需的反轉顏色相乘,然後再次反轉影像。結果是灰階的黑色端被著色,而白色保持不變。

  magick test.png  -size 1x1 xc:'rgb(204,153,51)'  \
          -fx '1-(1-v.p{0,0})*(1-u)'   fx_linear_black.png
[IM Output] ==> [IM Output] ==> [IM Output]
上述內容也顯示了重新映射公式的「gnuplot」直方圖,供您參考。使用稍微複雜一點的公式,您可以用特定顏色線性替換灰階的「黑色」和「白色」端。

  magick test.png  -size 1x2  gradient:gold-firebrick \
          -fx 'v.p{0,0}*u+v.p{0,1}*(1-u)'   fx_linear_color.png
[IM Output] ==> [IM Output] ==> [IM Output]
上述的「-size 1x2 gradient:color1-color2」僅用於生成雙色像素影像,供「-fx」公式參考。第一種顏色替換白色,第二種顏色替換黑色,而所有其他顏色則在白色和黑色之間插值。與灰階運算子的典型情況一樣,每個 RGB 通道都被視為單獨的灰階通道,儘管每個通道的線性插值都不同。順便一提,這完全等同於 按顏色調整色階 運算子「+level-colors
然而,與「+level-colors」不同的是,使用的顏色當然可以來自任何圖像來源,而不僅僅是作為參數提供的顏色名稱。 然而,即使直接使用顏色名稱也是可能的。

  magick test.png   -fx "yellow*u+green*(1-u)"  fx_linear.png
[IM Output]

數學非線性直方圖調整

雖然線性顏色調整很重要,並且可以使用更快的方法,但在許多情況下,線性「色階」調整並不是我們想要的,這就是「-fxDIY 運算子變得更有用的地方。 線性調整的另一種公式是「-fx 'v.p{0,1}+(v.p{0,0}-v.p{0,1})*u'」,它的優點是可以將「u」替換為單個隨機函數「f(u)」來產生非線性顏色變化。 這讓您可以做更多有趣的事情。 例如,如果在上一個示例中,您想將所有顏色推向「黑色」側,從而使圖像變成更「磚紅色」的顏色。

  magick test.png -size 1x2  gradient:gold-firebrick \
          -fx 'v.p{0,1}+(v.p{0,0}-v.p{0,1})*u^4'  fx_non-linear.png
[IM Output] ==> [IM Output] ==> [IM Output]
在一個更實際的例子中,Adelmo Gomes 需要為他正在開發的自動化 天氣圖重新著色 腳本進行顏色調整。 在這種情況下,他想將圖像的純黑色部分著色為 0.25 藍色,但保留其餘的灰階,尤其是圖像的白色和中間調灰色。 只有藍色需要進行這樣的調整,他目前是在圖像編輯器中手動完成的。 例如,您可以使用「u^2」這樣的二次公式將直方圖的黑色端著色為「.25」藍色。 只需要修改藍色通道,因此該值直接插入公式中。

  magick test.png  -channel B  -fx '.25+(1-.25)*u^2'  fx_quadratic.png
[IM Output] ==> [IM Output] ==> [IM Output]
然而,雖然這產生了合理的結果,但它確實稍微使中間調的灰色變暗,產生了一種病態的灰黃色。 為了避免這種情況,可以使用「指數」函數來更好地控制著色過程。

  magick test.png  -channel B  -fx '.3*exp(-u*4.9)+u'  fx_expotential.png
[IM Output] ==> [IM Output] ==> [IM Output]
同樣,圖表顯示了藍色通道是如何被修改以賦予黑色獨特的深藍色調的。 第二個值(「4.9」)是回到線性「+u」圖的衰減。 該值越小,衰減越慢,調整越線性。 該值越大,「衰減」越劇烈。 可能需要針對不同的顏色值調整該值,因此這不是通用的黑色著色通用公式,但非常適合為天氣圖著色。 一般來說,如果您可以用數學方式表達您想要的顏色調整,那麼您可以使用「-fx」運算符來獲得您想要的結果。

「曲線」調整

[diagram] 通常在圖形照片編輯器中,您會看到一個直方圖「曲線」圖表,就像我左邊顯示的那樣。 然後,用戶可以通過移動四個(或更多)控制點來編輯「曲線」,直方圖調整函數將遵循這些點。 控制點通常指定第一個灰度級在調整後變為第二個灰度級。 因此,像 0.0,0.2 這樣的點基本上意味著 0% 的灰色(黑色)在調整後應該是 20% 的灰度級。 現在 IM 不允許您直接指定「控制點」來生成「曲線」調整,它想要的是生成的「曲線」的數學公式。 幸運的是,有些程序可以從控制點生成該曲線公式,包括「gnuplot」、「fudgit」、「mathematica」和「matlab」,以及更多數學軟件包。 以下是一種可以使用「gnuplot」從四個控制點生成公式的方法,它是一個標準的額外軟件包,您可以安裝在大多数 Linux 發行版以及 Windows 上。

  ( echo "0.0 0.2";  echo "1.0 0.9"; \
    echo "0.2 0.8";  echo "0.7 0.5"; )   > fx_control.txt

  ( echo 'f(x) = a*x**3 + b*x**2 + c*x + d'; \
    echo 'fit f(x) "fx_control.txt" via a, b, c, d'; \
    echo 'print a,"*u^3 + ",b,"*u^2 + ",c,"*u + ",d'; \
  ) | gnuplot 2>&1 | tail -1             > fx_funct.txt
[Data]
控制點
==> [Gnuplot]
[Gnuplot]
Gnuplot 擬合的 FX 函數
請注意,曲線擬合所需的參數數量(以上示例中的「a」到「d」)必須與您提供的控制點數量相等。因此,如果您需要五個控制點,則需要在函數中加入另一個「e」項。

如果您的直方圖曲線通過固定控制點 0,01,1,則實際上只需要兩個參數,因為「d」將等於「0」,而「c」將等於「1-a-b」。

StackOverflow: 在 Windows 上使用 Gnuplot 繪製 IM 曲線 上發布了一份更詳細的使用指南,專門針對 Windows 用戶,但 Linux 用戶也可以使用。如您從上面額外的「gnuplot」生成圖像中所見,生成的函數完美地擬合了控制點。此外,由於它生成了「-fx」樣式的公式,因此它可以按原樣用作 IM 參數。
舉例來說……

  magick test.png    -fx "`cat fx_funct.txt`"     fx_funct_curve.png
[IM Output]
為了讓使用者更容易將魔法控制點轉換為直方圖調整函數,我建立了一個名為「im_fx_curves」的 shell 腳本,用於呼叫「gnuplot」並輸出給定控制點的更美觀的多項式方程式。Gabe Schaffer 也提供了一個 Perl 版本(使用下載的「Math::Polynomial」函式庫模組),稱為「im_fx_curves.pl」,用於執行相同的操作。可以使用任一腳本。例如,以下是具有 5 個控制點的不同曲線……

    im_fx_curves  0,0.2  0.3,0.7  0.6,0.5  0.8,0.8  1,0.6  > fx_curve.txt
[Gnuplot] ==>
[Gnuplot]
但是,FX 函數的速度非常慢。但從 IM 6.4.8-9 開始,您現在可以直接將擬合多項式表達式的已發現係數直接傳遞到 多項式函數方法 中。您可以使用帶有特殊「-c」選項的「im_fx_curves」生成以逗號分隔的係數列表……

    im_fx_curves -c  0,0.2  0.3,0.7  0.6,0.5  0.8,0.8  1,0.6  > coefficients.txt
[Gnuplot] ==>
[Gnuplot]
舉例來說,讓我們將這些曲線應用於我們的測試圖像……

  magick test.png  -function Polynomial `cat coefficients.txt`  test_curves.png
[IM Output]
在進階的 「Aqua」效果 示例中,更詳細地介紹了此方法的更實際示例。在 IM 論壇討論區 任意色調再現曲線 中,探討了生成「曲線」的另一種方法。

為圖像著色

均勻著色圖像

通常,通過將圖像與某種顏色按一定量混合來實現為圖像著色。這可以使用 評估運算符混合圖像 技術來完成,但這些技術使用起來並不簡單。幸運的是,我們可以使用「-colorize」圖像運算符,將均勻顏色混合到圖像中,這是一種更簡單的方法。此運算符將當前的「-fill」顏色混合到當前圖像序列中的所有圖像中。原始圖像的 Alpha 通道將被保留,只有顏色通道會被修改。例如,要使圖像(灰度或其他)變亮,我們使用「-colorize」將一定量的白色混合到圖像中,使其變亮而不會完全飽和圖像。

  magick test.png  -fill white -colorize 50%  colorize_lighten.png
[IM Output] ==> [IM Output]
同樣,我們可以使用「黑色」填充顏色使圖像變暗。

  magick test.png  -fill black -colorize 50%  colorize_darken.png
[IM Output] ==> [IM Output]
要將圖像的兩端朝中間色調變灰,您可以使用特定的灰色填充顏色。顏色「gray50」是 RGB 色彩光譜中的確切中間顏色。

  magick test.png  -fill gray50 -colorize 40%  colorize_grayer.png
[IM Output] ==> [IM Output]
這也經常被用作「去對比度」的方法,例如 反向級別調整運算符 所提供的方法,儘管控制較少。「-colorize」運算符還允許您分別為三個顏色通道指定溶解百分比。這對於以特殊方式線性變暗(或變亮)圖像非常有用。
在 IM v6.7.9 版本之前,「-colorize」運算子並不會修改 Alpha 色板。從該版本開始,如您在上方所見,它現在會統一調整所有像素的色彩,包括完全透明的像素。
-colorize」運算子的一種常見用途是簡單地替換現有影像中的所有顏色(著色「100%」),但保留影像的透明度(Alpha)形狀,以便產生彩色遮罩。但是,從 IM v6.7.9 版本開始,您需要透過停用 Alpha 色板來保護它免受此運算子的影響,然後再重新啟用 Alpha 色板。(如需詳細資訊,請參閱開啟 Alpha)。例如...

  magick test.png -alpha off \
          -fill blue -colorize 100% \
          -alpha on  colorize_shape.png
[IM Output]
如果沒有這種保護,colorize 會將畫布完全填滿指定的顏色...

  magick test.png -fill blue -colorize 100% colorize_blank.png
[IM Output]
但是,如果有可能使用 IM v6.7.9 之前的 IM 版本,我建議您在上述內容中加入「-alpha opaque」或「-alpha off」操作,以確保產生的影像是您預期的完全空白影像。請注意,您可以使用依顏色調整色階運算子,以單一顏色(而非顏色範圍)更快地清空畫布。另請參閱空白畫布

中間色調色彩著色

雖然Colorize 運算子會套用「-fill」顏色來線性地調整影像中所有顏色的色彩,但「-tint」運算子套用「-fill」顏色的方式,只會調整影像中間調顏色的色彩。此運算子是一個灰階運算子,顏色會根據指定的百分比(0 到 200)進行調整或增強。為了限制其效果,它也會使用數學公式進行調整,使其不會影響黑色和白色,而是對每個顏色通道的中間調顏色產生最大的影響。「-tint 100」基本上會調整完美的灰色,使其變成填充顏色強度的一半。較低的值會將其調整為較深的顏色,而較高的值會將其調整為與該顏色完全匹配。

  magick test.png  -fill red  -tint 40 tint_red.png
[IM Output] ==> [IM Output]
測試影像中的綠色不是真正的 RGB 綠色,而是縮放向量圖形「green」,其亮度只有真正綠色的一半。因此,它也是一種中間調顏色,因此會受到「-tint」運算子的影響,變得更暗,這與測試影像中的紅色和藍色色點不同。此外,您也可以使用以逗號分隔的百分比清單來調整個別顏色分量的色彩。例如「-tint 30,40,20,10」。但是,這可能難以使用,而且可能需要一些實驗才能正確設定。最好指定您想要的顏色,以獲得完美的 50% 灰色。
[IM 輸出]-tint」運算子的運作方式是以某種方式取得指定的顏色和百分比,然後根據「-fill」顏色的強度,根據以下公式調整影像中的個別顏色。(請參閱右側圖表)

f(x)=(1-(4.0*((x-0.5)*(x-0.5))))
一個二次函數,其結果用作影像中現有顏色的向量。如您所見,它會完全替換純粹中間灰色的顏色,而不會調整白色或黑色。

或者,您可以使用較低階的運算子來自行完成這類操作,請參閱FX 運算子,以及評估和函數運算子

色調運算子非常適合用於調整「-shade」輸出結果(請參閱陰影疊加高光圖像),例如3D 子彈圖像中的範例。您也可以使用「-tint」來增亮或變暗圖像的中间色調顏色。這有點像圖像的「伽瑪調整」,但又不完全相同。例如,將色調值大於 100 與「白色」顏色一起使用將會增亮中間色調。

  magick test.png  -fill white  -tint 130 tint_lighter.png
[IM Output] ==> [IM Output]
而值小於 100 則會使顏色變暗。

  magick test.png  -fill white  -tint 70 tint_darker.png
[IM Output] ==> [IM Output]
目前,純中間色調灰色不會映射到「-fill」顏色。

百分比參數不是「混合百分比」,而更像是「亮度百分比」。例如,它完全不適用於「黑色」填充顏色。

我不知道為什麼會這樣設計,也不知道它背後的故事。然而,它確實使得在為灰度圖像著色時,難以精確控制最終顏色。

使用下方疊加合成著色將提供更精確(儘管非常線性,而不是拋物線)的中間色調灰色著色。

深褐色調著色

一種特殊的攝影重新著色技術「-sepia-tone」基本上是將圖像轉換為灰度,並將所有中間色調著色為特殊的棕色。

  magick rose:  -sepia-tone 65%     sepia-tone.jpg
[IM Output]
給定的參數是要最接近棕褐色(類似於「Goldenrod」顏色)的灰度「中間點」。這最常見的用途是產生雙色調效果,以便產生「復古」照片(請參閱維基百科上的棕褐色調)。例如,這裡我使用各種顏色對對比度增強的灰度玫瑰圖像進行著色,以達到類似棕褐色的效果。您應該根據要查找的確切效果使用哪種顏色。

  magick rose: -colorspace gray -sigmoidal-contrast 10,40%  rose_grey.jpg
  for color in      goldenrod  gold  khaki  wheat
  do
    magick rose_grey.jpg  -fill $color   -tint 100    sepia_$color.jpg
  done
[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output]
我發現將棕褐色圖像與原始圖像混合或混合,以減少其效果,也可以產生更好的「褪色」效果。

  magick rose: \( +clone -sepia-tone 60% \) -evaluate-sequence mean  sepia-tone_blended.jpg
[IM Output]
另請參閱Hald 顏色查找表,瞭解如何保存更複雜的顏色變化的方法,例如上面的最後一個範例。

雙色調效果

「雙色調」是一種印刷方法,您可以在其中將圖像的灰度(黑色墨水)與其他顏色混合,以在有限的預算或印刷設備下產生更好的效果。例如,您今天看到的所有老照片都帶有棕褐色的原因是,棕褐色墨水倖存下來,沒有隨著時間的推移而變質或褪色。其他「黑白」圖像格式已褪色至無法使用。請參閱上面的棕褐色運算子。另一種稱為「藍晒法」(俗稱「藍圖」)的雙色調技術被廣泛用作大規模複製原始黑白建築圖紙的方法。請記住,這種技術在雷射和影印(以及 Xerox)發明之前就已經使用了。有關更多資訊,請參閱維基百科上的雙色調條目,以及假雙色調與真雙色調。然而,上面的色調運算子會產生合理的雙色調效果,就像它對上面的棕褐色效果一樣。

  magick rose: -colorspace gray -sigmoidal-contrast 10,40%  rose_grey.jpg
  for color in      blue  darkcyan  goldenrod  firebrick
  do
    magick rose_grey.jpg   -fill $color   -tint 100    duotone_$color.jpg
  done
[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output]
請注意,我通常會選擇「雙色調」顏色中較暗的版本,但您也可以使用色調運算器 的參數來調整它。您也可以使用S 形對比運算器 的參數來調整亮度和對比度。另一種從三種顏色(黑點、中點和白點顏色)生成雙色調的更精確方法是使用顏色查找表(見下文)。以下是一個快速範例,其中我使用顏色 'Black'、'Chocolate' 和 'LemonChiffon' 為雙色調創建了一個非常不尋常的雙色調。是的,黑點顏色通常保持黑色,這就是為什麼它通常被稱為 *雙* 色調。

  magick -size 1x1 xc:Black xc:Chocolate xc:LemonChiffon \
                                   +append     duotone_clut.gif
  magick -size 20x256 gradient: -rotate 90   duotone_clut.gif \
          -interpolate Bicubic -clut       duotone_gradient.gif
  magick rose_grey.jpg   duotone_clut.gif \
          -interpolate Bicubic -clut       rose_duotone.jpg
[IM Output] ==> [IM Output]
[IM Output] ==> [IM Output] ==> [IM Output]
上述方法的優點是可以精確控制中點顏色(與不精確的色調 不同)。您也可以直接使用您喜歡的任何三種顏色,就像上面的例子一樣,或者使用顏色的擴展漸變來更精細地控制三個(或更多)控制點之間的顏色。該技術還為您提供了一種非常緊湊的方式來存儲特定的雙色調效果,以便重複和將來使用。另請參閱Hald 顏色查找表,了解保存顏色變化的更複雜方法,這些方法超越了對灰度圖像進行著色。

色彩著色,自訂

-tint」的最大問題之一是它是一個灰度(或向量)運算器。也就是說,它完全獨立地處理紅色、綠色和藍色通道中的每一個。反過來,這意味著「-tint」不會影響「blue」或「yellow」等主要和次要顏色,即使所有灰度級別都會受到影響。但是,由於各種通道數學變換,例如FX 運算器和更快的評估和函數運算器,您可以生成自己的顏色疊加來修改圖像。也就是說,以類似於著色運算器的方式為圖像著色。例如,在這裡,我將圖像的灰度亮度級別設置為所需特定顏色的半透明疊加層。

  magick test.png  \( +clone -colorspace gray \
               -function polynomial -4,4,0 -background Gold -alpha shape \) \
          -composite   tint_diy_compose.png
[IM Output]
警告,這不會正確保留圖像透明度,但它適用於完全不透明的圖像。請注意,與色調不同,可以使用任何顏色,包括「black」,因為顏色不被視為向量加法,而是一種 alpha 合成。結果與您對普通色調的結果不太一樣。

色彩著色疊加

特殊的Alpha 合成方法「疊加」和「強光」實際上是在設計時考慮到顏色(和圖案)著色的。這些合成方法還將替換中間調灰色,使圖像中的黑色和白色高光保持不變。
例如,在這裡,我快速生成了一個彩色疊加圖像,並將其合成以對原始圖像進行著色。

  magick test.png \( +clone -alpha off -fill gold -colorize 100% \) \
          -compose overlay -composite  tint_overlay.png
[IM Output]
如您所見,alpha 合成不會保留原始圖像的任何透明度,因此需要使用第二個 alpha 合成操作來解決此問題。

  magick test.png \
          \( +clone -alpha off -fill gold -colorize 100% \
             +clone +swap -compose overlay -composite \) \
          -compose SrcIn -composite  tint_overlay_fixed.png
[IM Output]
使用「疊加」是一種比上面使用的二次函數更線性的著色形式,並且像「-tint」一樣,它分別應用於圖像的每個通道,這樣主要和次要顏色也保持不變。此外,此 alpha 合成方法不提供調整控制,因此,如果要控制著色級別,則需要在應用著色之前調整疊加圖像透明度。當然,與我目前展示的其他著色方法不同,您不僅限於為單一顏色著色,還可以 使用圖像或平鋪圖案應用著色。

  magick test.png \
          \( -size 150x100 tile:tile_disks.jpg \
             +clone +swap -compose overlay -composite \) \
          -compose SrcIn -composite  tint_overlay_pattern.png
[IM Output]
然而,這已經超出了基本顏色處理的範圍,因此我將不再贅述圖像著色。
Alpha 合成方法「HardLight」會產生與「Overlay」相同的結果,但來源圖像和目標圖像會交換。

這可以用在最近幾個範例中,以取代「+swap」。

全域色彩調整

調整亮度、飽和度和色相

-modulate」運算子的特殊之處在於它會在特殊的 HSL(色相、飽和度、亮度)色彩空間 中修改圖像。它會將每個彩色像素轉換到這個色彩空間中,修改它,然後再將其轉換回原始色彩空間。它需要三個值(儘管後面的值是可選的)作為百分比,這樣 100 不會對圖像進行任何更改。舉例來說:

  magick rose: -modulate 100,100,100  mod_noop.gif
[IM Output]
第一個值,*亮度* 是圖像整體亮度的乘數。

  magick rose:  -modulate 0     mod_bright_0.gif
  magick rose:  -modulate 50    mod_bright_50.gif
  magick rose:  -modulate 80    mod_bright_80.gif
  magick rose:  -modulate 100   mod_bright_100.gif
  magick rose:  -modulate 150   mod_bright_150.gif
  magick rose:  -modulate 200   mod_bright_200.gif
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
請注意,雖然亮度參數為「0」會產生純黑色圖像,但您無法僅使用此運算子產生純白色圖像。第二個值 *飽和度* 也是一個乘數,用於調整圖像中存在的整體色彩量。

  magick rose:  -modulate 100,0     mod_sat_0.gif
  magick rose:  -modulate 100,20    mod_sat_20.gif
  magick rose:  -modulate 100,70    mod_sat_70.gif
  magick rose:  -modulate 100,100   mod_sat_100.gif
  magick rose:  -modulate 100,150   mod_sat_150.gif
  magick rose:  -modulate 100,200   mod_sat_200.gif
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
飽和度為「0」會產生灰階圖像,如上面的將色彩轉換為灰階 中所示。然而,灰色會根據 HSL 色彩空間的定義,平均混合三個色彩通道,因此不會產生真正的「強度」灰階。基本上,較小的值會產生更多「柔和」的色彩,而大於「100」的值會產生更多卡通般的鮮豔圖像。請注意,由於 *亮度* 和 *飽和度* 是百分比乘數,因此您需要乘以一個非常大的數字才能將幾乎所有圖像色彩值更改為接近最大值。也就是說,您需要使用接近一百萬的 *亮度* 因數,才能使除純黑色以外的所有色彩都變成白色。

色相調整

最後一個值,*色相*,實際上更有用。它以循環的方式旋轉圖像的色彩。為了實現這一點,給定的 *色相* 值會產生「模數加法」,而不是乘法。但是請注意,色相是使用百分比旋轉的,而不是使用角度旋轉的。這看起來可能很奇怪,但「-modulate」一直都是這樣。角度和 modulate 參數之間的轉換公式為:
色相角度 = ( modulate_arg - 100 ) * 180/100
modulate_arg = ( 色相角度 * 100/180 ) + 100
這意味著「100」(對於所有三個參數)不會產生任何變化。而值「0」或「200」會有效地反轉圖像中的色彩(但不會反轉亮度)。舉例來說:

  magick rose:  -modulate 100,100,0      mod_hue_0.gif
  magick rose:  -modulate 100,100,33.3   mod_hue_33.gif
  magick rose:  -modulate 100,100,66.6   mod_hue_66.gif
  magick rose:  -modulate 100,100,100    mod_hue_100.gif
  magick rose:  -modulate 100,100,133.3  mod_hue_133.gif
  magick rose:  -modulate 100,100,166.6  mod_hue_166.gif
  magick rose:  -modulate 100,100,200    mod_hue_200.gif
[IM Output]
0
(紅色 <-> 青色)
[IM Output]
33.3
(紅色 -> 藍色)
[IM Output]
66.6
[IM Output]
100%
無操作
[IM Output]
133.3
[IM Output]
166.6
(紅色 -> 綠色)
[IM Output]
200
(與 0 相同)
如您所見,值「33.3」會產生所有色彩的負向或逆時針旋轉約 60 度,有效地將紅色映射到藍色,藍色映射到綠色,綠色映射到紅色。使用值「0」或「200」會產生色彩的完整 180 度反轉,而不會反轉圖像的亮度。請注意,色相是循環的,因此使用值「300」會產生 360 度的色彩旋轉,並且不會導致圖像發生變化。有關使用「色相調整」修改圖像色彩的範例,請參閱色度鍵遮罩地圖中的圖釘
這些類型的操作以及更多操作,也可以使用進階的 色彩空間 技術來應用,例如在 重新著色矩陣運算器(如下)中使用,但對於圖像的基本「調節」來說,此運算器大大簡化了事情。對於主要顏色交換,可以使用 重新著色矩陣運算器 或通道交換(請參閱 分離/組合運算器),這可能是更準確的技術。雖然它的功能少很多。另請參閱 Hald 色彩查詢表,了解如何儲存色彩變化(尤其是色相變化)以供稍後重複使用的方法。

自訂調整

如果您真的想「自己動手做」,您可以做到。您基本上是將圖像變更到適當的色彩空間,修改值,然後再變更回來。請記住,在 HSL 色彩空間 中,綠色通道保存飽和度值,而藍色通道保存亮度值。例如,以下是使用預設 HSL 色彩空間時,相當於「-modulate 80,120」(稍微變暗,增加色彩飽和度)的操作...

  magick rose: -colorspace HSL \
          -channel B -evaluate multiply 0.80 \
          -channel G -evaluate multiply 1.20 \
          +channel -colorspace sRGB   modulate_channel.png
[IM Output] ==> [IM Output]
當然,如果您使用這種方法修改色相(紅色通道),您需要確保最終值「環繞」(模數),而不是簡單地在最大值或最小值處裁剪值(兩者都是「紅色」色相)。因此,對於色相修改,直接使用 調節運算器 可能更容易。

在其他色彩空間中調整

-modulate」 的最大問題是在處理包含許多「接近白色」的圖像時。由於它在 HSL 色彩空間中進行工作,因此當亮度降低時,偏白色的顏色將變得更加「飽和」。您可以在上面玫瑰圖像的白色葉子中看到這一點,它在變暗 50% 時顯示出許多色彩偽影。這在處理 JPEG 圖像格式時尤其是一個問題,因為由於其有損壓縮算法,它往往會產生偏白的顏色(實際上,JPEG 中的所有顏色通常都略微偏離)。例如...

  magick wedding_party_sm.jpg  -modulate 85  modulate_off-white.png
[IM Output] ==> [IM Output]
這裡的問題是,在 HSL 中,所有偏白的顏色都被打包到所用色彩空間的一個小的「白點」區域(一個雙錐體)。然後,當亮度降低時,隨著顏色錐體的擴展,偏白的顏色會擴展,導致偏白的顏色產生一組更多彩(飽和)的偏白顏色。也就是說,顏色的微小變化被誇大了。解決方案是在 HSB 色彩空間中「-modulate」,而不是 HSL 色彩空間。
HSB 中的「B」表示亮度,但通常也稱為 HSV,使用「V」表示值。它們是相同的色彩空間,但「V」是一個令人困惑的術語,因為值通常表示「一個存儲的數字」。

還有一個 HSI 色彩空間(使用「I」表示強度),但它並不常見,並且由於添加了 HCL(其中「L」表示亮度)循環色彩空間(見下文)而不需要它。

在 HSB 色彩空間中,「白色」不是單個點,而是一個大的「圓盤」,因此偏白色彼此並不「接近」。因此,當您降低亮度時,偏白色會均勻收縮,從而減少任何輕微的顏色變化,而不是擴展它們。因此,白色只會變成灰色,而不是更多彩。要調節 HSB 色彩空間 中的圖像,您可以使用該色彩空間中的 DIY 技術(見上文)。或者,對於 IM v6.5.3-7 及更高版本,您可以使用「色相」色彩空間之一 定義「modulate:colorspace」的操作控制

  magick wedding_party_sm.jpg \
          -define modulate:colorspace=HSB -modulate 85 \
          modulate_HSB.png
[IM Output]
其他「色相」色彩空間有 HWB 和 HCL(請參閱下一節)。當然,如果您將圖像縮小到這麼小的尺寸,更好的解決方案是不要將圖像保存為 JPEG 格式,因為這是導致灰白色值的原因。更好的做法是在完成之前根本不要保存圖像,這樣您就可以在最佳的內存 品質 設置下保留所有顏色值。HSB 色彩空間未被默認為調節使用的預設原因是,如果您在此色彩空間中增亮圖像,則顏色會變得更加飽和和大膽,而不是圖像變得更加明亮和潔白。例如,這裡是以預設 HSL 和指定的 HSB 色彩空間對「玫瑰」圖像進行 150% 增亮的比較。

  magick rose:         -modulate 150        mod_bright_HSL.gif
  magick rose: -define modulate:colorspace=HSB \
                         -modulate 150        mod_bright_HSB.gif
[IM Output]
HSL
[IM Output]
HSB
在 IM v6.4.0-10 之前,「-modulate」運算符實際上使用的是 HSB 色彩空間而不是 HSL 色彩空間。這是因為一位用戶報告了上述情況的錯誤而更改的。

重點是,對於某些圖像,如果您使用 HSL,您會很頭疼,而對於其他圖像,如果您使用 HSB 色彩空間,您也會很頭疼。這取決於您要執行的操作!

在 LCHab 和其他色彩空間中進行調節

色相調節(在 HSL 或 HSB 色彩空間中)實際上被認為是相當粗糙的。這些色彩空間沒有考慮到更逼真的顏色強度。因此,在「藍色」和「黃色」色相之間旋轉也會產生非常大的亮度變化。請參閱 維基百科:HSL 色彩空間的缺點。一種替代方法是執行 Grafica Obscura 的「矩陣運算」論文中所述的亮度保持旋轉。這很複雜,因為顏色修改是作為運算的一部分完成的,作為單個計算的矩陣運算,該運算會根據所需的旋轉量而有所不同。從 IM v6.8.4-7 開始,調節運算符 還可以處理特殊的色彩空間「LCHab」和「LCHuv」,它們是各自「Luv」和「Lab」色彩空間的圓柱(色相-色度)形式。有關更多信息,請參閱 維基百科,圓柱 LUV 或 LCHuv 色彩空間HCL 色彩空間
LCHab」和「LCHuv」色彩空間的等效通道與「HCL」和「HCB」色彩空間的等效通道相反。也就是說,「灰度」強度等效值在圖像的第一個(「紅色」)通道中,而色相在第三個(「藍色」)通道中。
例如,我們使用「LCHab」色彩空間對紅玫瑰進行一些色相旋轉。將這些與前面一組「HSL」色彩空間的結果進行比較。

  for i in   0 25 50 75 100 125 150 175;  do
    magick rose: -define modulate:colorspace=LCHab \
                            -modulate 100,100,$i     mod_lch_$i.gif
  done
[IM Output]
0% & 200%
[IM Output]
25%
(紅色->藍色)
[IM Output]
50%
[IM Output]
75%
[IM Output]
100%
無操作
[IM Output]
125%
[IM Output]
150%
[IM Output]
175%
請注意,色相的分佈與更傳統的色相色彩空間不同。但更重要的是,原始圖像的強度得以保留。因此,您永遠不會從純原色/二次色循環到另一種純原色/二次色,因為它們都沒有相同的強度。然而,色相上的顏色漸變更加平滑,在原色和二次色處的「峰值」不那麼尖銳。以下是「LCHab」與普通「HSL」色彩空間(使用適當的旋轉百分比)的紅色到藍色的簡單色相旋轉比較。
[IM Output]
原始圖像
[IM Output]
LCHab
25%
[IM Output]
HSL/HSB
33.3%
請注意藍色如何不像那麼暗,而是一種更接近原始圖像色調的色調。有關 HCL 色彩空間色相的更多信息,請參閱 LCH 色輪 上的示例。
在 IM v6.8.4-7 之前的版本中,您會使用 'HCL' 色彩空間(IM v6.7.9-1 版本引入)。這個色彩空間與 'LCHuv' 完全相同,只是通道順序相反(色相存儲在圖像的紅色通道中,這只是該色彩空間的定義方式)。這意味著您還必須交換各個通道的位置,以便讓 調製運算符 正常工作。

'LCHab' 和 'LCHuv' 色彩空間的通道順序與 'HSL' 相同,以便讓調製功能正常工作,並直接在色彩空間上運作,而無需重新排列通道。

請注意,對於非常暗的顏色,'LCHuv'可能會產生不連續的顏色值。然而,這不應該發生在真實圖像中,只會發生在直接在圓柱空間中生成的圖像中。

色彩矩陣運算子

"-color-matrix" 運算符將使用矩陣技術對圖像進行重新著色。也就是說,您需要為其提供一個值矩陣,該矩陣表示如何線性混合圖像的各種顏色通道值以產生新的顏色值。典型的用法是為運算符提供 9 個值,這些值形成三個函數(行)或三個乘數(列)。因此,前三個數字是紅色通道的顏色公式,接下來是綠色通道,依此類推。例如...

  magick rose: -color-matrix ' 1 0 0
                                0 1 0
                                0 0 1 '   matrix_noop.png
[IM Output]
等同於應用以下方程式...
紅色' = 1 * 紅色 + 0 * 綠色 + 0 * 藍色
綠色' = 0 * 紅色 + 1 * 綠色 + 0 * 藍色
藍色' = 0 * 紅色 + 0 * 綠色 + 1 * 藍色
在這種特殊情況下,圖像不會發生任何變化。該矩陣形成一個特殊的陣列,稱為「單位矩陣」。通過混合行,您可以交換各個通道的位置。例如,在這裡我交換了紅色和藍色通道的值。

  magick rose: -color-matrix ' 0 0 1
                                0 1 0
                                1 0 0 '  matrix_red_blue_swap.png
[IM Output]
或者簡單地將紅色通道複製到其他兩個通道,以提取或分離「紅色通道」(另見分離通道圖像)...

  magick rose: -color-matrix ' 1 0 0
                                1 0 0
                                1 0 0 '  matrix_red_channel.png
[IM Output]
或者使用 2/5/3 灰階比例將圖像轉換為灰階圖像(請參閱將顏色轉換為灰階)...

  magick rose: -color-matrix ' .2 .5 .3
                                .2 .5 .3
                                .2 .5 .3 '  matrix_grayscale.png
[IM Output]

您可以使用更大的矩陣,最多可達 6 行 6 列。這些對應於通道:「紅色」、「綠色」、「藍色」、「黑色」(如果已設定)、「Alpha」(如果已設定)和一個常數。請注意,「黑色」和「Alpha」通道必須在矩陣大小足夠時提供,即使該值本身可能不存在或未使用。最後一個常數列只是對公式的簡單加法(如果為負數則為減法)。第六行(如果已給出)將被忽略,並且不使用。默認情況下,「矩陣」定義遵循與用戶定義形態學/卷積核相同的結構,並且如果未指定大小幾何形狀,則將其視為「方形」核。目前不使用內核的偏移量。然後將給定的「值數組」覆蓋在更大的「6x6 單位矩陣」(對角線為 1)上,然後應用於圖像。這種內部處理方式意味著您實際上可以僅通過幾行數字來簡化矩陣值,而不是全部數字。當您需要在顏色計算中包含「常數」,或者只想修改一個通道時,這一點尤其有用。例如,反轉(否定)圖像。

  magick rose: -color-matrix '6x3: -1  0  0 0 0 1
                                     0 -1  0 0 0 1
                                     0  0 -1 0 0 1'  matrix_negate.png
[IM Output]
將所有紅色通道值設定為最大值(使用「常數」)...

  magick rose: -color-matrix '6x1: 0,0,0,0,0,1'  matrix_red_max.png
[IM Output]
由於覆蓋在單位矩陣上,其他通道值不受影響,儘管它們在內部仍然會重新計算。
在 IM v6.6.1-0 之前的版本中,"-color-matrix" 被命名為 "-recolor"。

顏色矩陣範例

深褐色,或者至少是該操作的線性形式

  magick rose: -color-matrix ' 0.393 0.769 0.189
                                0.349 0.686 0.168
                                0.272 0.534 0.131  ' matrix_sepia.png
[IM Output]
鮮豔的色彩,採用一種稱為數位維也納的技術...

  magick rose: -color-matrix '  1.2 -0.1 -0.1
                                -0.1  1.2 -0.1
                                -0.1 -0.1  1.2 ' matrix_vivid.png
[IM Output]
此矩陣會增亮每個顏色通道,同時減去其他通道的顏色,使 RGB 圖像中的顏色更加鮮豔。這與使用 調整 將圖像色彩飽和度提高 20% 不完全相同,但與之類似。 寶麗來色彩...

  magick rose: -color-matrix \
            '6x3:  1.438 -0.122 -0.016  0 0 -0.03
                  -0.062  1.378 -0.016  0 0  0.05
                  -0.062 -0.122 1.483   0 0 -0.02 ' matrix_polaroid.png
[IM Output]
未來:使用顏色矩陣進行色相旋轉...
Grafica Obscura 網頁上所述。
有關使用顏色矩陣的更多信息,請參閱...但是請注意,這些實現大多數都使用矩陣的 對角轉置 形式,其中列形成方程式,而不是行。或者涉及更少的通道(更少的行/列數)。

太陽化著色

對圖像進行“-solarize”基本上是將最亮的顏色“燒錄”成黑色。顏色越亮,曝光後的顏色就越暗。當化學膠片過度曝光時,攝影中就會發生這種情況。

  magick rose:  -solarize 90%     solarize.jpg
[IM Output]
基本上,高於給定灰度級的任何內容都會被反轉。因此,如果您給出“0%”的參數,您基本上就有一個簡陋的 反轉運算符。例如,這裡是一個使用“-fx”數學公式偽造的“-solarize”。

  magick rose:  -fx  '.9>u ? u : 1-u'     solarize_fx.jpg
[IM Output]
此運算符特別適合從圖像中提取中間調灰色。例如,在這裡我使用非常強的 S 形對比度 操作在 70% 灰色處產生一種“模糊”閾值。然後我對結果進行 曝光 以生成模糊尖峰而不是模糊閾值。最後的電平調整將尖峰提升到最大亮度以產生“燈絲”效果。

  magick -size 10x300 gradient: -rotate 90 \
                         -sigmoidal-contrast 50x70%   fuzzy_thres.png
  magick fuzzy_thres.png  -solarize 50%   fuzzy_spike.png
  magick fuzzy_spike.png  -level 0,50%    filament.png
[IM Output] ==> [IM Output] ==> [IM Output]
旁白: 上面顯示漸變“輪廓”圖的圖像是使用 IM 示例 腳本 目錄中的“im_profile”生成的。請注意,任何白色如何變為黑色,而中央尖峰周圍的中間調灰色如何保留。“-sigmoidal-contrast”運算符決定了尖峰的模糊程度和位置。我稱之為“燈絲”,因為結果通常看起來非常像發光的電燈絲或閃電放電。有關此效果的另一個示例,請參見 隨機通量。這種中間調灰度的提取也被很好地應用於從位圖形狀生成 邊緣輪廓 的技術,以及 兩個偏置梯度的乘法。此操作的另一個新用途是確定圖像基本上是純黑白草圖或繪圖(例如來自書籍),而不是陰影灰度或彩色圖像,請參見 確定圖像是否為:純黑白或灰度

使用查找表重新著色圖像

雖然您可以使用上面顯示的各種直方圖色彩調整來重新著色圖像,但還有另一種重新著色圖像的技術,只需從預先準備好的色彩漸層或“顏色查找表”(Color LUT 或 CLUT)“查找”修改後的數值。顏色查找表有兩種:簡單的一維或“每通道”查找表和 3D 顏色查找表。通道查找表有三個獨立的查找表:R、G 和 B 通道各有一個。通道查找表中的每個條目都將輸入通道值映射到輸出通道值。輸出圖像的紅色通道僅受輸入圖像的原始紅色值的影響。然而,3D 顏色查找表允許根據整個輸入顏色替換整個顏色。也就是說,紅色通道的輸出值可以取決於輸入紅色、綠色和藍色值中的任何一個或全部。這有時稱為通道串擾。

顏色(通道)查找表

圖像處理工具的一個常見要求是能夠從預先準備好的顏色表中替換整個顏色範圍。這使您可以通過從特殊圖像中查找其替換顏色,將一組顏色(通常是灰度)的圖像變成完全不同的顏色集。當然,您確實需要一個“查找表”圖像來讀取替換顏色。對於前幾個示例,我選擇對 LUT 使用垂直顏色漸層,以便可以使用 IM“漸層:”生成器來簡化“顏色查找表”的生成。理論就到此為止。讓我們嘗試通過重新著色一個簡單的灰度等離子體圖像來嘗試一下,用深藍色到灰白色的顏色漸層替換灰度。


magick -size 100x100 plasma:fractal -virtual-pixel edge -blur 0x5 \ -shade 140x45 -normalize \ -size 1x100 xc:black -size 9x100 gradient: \ +append gray_image.jpg magick -size 10x100 gradient:navy-snow gradient_ice-sea.png magick gray_image.jpg gradient_ice-sea.png -clut gray_recolored.jpg
[IM Output] ==> [IM Output] ==> [IM Output]
-clut”運算符採用兩個圖像。第一個是要替換顏色值的圖像,第二個是單行或單列的漸層圖像。
-clut”運算符已添加到 IM v6.3.5-8 中。
如果您的 IM 太舊而無法理解“-clut”運算符,或者您想做一些與眾不同的事情,例如二維顏色查找表,那麼您可以使用通用 DIY 運算符 FX。例如,以下是與上述命令等效的慢速命令。

  magick gray_image.jpg  gradient_ice-sea.png \
          -fx 'v.p{0,u*v.h}'  gray_recolored_fx.jpg
[IM Output]
問題是,即使對於像上面這樣簡單的過程,“-fx”運算符也非常慢,並且必須專門為行或列 LUT 設計。但它確實有效。LUT 不必很大。例如,在這裡我們使用了一個非常小的 LUT,顏色數量非常有限。

  magick -size 1x6 gradient:navy-snow  gradient_levels.png
  magick gray_image.jpg  gradient_levels.png  -clut  gray_levels.jpg
[IM Output] ==> [IM Output] ==> [IM Output]
我放大了網頁顯示上方用於顯示的漸層圖像,否則它太小而無法正確看到。該 LUT 實際上只有 6 個像素大小。但是,如果您查看結果,您會發現顏色查找運算符將這 6 種顏色平滑地轉換為平滑的漸層。發生的事情是 IM 正在對 LUT 圖像進行插值查找。也就是說,它不是僅僅挑選找到的顏色,而是對所有附近的顏色進行加權平均,以更好地表示 LUT。在這種特殊情況下,它使用了默認的“雙線性”設置,該設置僅將每個彩色像素與線性線段鏈接在一起。使用非常小的顏色查找表時,不同的“-interpolate”設置會生成不同級別的顏色平滑度。例如,在這裡我展示了各種類型的 LUT 顏色插值平滑處理。

  magick gray_image.jpg  gradient_levels.png \
          -interpolate Integer         -clut  gray_levels_integer.jpg
  magick gray_image.jpg  gradient_levels.png \
          -interpolate NearestNeighbor -clut  gray_levels_nearest.jpg
  magick gray_image.jpg  gradient_levels.png \
          -interpolate Average         -clut  gray_levels_average.jpg
  magick gray_image.jpg  gradient_levels.png \
          -interpolate Blend           -clut  gray_levels_blend.jpg
  magick gray_image.jpg  gradient_levels.png \
          -interpolate BiLinear        -clut  gray_levels_bilinear.jpg
  magick gray_image.jpg  gradient_levels.png \
          -interpolate Catrom          -clut  gray_levels_catrom.jpg
  magick gray_image.jpg  gradient_levels.png \
          -interpolate Spline          -clut  gray_levels_spline.jpg
[IM Output]
整數
[IM Output]
最近鄰
[IM Output]
平均
[IM Output]
混合
[IM Output]
雙線性
[IM Output]
Catrom
[IM Output]
樣條
Integer」和「Nearest」設置的特殊之處在於它們完全不會對顏色進行平滑處理。也就是說,不會添加新的「混合顏色」,使用存在的確切顏色值為灰度圖像著色。但是請注意兩者之間查找顏色的方式有何不同。這是一個細微的差異,但可能非常重要。另一方面,「Average」設置也會生成色帶,但僅使用顏色的混合,導致顏色數量比顏色查找表圖像的大小少一種。「Blend」混合了「Average」和「Nearest」,以添加更多像素。這種顏色「條帶」(或區塊效應)實際上在地理地圖和溫度圖中很常見,因為它可以更好地表示地圖的確切形狀。邊緣銳利的邊界稱為等值線。在最終圖像中添加輕微的單像素模糊可以改善這些邊緣的外觀,使其看起來更平滑,而不會破壞顏色條帶。「BiLinear」設置也會生成條帶,但僅以急劇的漸變變化形式出現,當顏色急劇變化時(本例中沒有)。而「Catrom」會使顏色變化變得平滑。最後,「Spline」會模糊顏色,並且可能不會生成給定 CLUT 中的任何顏色。為避免插值問題或更好地定義顏色漸變,最好的方法是使用更長的 LUT。理想情況下,這應該涵蓋所有可能的強度值範圍。對於 ImageMagick Q16(使用 16 位品質編譯),需要高度為 65536 像素的 LUT。但是像素插值允許您使用更合理的 500 像素 LUT 漸變圖像,適用於大多數圖像重新著色任務。請注意,在上述示例中使用的垂直漸變 LUT 在我們看來是上下顛倒的,因為黑色或「0」索引位於圖像的頂部。通常,我們人類更喜歡看到黑色級別位於底部的漸變(這要歸功於我們的進化史)。如果您想以「正確的方式」保存漸變圖像,則可以在讀取時「-flip」圖像。例如,讓我們嘗試一個更複雜的 LUT,在將垂直漸變應用於圖像之前先將其翻轉。

  magick -size 1x33 gradient:wheat-brown gradient:Brown-LawnGreen \
          gradient:DodgerBlue-Navy   -append  gradient_planet.png
  magick gray_image.jpg \
          \( gradient_planet.png -flip \) -clut   gray_planet.jpg
[IM Output] ==> [IM Output] ==> [IM Output]
如您所見,對於垂直漸變,在使用之前將其翻轉非常有意義。有關生成漸變的更多示例,請參見顏色漸變。您可能還對使用每個灰度級別的圖像來平鋪灰度圖像的方式感興趣,這可以生成更好的「地圖」類圖像。請參閱使用圖案進行抖動

函數到顏色查找表的轉換

這些預先準備好的「顏色查找表圖像」(或稱 LUT)也可以用來大幅提高非常複雜且速度較慢的「-fx」運算的速度。如此一來,IM 不必每個像素解釋函數字串 3 到 4 次,而是可以更快地查找替換顏色。執行此操作的過程非常簡單,可以將函數應用於未修改的線性漸層,或者將函數中的「u」替換為值「(i/w)」或「(j/h)」,以根據其位置計算替換值。例如,在進階的水波效果範例中,我使用了一個複雜的「-fx」函數來調整陰影運算子的灰階輸出。此外,由於此灰階調整也會疊加到「道奇藍」形狀上,因此沒有理由不能將這兩個運算子的結果組合成單一漸層查找表。也就是說,我們從「-fx」公式和顏色疊加層產生 LUT。此外,在這些範例中,我決定產生單一行像素,而不是像之前那樣產生單一列像素。

  magick -size 1x512 gradient: -rotate 90 -alpha off \
          -fx '3.5u^3 - 5.05u^2 + 2.05u + 0.3' \
          -size 512x1 xc:DodgerBlue -compose Overlay -composite \
          aqua_gradient.png
[IM Output]
現在可以使用多項式函數更直接、更快速地產生上述的多項式「-fx」。例如
"-function Polynomial 3.5,-5.05,2.05,0.3"
現在可以將這個預先生成的 LUT 更快地應用於陰影形狀,而只需儲存一張非常小的圖像。

  magick -font Candice -pointsize 72 -background None label:A \
          -trim +repage  aqua_mask.png
  magick aqua_mask.png -alpha Extract -blur 0x6 -shade 120x21 \
          -alpha On -normalize  aqua_shade.png
  magick aqua_shade.png  aqua_gradient.png -clut aqua_font.png
[IM Output] ==> [IM Output] ==> [IM Output]
警告:上述內容不完整(邊緣尚未變暗)
如您所見,結果非常有效,而且一旦產生了適當的 LUT 漸層,您就可以一遍又一遍地重複使用相同的漸層,次數不限。

色彩查詢表和透明度處理

-clut」運算子由「-channel」設定控制,但實際上它只會替換圖像中的個別通道值。這表示通常會使用來源圖像的每個個別通道從顏色查找表中「查找」僅針對該通道的替換值。這包括 Alpha 通道,而這通常非常不方便且難以應用。通常,「-clut」運算子用於為灰階來源圖像著色(請參閱先前的範例),或者用於使用灰階 CLUT(顏色查找表)對彩色圖像進行直方圖調整。換句話說,通常其中一個圖像通常是灰階的。從 IM v6.4.9-8 開始,如果「-channel」設定指定您要替換/調整圖像的 Alpha 通道(存在「A」),並且「來源」圖像或「CLUT」圖像沒有定義 Alpha 通道,則 IM 會假設該圖像是灰階的,並會採取相應的行動。例如,我在這裡產生一個簡單的模糊三角形,作為灰階圖像。然後,我可以使用包含透明度的顏色查找表進行著色。這次我沒有翻轉 CLUT 圖像,因此黑色替換將位於頂部,而白色替換將位於底部。

  magick -size 100x100 xc:  -draw 'polygon 50,10 10,80 90,80' \
          -blur 0x10  blurred_shape.jpg
  magick -size 1x5 xc:none \
          -draw 'fill red    point 0,2' \
          -draw 'fill yellow rectangle 0,0 0,1'   gradient_border.png
  magick blurred_shape.jpg -alpha off    gradient_border.png \
          -channel RGBA  -interpolate integer -clut  clut_shape.png
[IM Output] ==> [IM Output] ==> [IM Output]
請記住,只有當灰階圖像沒有 Alpha 通道(使用「-alpha off」或「-alpha off」關閉)時,上述操作才會按預期運作,並且您指定也要查找 Alpha 通道值(使用「-channel RGBA」)。以下是另一種特殊情況,其中具有透明度(和 Alpha 通道)的圖像需要使用灰階直方圖調整漸層(未啟用 Alpha 通道)進行調整。

  magick -size 100x100 xc:none -draw 'polygon 50,10 10,80 90,80' \
          tile_disks.jpg -compose In -composite shape_triangle.gif
  magick shape_triangle.gif -channel A -blur 0x10 +channel shape_blurred.png
  magick -size 1x50 gradient: xc:black -append -flip \
          -sigmoidal-contrast 6x0%  feather_histogram.jpg
  magick shape_blurred.png \( feather_histogram.jpg -alpha off \) \
          -channel A    -clut    shape_feathered.png
[IM Output] ==> [IM Output] ==> [IM Output] ==> [IM Output]
以上是一個典型的 影像羽化 問題。中間影像中的「黑色」暈圈是由於 "-blur" 操作使得三角形周圍完全透明的區域變得可見。由於完全透明的顏色未定義,IM 預設為黑色。CLUT 影像本身的設計是為了確保任何透明度低於 50% 的像素都會變成完全透明,有效地使影像中先前完全透明的部分再次透明。在此範例中,我過度執行了初始「模糊」處理,然後過度校正了 Alpha 通道調整。結果是三角形的點嚴重圓化。對於一般影像羽化,通常會對 "-blur" 和 "-sigmoidal-contrast" Alpha 調整使用小得多的值。Fred Weinhaus 在他的 "feather" 腳本中實作了一種模糊羽化技術,使其更易於使用。

Hald 3D 色彩查詢表

從 IM v6.5.3-4 開始,您現在也可以使用完整的 3D 色彩查詢表,該表可用於直接替換多個影像的所有顏色。也就是說,不再將每個顏色通道的值視為單獨的實體(如上面的 CLUT),而是使用整個顏色來查詢新顏色。然而,3D 色彩表通常需要特殊的檔案格式才能正確儲存顏色的 3D 陣列。但是,透過使用特殊的顏色值排列方式,可以將 3D 表格儲存到稱為「Hald 色彩 LUT」的 2D 影像中。這只是一個普通的影像,因此任何良好的影像檔案格式都可以用於儲存 Hald 3D 色彩 LUT。有關 HALD 影像的更多詳細資訊和範例,請參閱官方網站 Hald Images, Clut Technology。要產生 Hald 3D 色彩表,請使用「HALD:{level}」影像產生器。例如,以下是一個小的影像,我將其放大了,以便您可以看到個別的像素...

  magick  hald:3    hald_3.png
[IM Output]
這個表格包含一個顏色立方體,其邊長為「{level}2」種顏色或 9 種顏色。完整的顏色立方體包含「9 × 9 × 9」種顏色,總共 729 種顏色,這些顏色存儲在該數字平方根大小的圖像中,即 27x27 像素。顏色存儲方式是,前 9 種顏色(位於左上角)形成從「純黑色」到「純紅色」的漸變。然後,每隔 9th 種顏色形成「綠色」漸變,每隔 81st 種顏色形成「藍色」漸變。右下角的最後一種顏色是「純白色」。如果您覺得更容易想像,可以將圖像視為一個更簡單的一維像素陣列,這些像素被引用為一個三維顏色立方體。現在這只是一個小的 HALD CLUT 圖像。更典型的情況是,您至少會使用 8 級 Hald(預設值),它將包含一個每邊 64 種顏色的顏色立方體,即 64^3 = 262144 種顏色,並生成一個 512x512 像素大小的圖像,並將其保存為大約 10KB 的 PNG 圖像。這並非所有 8 位元顏色,但已經相當不錯了。對於具有所有 8 位元顏色的 HALD 圖像,您需要使用 16 級版本,這將生成一個 4096x4096 像素的圖像。這只是為了證明即使是普通的數位相機圖像通常也無法容納所有可能的 8 位元顏色。然而,可以使用較小的 Hald 圖像,因為 IM 會從 Hald 中插值相鄰的 8 種顏色來計算出查找替換的最終顏色。它只是不如較大版本的表示方式那麼好。不建議使用大於 8 的 Hald 圖像,因為這需要非常大的圖像,每個值深度至少需要 16 位元才能容納。現在,這些生成的 Hald 圖像是「恆等」或「無操作」CLUT 圖像。也就是說,它們是形成三維顏色立方體的正常顏色值,因此不會對圖像產生任何變化。例如,讓我們使用「-hald-clut」運算符應用「無操作」Hald 圖像...

  magick rose:  hald_3.png -hald-clut   rose_hald_noop.png
[IM Output] ==> [IM Output] ==> [IM Output]
此圖像與原始圖像完全相同,並且 Hald 圖像未包含任何更改。但是,通過手動修改 Hald 圖像或使用顏色修改,您可以將原始顏色替換為修改後的顏色。例如,我在這裡創建了一個混合棕褐色的配色方案...

  magick hald_3.png \( +clone -sepia-tone 60% \) -evaluate-sequence mean hald_sepia.png
  magick rose.png   hald_sepia.png -hald-clut   rose_hald_sepia.png
[IM Output] ==> [IM Output] ==> [IM Output]
當然,如果您可以對 Hald 圖像應用特定的顏色修改,則也可以將其直接應用於實際圖像。但是,您現在可以保存顏色修改以供重複使用,並且可以根據需要多次應用。這意味著您可以將精力集中在 Hald 上,並將其保存以供將來使用。您還可以將 Hald CLUT 圖像發送或下載給其他人,甚至其他應用程式。您甚至可以直接在 Hald 中編輯顏色,使用「Gimp」或「Photoshop」等圖像編輯器,或者如果將其保存為 列舉像素文字圖像,則可以使用純文字編輯器!對於非常複雜的顏色修改,尤其如此。請將您認為有趣或有用的任何 Hald CLUT 圖像發送給我,我會在這裡進行示例說明。您將在此處以及其他地方獲得署名!

Hald 色彩查詢表的限制

與使用 CLUT 運算符 進行的更簡單的一維漸變查找不同,您可以使用 Hald CLUT 來旋轉顏色。例如,交換紅色和藍色。這是一種用途更廣泛的 CLUT 方法。但是,它在執行更簡單的操作(如為灰度圖像著色或對顏色值進行直方圖調整)方面不如前者好。它還可以通過在 Hald CLUT 圖像中保存此類替換顏色,將顏色替換為透明或半透明值。但是,此替換查找僅基於顏色。您不能使用它以特定方式替換透明顏色。畢竟它不是一個四維顏色查找超立方體!

使用 Hald 色彩查詢表替換顏色

由於整個顏色值都用於查找替換顏色,因此您也可以將其用作一種方法,將圖像中的所有顏色直接替換為其他顏色。但是,由於 IM 目前會對 Hald 進行線性內插查找,因此您需要在 3D 色彩立方體的所有 8 個相鄰顏色單元格中設置替換顏色。
建設中
這需要更多工作,並且可能需要「最近鄰」Hald 查找設置(例如使用 -interpolate),而不是 3D 線性內插查找,以便更好地進行特定顏色替換。此外,如果有一些簡單的方法可以在 Hald 中定位特定顏色(最近鄰或 8 個鄰居),這將會容易得多。 如果您有任何想法、建議,或者更好的是提供一些小範例,請將它們發送給我或 IM 討論區 另一個想法是,如果您有兩張圖像,原始圖像和轉換後的圖像,則應該可以通過比較兩張圖像來填充 Hald CLUT 圖像。當填充了直接顏色後,至少應該能夠通過對存在的顏色進行曲線擬合來大致推導出顏色立方體的其餘部分。也就是說,根據發現的顏色變化創建一個 4D 顏色表面。完成後,您可以將 Hald CLUT 應用於任何其他圖像,以便對任何其他圖像進行相同的顏色轉換(在任一方向上)。

完整色彩圖替換

未來:將一個色彩圖中的所有顏色替換為另一個色彩圖中的顏色。歡迎提出有關如何最好地做到這一點的建議,或者由程序員來實現一些圖像色彩圖功能。一種方法可能是使用 使用符號抖動 中提出的想法。目前最著名的解決方案(但並不理想)是由 Fred Weinhaus 在他的「mapcolors」腳本中提供的。該腳本本質上是一次映射一種顏色,將一張圖像中涉及的像素遮罩到一張新的空白圖像中。另一個想法是以某種方式將 3 維顏色替換映射到 HALD 色彩表 中。這不僅會映射指定的顏色,還會以邏輯方式重新映射指定顏色之間的顏色。 需要 HALD 生成器。
建設中
More color options yet to be looked at in detail...

  -contrast
  -brightness-contrast

Color Cycling?
    -cycle     shift colormap (for animations of fractals???)

Chromaticity Color Points???
   –white-point x,y
   –red-primary x,y
   –green-primary x,y
   –blue-primary x,y


Thresholds  (after negation)
  Specifically  -white-threshold and -black-threshold