ImageMagick 範例 —
影像卷積

索引
ImageMagick 範例 前言與索引
卷積簡介
影像模糊化(低通濾波)
邊緣偵測卷積(高通濾波)
方向性卷積(斜率、羅盤濾波)
相關性
相鄰像素計數
卷積使用像素的局部「鄰域」來修改影像。它透過合併和平均每個像素周圍的所有顏色值來實現此目的,以模糊影像、突出顯示邊緣和邊界,以及銳化影像。卷積的變體「相關性」也用於掃描和搜尋特定模式,產生一個表示影像匹配程度的影像。

卷積簡介

Convolve」方法以及與其密切相關的「Correlate」方法,在許多方面與形態學非常相似。事實上,它們的工作方式幾乎完全相同,在每個位置匹配一個鄰域「核心」,使其成為形態學的另一種特殊「方法」。事實上,它們也使用了許多相同的程式碼,甚至與基本核心使用者自訂核心中定義的相同核心定義。如需專為此運算子設計的更具體核心(有很多),請參閱模糊核心邊緣偵測核心。最重要的核心是「高斯」核心。但是,卷積比形態學歷史更悠久,它產生更多灰階漸變效果,而不是形態學通常產生的二元形狀研究效果。這就是為什麼它經常被認為是一種與形態學截然不同或獨立的運算,並且是影像處理中更核心的運算。基本上,卷積或相關性會對指定鄰域中的所有像素執行「加權平均」。也就是說,它將附近每個像素的值乘以核心給定的數量,然後將所有這些值加總在一起以產生最終結果。因此,最終影像中的每個像素通常至少包含原始影像中局部環繞它的所有其他像素的一小部分。換個角度來看,影像中每個像素的顏色將根據所使用的核心,被添加到(模糊)或減去(銳化/邊緣偵測)其所有鄰近像素的顏色。「卷積」和「相關性」是相同的運算,只有一個非常微小但重要的區別,對於我們現在將看到的示例和控件,您可以將它們視為基本相同。稍後(請參閱卷積與相關性),我們將仔細研究這兩個運算子的真正區別,以及為什麼它們的區別如此微小。但在大多數情況下,它們是相同的方法。

卷積  ( )

如上所述,「Convolve」方法的工作原理是根據核心中的浮點值對局部鄰域中的每個像素進行加權。然後將加權值簡單地加總在一起,以在結果影像中產生新的替換像素。例如,讓我們使用一個非常小的使用者自訂卷積核心來卷積單個像素。我還設定了特殊的顯示核心設定,因此您可以看到正在定義和使用的核心的詳細資訊(顯示的影像已放大)。

  magick xc: -bordercolor black -border 5x5 pixel.gif
  magick pixel.gif -define morphology:showKernel=1 \
         -morphology Convolve '3x3: 0.0, 0.5, 0.0
                                    0.5, 1.0, 0.5
                                    0.0, 0.5, 0.0' pixel_spread.gif
[IM Text]
[IM Output] [IM Output] ==> [IM Output]
如您所見,圖像中的單個像素現在已擴展為周圍產生 50% 灰度的像素。也就是說,當內核的「原點」(在本例中為其中心)位於原始圖像中單個像素旁邊時,只有該單個像素具有非零值。然後,此像素值由內核的「0.5」值加權,並將生成的「半亮」像素添加到生成的圖像中。類似地,當內核的原點精確定位在原始像素上時,它將獲得「1.0」的值,從而複製原始像素,並且周圍沒有其他值(黑色)添加任何分量到結果。請注意,任何「0.0」的內核值都不會參與最終計算。零值實際上不是「鄰域」的一部分,就像形態學內核中的任何「Nan」值都不會參與一樣。因此,此內核由 5 個元素鄰域組成。在許多方面,「卷積」方法與形態學「膨脹」方法非常相似,但是「膨脹」僅將內核視為一種位圖遮罩,定位鄰域內的最大值。另一方面,「卷積」是鄰域中所有值的加權和,因此每個內核元素的值都對整體結果起作用。卷積運算的語法是...

  -morphology Convolve {convolution_kernel}
但您也可以使用更舊、更直接的運算符...

  -convolve {convolution_kernel}
在 IM v6.5.9 之前,舊的「-convolve」不理解形態學內核定義。它只接受「舊樣式」的使用者定義內核,僅包含一個由逗號分隔的值組成的字串,以生成一些奇數大小的方形內核。它現在將接受「新樣式」的卷積內核定義。

但是它仍然限於「奇數大小」的方形內核。並且將保持這種狀態,直到它開始使用新的「形態學」卷積方法。

舊的「-convolve」運算符與較新的形態學「卷積」方法並不完全相同。以下是兩個操作的不同之處的列表...

  • 舊運算符實現為相關性而不是真正的卷積。這意味著內核沒有以其反射形式疊加在源圖像上。有關這對結果的影響,請參見卷積與相關性

  • 它只接受奇數大小的方形內核。形態學允許任何矩形陣列,陣列內的任何點都被聲明為原點。

  • 舊運算符將始終標準化內核,而使用者無法控制內核的內核縮放。新的不會自動標準化,您需要請求它。但是,大多數生成的內核都已為您預先標準化。

  • 您不能使用任何形式的與恆等內核混合,儘管輸出輸出偏差會照常執行。
  • 但是,如果主機具有此類功能,它將使用快速的「GPU」代碼。形態學尚未啟用此功能。

  • 目前,其他與卷積相關的運算符,例如「-gaussian_blur」、「-blur」、「-sharpen」、「-unsharp」,都使用舊版本的運算符。

  • 根據預設,舊指令只會針對色彩通道進行卷積(由「-channel」設定所定義)。如果您使用「-channel RGBA」設定進行卷積,它也會根據 Alpha 通道對核心值進行加權,以確保在透明度方面進行正確的模糊處理。

    形態學「convolve」方法預設會自動處理色彩通道的透明度加權。也就是說,使用它進行影像模糊處理會將透明顏色視為透明,從而預設避免 模糊透明度錯誤

    但是,如果使用者修改了預設的「-channel」設定(不包含特殊的「Sync」標誌),那麼它將會把卷積處理成一個純粹基於通道的灰階運算子。

    如需更多資訊,請參閱「-channel」設定文件,或查看 影像通道數學運算,它以相同的方式使用相同的標誌。



最終,隨著與更新的形態學「Convolve」方法的合併,上述大部分差異將會發生變化。

如果您想查看「Convolve」實際運作方式的一些絕佳範例,我建議您也查看 EECE \ CS 253 影像處理,第 7 講,空間卷積維基百科,卷積 文章中有一些關於卷積過程的精美 1D 動畫。

卷積核缩放

上述範例適用於大部分為黑色的影像(例如單一像素),但如果您將其應用於真實影像,則會遇到問題...


magick logo: -resize 50% -crop 80x80+150+60 +repage face.png
magick face.png \ -morphology Convolve '3x3: 0.0,0.5,0.0 0.5,1.0,0.5 0.0,0.5,0.0' \ face_spread.png
[IM Output] [IM Output] ==> [IM Output]
正如您所見,產生的影​​像非常明亮(實際上亮了 3 倍)。發生這種情況的原因是每個像素都被共用了 3 次。邊緣為 4 × 「0.5」,再加上原始像素的完整副本。也就是說,核心中的所有值的總和為 3,這使得產生的影​​像亮了三倍!如果您回頭查看上面的「showKernel」輸出,您將會看到它將此核心列為「卷積輸出範圍從 0 到 3」。這表明此核心通常會使影​​像變亮 3 倍。要解決此問題,您需要將核心中的所有值除以 3。也就是說,「0.5」的值實際上應該是「0.1667」左右,而「1.0」的中心值應該是「0.3333」。此過程稱為「核心正規化」。例如,以下是手動「正規化」的結果以及核心定義...

magick face.png -define morphology:showKernel=1 \
       -morphology Convolve \
       '3x3: 0.0,.1667,0.0  .1667,.3333,.1667  0.0,.1667,0.0' \
       face_spread_norm.png
[IM Text]
[IM Output] [IM Output] ==> [IM Output]
正如您所見,您會得到一張人臉影​​像的稍微模糊版本,因為每個像素都分散到其所有相鄰像素。
上面顯示的「核心影​​像」(使用特殊的 核心轉影像腳本 生成)也顯示了產生的正規化核心。正如您所見,核心本身現在非常暗,因為它的所有值也很暗,儘管它們加起來的值為「1.0」。

從現在開始,所有顯示的卷積核心影​​像都將始終進行調整,以便將最大值設為白色,否則您通常會看到的是一張黑暗且基本上無用的「核心影​​像」。

自己正規化核心並不令人愉快,而且正如您所見,它使得產生的核心定義更難以理解。因此,提供了替代方法。從 IM v6.5.9-2 開始,特殊的專家選項「-define convolve:scale={kernel_scale}」允許您為核心指定全局縮放係數,從而調整整體結果的亮度。

magick face.png -define convolve:scale=0.33333 \
       -morphology Convolve '3x3: 0.0,0.5,0.0  0.5,1.0,0.5  0.0,0.5,0.0' \
       face_spread_scale.png
[IM Output]
實際上,這樣做會調整內核結果的整體強度。 正如您在後面的示例中將看到的,您可能希望使卷積結果或多或少地增強。 這個“kernel_scale”因子讓您可以做到這一點。

內核歸一化(自動縮放)

您可以簡單地要求 IM 通過為其提供特殊的“!”歸一化標誌,在內部計算出這個“歸一化比例因子”,而不是計算出比例因子(如上所述)。

magick face.png -define convolve:scale=\! \
       -morphology Convolve  '3x3: 0,1,0  1,2,1  0,1,0' \
       face_spread_normalize.png
[IM Output]
!”字符有時也被各種 UNIX 命令行 shell 用於特殊目的。 因此,即使在引號中,您也可能必須使用反斜杠來轉義字符。 建議謹慎使用。
請注意,由於內核現在已歸一化,因此我可以使用整數以更簡單的方式定義它。 歸一化後的內核仍然與之前的“縮放”內核相同。 通常,您總是希望對內核進行歸一化,因此,由於這個原因,更簡單的“-convolve”變體將自動執行此歸一化。 您可以讓 IM 對內核進行歸一化,然後再次按給定量進一步縮放它以調整其輸出範圍。 為了更容易,您可以將縮放因子指定為百分比。 例如,在這裡我對內核進行了歸一化,但隨後將值重新縮放到計算大小的 50%,以便產生更暗的結果。

  magick face.png -define convolve:scale=50%\! \
         -morphology Convolve  '3x3: 0,1,0  1,2,1  0,1,0' \
         face_spread_norm_half.png
[IM Output]
請注意,使用值“!”實際上等同於使用“1!”甚至“100%!”。 如果您想翻轉內核內的正值和負值,您甚至可以使用負縮放因子。 有關此示例,請參閱使用模糊“反銳化”圖像。 如果內核已通過這種方式歸一化,則顯示內核輸出將告訴您它已歸一化。

歸一化如何工作

內核歸一化”的實際工作方式是將所有內核值加在一起(包括任何也可能出現的負值)。 如果結果非零,則縮放所有值,使其組合值加起來為 1 (“1.0”)。 請注意,如果您有負值,這實際上可能會創建一個值大於 1 的內核,通常在原點處。 它特別發生在反銳化內核中。 然而,重要的是內核作為一個整體加起來為“1.0”,這樣最終圖像就不會因卷積操作而變暗或變亮。 如果加法的結果為零 (“0.0”),則假定該內核是一個特殊的零和內核。 在這種情況下,縮放內核以使所有正值等於“1.0”,並且同樣,所有負值將加起來為“-1.0”。 這些內核在邊緣檢測技術中尤其普遍。 顯示內核輸出還將指定它是零和的,如果內核是這種形式,即使實際上不是歸一化的零和內核,儘管這也很容易通過顯示的其他數字看到。 大多數數學確定的內核都是預先歸一化的。 這包括數學推導的內核:“Unity”、“Gaussian”、“LoG”、“DoG”、“Blur” , "Comet"。 然而,離散常數內核沒有經過預歸一化,因此您必須使用內核歸一化設置(上文)來執行此操作。 這包括內核:“Laplacian”、“Sobel”、“Roberts”、“Prewitt ”、“Compass”、“Kirsch”、“FreiChen”。 請注意,“FreiChen”內核具有專門為更具體目的預先加權的子類型。 FreiChen 內核不應歸一化,而應按原樣使用。

零和歸一化

並非所有卷積內核都只使用正值。 您也可以使用正值和負值的混合內核,並且這些內核的值通常意味著加起來為零以產生 零和內核。 此類內核對於更高級的圖像卷積非常重要,因為它們提供了 邊緣檢測銳化圖像 的技術。 正如我在上一節中提到的,通常的歸一化標誌“!”將適用於此類內核。 但是有時由於特殊情況,您希望確保內核確實保持“零和”。 特殊的“^”歸一化方法僅提供了一種方法來確保內核在以下情況下為“零和”……
  1. 如果用戶的內核定義不夠精確,無法確保零和。 例如,您不能將“1/3”或 3 的任何其他分數因子指定為精確的浮點十進制數。
  2. 數學曲線被內核大小(半徑)“剪裁”,因此它可能不再是零和。 例如,這發生在基於無限響應曲線的“LoG”或“DoG”內核中。 出於這個原因,IM 實際上在這些內核上內部使用了這種特殊的歸一化。
  3. 確保 相關性“形狀蒙版”為零和,以便在搜索中,IM 可以平等地尋找正匹配和負匹配。 請參閱下面的 相關形狀搜索
發生的情況是,它會將內核的所有正值和負值作為單獨的實體進行歸一化。 也就是說,所有負值都將縮放到“-1.0”,所有正值都縮放到“+1.0”。 結果是將保證內核作為一個整體加起來為零。 請注意,如果您對全正內核(例如“高斯”)使用此歸一化方法,您仍然會得到一個正確歸一化的內核。 因此,這種形式的歸一化仍然可以用於 模糊內核。 但是,它不應用於歸一化直接定義的 銳化 甚至 不銳化 內核,因為這可能包含負值,但需要總和為 1(使用正常的歸一化方法)。

混合內核與單位內核

內核縮放設置的完整語法是...
-define convolve:scale='{kernel_scale}[!^] [,{origin_addition}] [%]'
-set option:convolve:scale '{kernel_scale}[!^] [,{origin_addition}] [%%]'
請注意在使用“-set”時百分比字符的加倍。 可選的歸一化標誌“!”或“^”將首先應用於用戶定義或內置的內核(如果請求)。 之後,內核將按“kernel_scale”因子縮放,增加或減少卷積對結果的有效“功率”。 默認縮放因子為“1.0”。 最後,內核的“原點”值將添加逗號後的數字。 默認“origin_addition”為“0.0”。 最後一步有效地將給定“縮放”的 單位內核 添加到先前生成的歸一化和縮放內核中。 這會生成可以...請注意,如果您給出百分比(“%”)標誌,則該百分比將應用於“kernel_scale”因子和“origin_addition”。 當涉及分數時,這可以使比例更容易閱讀和理解。 內核縮放定義的使用示例...

  -define convolve:scale='!50%,100%'  -morphology Convolve Laplacian:2  
將生成請求的“拉普拉斯算子:2”內核...
0 -1 0
-1 4 -1
0 -1 0
對其進行歸一化('!' 標誌)
0 -0.25 0
-0.25 1 -0.25
0 -0.25 0
縮放 50%
0 -0.125 0
-0.125 0.5 -0.125
0 -0.125 0
添加單位內核(向原點值添加 100%)
0 -0.125 0
-0.125 1.5 -0.125
0 -0.125 0
您現在可以使用 'Laplacian:2' 作為銳化內核進行卷積,但銳化程度僅為 '50%'。請記住,在縮放設定中的任何位置給出的任何 '%' 標記都會使兩個值都成為百分比。如果不存在,則兩個值都只是簡單的直接乘數。例如,以下所有縮放選項都是等效的

     50,100%     50%,100    %50,100      .5,1      0.5,1.0   
這兩個歸一化標記也是如此。它們可以出現在卷積縮放設定中的任何位置,但它們始終會在進行任何其他縮放之前應用。

輸出結果偏差控制

當您處理包含負值的內核時,結果圖像中的一些像素應指定為負值。使用 零和內核(見下文)時尤其如此。不幸的是,除非您有專門構建的 HDRI 版本的 ImageMagick 來保留生成的負值,否則任何負結果都將被裁剪為零(黑色)。您將只從卷積中獲得正結果。它不能存儲在普通的圖像格式中,因此您只能獲得一半的結果。您可以構建 HDRI 版本的 ImageMagick 來保留生成的負值,然後提取您想要的信息。或者,您可以使用負縮放因子來否定內核。例如使用...
-define convolve:scale='-1'
但是,您只會得到負結果,而正結果會被裁剪。但是,通過使用 IM 設定 "-bias",您仍然可以保留正負結果。非 HDRI 版本 IM 的設定是...

     -define convolve:scale=50%\!  -bias 50%
第一個設定將輸出縮放到您通常獲得的一半大小(在歸一化之後),以便為正負結果騰出空間。然後,在將結果保存回圖像之前,它會為像素輸出添加 50% 的灰色。使用這些設定,任何“零”結果都將變為純灰色,負結果比這更暗,正結果比這更亮。黑色將代表 '-1.0',白色將代表 '+1.0'。在下面的 相關形狀搜索 示例中顯示了一個這樣做的示例。

模糊圖像(低通濾波)

IM 示例的另一部分,特別是 模糊和銳化圖像,實際上處理了這個主題的實際方面。在這裡,我們將查看更具體的細節。但是,我們首先將描述基本內核以及如何在不修改的情況下直接使用它們。稍後我們將研究修改模糊以產生其他效果的方法。

模糊化內核

[IM Output]

統一

這是一個實際上什麼都不做的特殊內核。只指定了一個內核元素,因此每個像素都被自身替換而沒有變化。例如,這裡是一個無操作 卷積...

  magick face.png -morphology Convolve Unity face_unity.png
[IM Output] [IM Output] ==> [IM Output]
從 IM v 6.6.9-4 開始,內核可以採用單個參數,作為特定於內核的比例參數。這允許您使用它來乘以圖像的值,例如使圖像變亮或變暗。

  magick face.png -morphology Convolve Unity:0.5 face_dimmed.png
[IM Output]
這似乎不是很有用,但它可以用於生成 軟模糊銳化 效果,或者在您可能無法使用 內核縮放內核恆等混合 的多內核序列中。也可以使用 'Disk:0.5' 生成相同的單元素內核,這也允許您指定一個額外的縮放參數作為內核生成的一部分。(例如:最後一個示例為 'Disk:0.5,0.5')。類似的內核(用於 卷積)也可以由 'sigma' 為 '0.0' 的 '高斯' 內核生成器生成。但是,這只能產生一個小的 3x3 內核,它由一個被 8 個 '0.0' 值包圍的中心 '1.0' 值組成。 [IM Output]

使用形狀內核進行均值或平均濾波

雖然下面定義的大多數卷積內核通常都以某種方式使用高斯曲線,但您仍然可以使用之前的形態學形狀內核之一來簡單地對給定(大)區域內的像素求平均值。當然,您需要標準化內核,以便實際生成平均值,而不僅僅是鄰域的總和。例如,這裡我使用一個較小的“八邊形”形狀的內核,來平均每個像素周圍圓形區域內的所有像素值。

  magick face.png -define convolve:scale=! \
         -morphology Convolve Octagon:2 face_mean.png
[IM Output] [IM Output] ==> [IM Output]
結果是每個像素的值在定義的鄰域中的所有 25 個像素上均勻分佈。也就是說,它等效於在給定形狀上的“均值”或“平均”濾波器。如果要從該平均值中排除原始像素,僅使用周圍像素,則可以使用“環形”內核(僅提供一個半徑)。其他形狀內核也可以用相同的方式使用,例如,對“菱形”、“方形”或大型“圓盤”形狀以及您想要的任何尺寸的像素值求平均值。然而,雖然在形狀區域上的恆定平均會使圖像模糊,但它往往會在生成的圖像中產生不尋常的效果(特別是混疊偽影)。更具體地說,使用“平面”平均內核往往會將銳邊轉換為較厚的線性斜率,並且在加厚邊緣處的斜率會發生突然變化。結果的厚度為內核“半徑*2-1”。不同的邊緣角度如何影響斜率的厚度和線性度,取決於“平面”或平均內核的形狀。

  magick -size 80x80 xc: -draw 'polygon 15,15 15,65 60,15' shape.png
  magick shape.png \
         -define convolve:scale=! -morphology Convolve Square:5 \
         shape_mean_square.png
  magick shape.png \
         -define convolve:scale=! -morphology Convolve Disk:5 \
         shape_mean_disk.png
[IM Output] ==> [IM Output] [IM Output]
請注意,上述對角線模糊對於方形內核與圓盤內核是不同的。另一種生成方形“線性斜率”模糊的方法是對特定半徑使用非常大的 sigma 值。例如,上面的方形內核卷積也可以使用 -blur 5x65535 來實現。這在形態學可用之前,Fred Wienhaus 在他的腳本中經常使用這種方法。 [IM Output]

高斯內核(二維高斯模糊)

您可能已經了解到,“高斯”內核是用於對圖像進行卷積的最常用內核。這是用於模糊效果的數學理想內核。例如,這裡是一個小型“高斯”內核的顯示內核(它們可以很快變得非常大)...

  magick xc: -define morphology:showKernel=1 \
         -morphology Convolve:0 Gaussian:0x0.8 null:
[IM Text]
我實際上並不想對上面應用卷積,因為我只想顯示它要使用的內核。因此,我使用了“:0迭代次數,所以它什麼也不做。類似地,我使用特殊的“null:”文件格式丟棄生成的圖像輸出。正如您從卷積輸出範圍中看到的那樣,“高斯”內核已經為您進行了標準化(縮放)。但是,您還會注意到它仍然是一個相當大的內核,充滿了小的分數值。如果您仔細觀察,您會發現最大值(2.48678,也在第一行列出)位於中心,最小值朝向邊緣和角落(值約為 .000000194)。以下是使用卷積的典型高斯模糊...

  magick face.png -morphology Convolve Gaussian:0x2 face_gaussian.png
[IM Output] [IM Output] ==> [IM Output]
內核語法非常簡單...

   Gaussian:[{radius}]x{sigma}
這些參數實際上與「-gaussian-blur」運算子所使用的參數完全相同,後者實際上是使用此核心執行卷積。第一個數字,像大多數形態學核心一樣,是核心的「半徑」或大小。這只是一個整數,最小值為 1,這使得最小的核心大小為 3x3 個元素。最好的方法是始終指定為零,這讓 ImageMagick 可以為提供的「sigma」值計算適當的半徑。第二個更重要的參數是「sigma」,它定義了每個像素應該變得多麼模糊或「散開」。值越大,圖像就會變得越模糊。它是一個浮點值。必須提供 sigma。如果給定的 sigma 值為「0.0」,您最終將得到一個相當無用的「單位」核心(給定半徑,或半徑為 1,因此產生一個 3x3 的核心,其中包含一個由「0.0」值包圍的「1.0」值。)。正如您在上面看到的,與任何類型的「單位」核心進行卷積對圖像沒有任何作用!如果您確實指定了「半徑」,通常最好將其設置為「sigma」的至少兩倍,IM 通常會計算一個大約是 3 倍大的半徑(實際上是提供有意義結果的最大半徑),儘管這取決於特定 IM 安裝的編譯時品質。有關「高斯」核心參數的效果以及一般圖像模糊的更多信息,請參閱...模糊圖像 [IM Output]

模糊核心(一維高斯模糊)

模糊」核心與高斯核心非常相似,甚至採用相同的參數(見下文)。但是,高斯是一個二維曲線,「模糊」核心產生一個一維曲線。也就是說,它生成一長串單行值。以下是小型「模糊」核心的顯示核心輸出。

  magick xc: -define morphology:showKernel=1 \
         -morphology Convolve:0 Blur:0x0.8 null:
[IM Output]
[IM Text]
上圖是默認「模糊」核心的實際輪廓。它是使用核心圖像腳本「kernel2image」創建的,然後使用「im_profile」腳本繪製該圖像。它清楚地顯示了該核心代表的「高斯鐘形曲線」。
以下是如何使用此核心水平模糊圖像的示例。

  magick face.png -morphology Convolve Blur:0x4 face_blur.png
[IM Output]
核心的語法與「高斯」完全相同,但帶有一個額外的可選旋轉角度。

   Blur:[{radius}]x{sigma}[,{angle}]
和以前一樣,需要第二個值「sigma」,如果設置為零,您將獲得「單位」核心的線性等效值。
角度」允許您將核心旋轉 90 度,從而可以垂直模糊圖像。

  magick face.png -morphology Convolve Blur:0x4,90 face_blur_vert.png
[IM Output]
目前只能旋轉 90 度。這可能會在 ImageMagick 的更高版本中更改。此核心的目的是實際上創建一種比「高斯」核心產生的二維圖像模糊更快的形式。有關如何做到這一點的詳細信息,請參閱下面的高斯與模糊核心 [IM Output]

彗星核心(半一維高斯模糊)

彗星」核心幾乎與「模糊」核心完全相同,但實際上只是半個模糊核心。

  magick xc: -define morphology:showKernel=1 \
         -morphology Convolve:0 Comet:0x1.0 null:
[IM Text]
請注意,原點的定義位置是如何在左邊緣,而不是在核心的中心。這對於卷積核心來說非常不尋常,因此會產生非常不尋常的結果。它會沿一個方向模糊圖像,就像手指塗抹了濕繪畫的表面,留下了一條顏色軌跡。它有點像彗星的尾巴,或者流星或流星留下的軌跡。

  magick face.png -morphology Convolve Comet:0x5 face_comet.png
[IM Output]
請注意,前景和背景顏色都被「模糊」了。如果您只想模糊前景顏色,請將背景設為透明,並在前景模糊後添加它。您還可以指定第三個 *角度* 參數,以將內核圍繞其「原點」旋轉 90 度的任意倍數。

  magick face.png -morphology Convolve comet:0x5+90 face_comet_vert.png
[IM Output]
這個內核實際上與專門的 動態模糊 運算子使用的內核相同,儘管該運算子還執行了一些非常精確的坐標查找處理,以允許模糊在任何角度都能正常工作。儘管它做得不好,但在 45 度等大角度會產生顏色的「團塊」。希望實現適當的內核旋轉,以便在 90 度增量以外的角度創建更好的動態模糊類型效果。 [IM 輸出]

高斯 vs 模糊內核

如前所述,「高斯」和「模糊」內核密切相關,實際上可以完成相同的工作。兩者都是 高斯曲線 的表示,第一個是二維表示,而另一個是一維表示。例如,這裡重複「-gaussian-blur 0x2」,它等效於「-morphology Convolve Gaussian:0x2」運算。

  magick face.png -gaussian-blur 0x2 face_gaussian-blur.png
[IM Output]
這可以通過使用兩個獨立的線性或一維模糊運算(彼此旋轉九十度(順序並不重要))來代替...

  magick face.png -morphology Convolve Blur:0x2 \
         -morphology Convolve Blur:0x2+90 face_blur_x2.png
[IM Output]
您可以將兩個內核作為內核列表提供,而不是指定兩個單獨的捲積。例如

  magick face.png -morphology Convolve 'Blur:0x2;Blur:0x2+90' face_blur_x2.png
根據 多內核組合 設定,IM 預設會使用第二個(以及後續)捲積內核「重新迭代」第一個捲積內核的結果。您甚至可以通過使用「>」執行 90 度旋轉列表(在這種情況下為兩個內核),要求 IM 將一個內核展開為 旋轉內核列表,從而進一步簡化上述內容。例如...

  magick face.png -morphology Convolve 'Blur:0x2>' face_blur_x2.png
以上所有範例都是等效的,這就是「-blur」運算子的工作原理。

  magick face.png -blur 0x2 face_blurred.png
[IM Output]
這表示「-blur」和「-gaussian-blur」運算子之間的真正區別。在前者中,使用單個大型二維內核,而在後者中,使用兩個小型一維內核。然而,就速度而言,「-blur」運算子通常快一個數量級,因為它使用兩個小得多的內核,而不是一個非常大的內核。模糊參數(*sigma* 參數的大小)越大,內核就越大,兩個運算之間的速度差異就越大。因此,「-blur」運算子通常是推薦使用的運算子。兩個運算子之間的結果差異僅在於小的量子捨入效應(除非您使用的是 HDRI)和邊緣效應(取決於 虛擬像素設定)。這兩者都是由於在「模糊」捲積的兩個獨立通道之間保存中間圖像而導致的信息丟失造成的。這種差異通常很小,以至於在任何實際使用中都看不見且無關緊要。

柔化模糊(與原始圖像混合)

您可以通過將任何類型的模糊與一些原始圖像混合來柔化其影響。尤其是在應用非常強烈的模糊時。例如...

  magick face.png -morphology Convolve Gaussian:0x3 face_strong_blur.png
  magick face.png face_strong_blur.png \
         -compose Blend -define compose:args=60,40% -composite \
         face_soft_blur.png
[IM Output] + [IM Output] ==> [IM Output]
這使用了「混合」合成方法,將「60%」的模糊圖像(合成源圖像)與「40%」的原始圖像(合成目標圖像)混合,以在最終圖像上產生「柔化模糊」效果。但是,您可以通過使用相同的比率 將內核與恆等內核混合 來直接執行相同的操作。

  magick face.png -define convolve:scale=60,40% \
         -morphology Convolve 'Gaussian:0x3' face_soft_blur2.png
[IM Output]
請注意,縮放數值的順序是相同的。第一個數字(「60%」)會縮放給定的內核,以減少其對輸出的影響,而第二個數字(「40%」)會加入足夠的「Unity」(或「Identity」)內核,以防止結果變暗。重點是,對於模糊內核,這兩個數字加起來等於「100%」,就像合成混合一樣。您也可以使用更快的兩次通過模糊,但在這種情況下,我們無法將「混合」直接合併到內核中,因為兩個獨立的卷積不會「乾淨地」分離。因此,我們需要在之後再次執行混合合成

  magick face.png \( +clone -blur 0x3 \) \
         -compose Blend -define compose:args=60 -composite \
         face_soft_blur3.png
[IM Output]
請注意,您只需要給出要與原始圖像混合的模糊(來源)圖像的數量。因此,「100」的值將給出模糊的圖像,而「0」將給出原始圖像。
請記住,「-blur」運算符與使用更快的兩次通過模糊內核完全相同。

使用模糊「銳化」圖像(從原始圖像中減去)

通過進一步混合內核,以便開始使用負縮放,您可以從原始圖像中減去模糊效果。結果是一種稱為「銳化」的技術。有關其如何獲得如此不幸的名稱,請參閱Unsharp, Wikipedia

  magick face.png -define convolve:scale=-100,200% \
         -morphology Convolve 'Gaussian:0x2' face_unsharp.png
[IM Output]
請注意,即使使用了負內核縮放因子,這兩個數字仍然加起來等於「100%」,與上面的完全相同。您也可以使用合成混合來做到這一點。上面的示例實際上是錯誤命名的「-sharpen」運算符的工作原理,但只有「sigma」模糊控制。但是,沒有提供對操作的其他控制。混合與上面給出的完全相同。您可以使用更快的兩次通過、一維模糊內核,但同樣需要將混合操作作為單獨的步驟執行。

  magick face.png \( +clone -blur 0x2 \) \
         -compose Blend -define compose:args=-100,200 -composite \
         face_unsharp_fast.png
[IM Output]
您可能已經發現,這與柔化模糊幾乎相同,但模糊的圖像是從原始圖像中減去而不是添加。一種稱為外推混合的混合方法,或混合超出正常的 0 到 100% 範圍。同樣,您可以簡單地指定要從原始圖像中減去多少模糊圖像。例如,讓我們過度銳化圖像,導致一些鋸齒和顏色失真。

  magick face.png \( +clone -blur 0x2 \) \
         -compose Blend -define compose:args=-200 -composite \
         face_unsharp_200.png
[IM Output]
完整的「-unsharp」運算符提供了另一種類型的控制。具體來說,是一個差異閾值,因此只有當給定的差異較大時才應用銳化,例如在圖像內的實際邊緣附近。該閾值可用於防止「銳化」小的缺陷,如皺紋或相機噪點。在調整圖像大小或扭曲圖像後,通常會使用非常小的模糊(sigma=0.75 的數量級)來銳化圖像,以改善最終結果。有關此的一些示例,請參閱銳化調整大小的圖像。使用「銳化」技術進行圖像銳化的替代方法是實際定位圖像邊緣並使用它們來銳化圖像。有關詳細信息,請參閱下面的使用邊緣檢測銳化圖像。但是,它通常被認為速度較慢,儘管實際上並沒有那麼慢。

邊緣檢測卷積(高通濾波)

邊緣偵測是另一個大量使用卷積的領域。這裡的任務是以各種方式突出顯示或增強圖像的邊緣。這可以是盡可能準確地定位邊緣,也可以是確定每個邊緣的斜率角度或方向。然而,圖像中存在的噪聲會使這項工作變得更加困難,例如由掃描器、數位相機產生的噪聲,甚至僅僅是由 JPEG 圖像文件格式的有損壓縮造成的噪聲。然而,一般來說,較大的內核可以更好地處理噪聲,但會損失定位邊緣的準確性,而較小的內核會產生銳利的邊緣定位結果,但由於圖像中的噪聲,會產生更多雜散結果。有很多小的、眾所周知的內核,它們已經被開發出來並被研究用於邊緣偵測。其中大部分是以研究數學或開發特定內核類型的數學家的名字命名的。因此,您會看到諸如「拉普拉斯」、「索貝爾」和「普雷維特」等內核。這些「命名」的內核通常非常小,並且使用整數定義,因此它們可以內建到專門設計的優化軟件和硬件中以提高速度。也就是說,它們被稱為「離散」內核。因此,您需要在使用過程中對內核進行縮放歸一化。邊緣偵測還具有提供銳化圖像邊緣方法的副作用。

零和內核

所有邊緣偵測內核都有一個共同的特徵。它們都是零和的。這意味著它們包含負值,但內核中的所有值加起來為零。對於平滑的純色圖像,使用此類內核的卷積將產生「零」或黑色圖像。但是對於任何其他圖像,您將獲得包含負值和正值的結果。例如,這裡我在包含一些基本形狀的圖像上應用了一個離散的「索貝爾」邊緣檢測器...

  magick -size 80x80 xc:black \
         -fill white -draw 'rectangle 15,15 65,65' \
         -fill black -draw 'circle 40,40 40,20' shapes.gif
  magick shapes.gif -define convolve:scale='!' \
         -morphology Convolve Sobel shapes_sobel.gif
[IM Output] ==> [IM Output]
如果您查看結果,您會發現內核是有方向性的,因為只找到了垂直邊緣(由角度為零的「索貝爾」內核定義)。但是它只找到了一組邊緣,即「正」的從左到右的黑到白的斜坡。要獲得「負」斜坡,您需要使用內核縮放設置來否定內核。例如...

  magick shapes.gif -define convolve:scale='-1!' \
         -morphology Convolve Sobel shapes_sobel_neg.gif
[IM Output]
使用「索貝爾」內核,您也可以將其旋轉 180 度以獲得與「尺度否定」相同的結果,但並非所有內核都以這種方式對稱。另一種解決方案是向結果添加輸出偏差。也就是說,向生成的圖像添加 50% 的灰色,以便負值比這個值淺,而正值比這個值亮。但是,您還需要縮放內核,以確保結果保持在圖像的「黑色」和「白色」限制內「未裁剪」。

  magick shapes.gif -define convolve:scale='50%!' -bias 50% \
         -morphology Convolve Sobel shapes_sobel_bias.gif
[IM Output]
如果您不關心極性,您可以通過一些技巧獲得結果的絕對值..

  magick shapes.gif -define convolve:scale='50%!' -bias 50% \
         -morphology Convolve Sobel -solarize 50% -level 50,0% \
         shapes_sobel_abs.gif
[IM Output]
有關更多結果處理技術,特別是涉及方向判定的技術,請參閱「Sobel」核心。除了使用輸出偏差之外,另一個選擇是建置 Imagemagick 的特殊HDRI版本。這會使用浮點值將圖像儲存在記憶體中,這表示圖像值不會因為使用整數而被「裁剪」或「捨入」。但是,即使您確實使用這個特殊版本的 IM,您仍然需要在儲存到一般圖像檔案格式之前對結果進行後處理,或者您需要使用特殊的啟用浮點數的圖像檔案格式。但是,您不需要擔心中間圖像結果中的裁剪或捨入效應,從而使事情更容易處理。

邊緣偵測核心

[IM Output]

LoG:高斯差分


   LoG:{radius},{sigma}
LoG」或「高斯差分」是您可以獲得的最佳邊緣偵測核心之一。它也被稱為「墨西哥帽」核心。基本上,它是一個「拉普拉斯」微分(斜率)運算器,它已經通過添加高斯模糊進行了平滑處理。這反過來又消除了圖像中大部分的雜訊影響,這可以通過「sigma」設定進行調整。核心包含負值,這些負值在強中心峰值周圍形成環。在上面顯示的「核心圖像」中,負值顯示為深色(接近黑色),邊緣向邊緣衰減為零(深灰色)。這是它的效果。顯示它如何突出顯示圖像的邊緣。

  magick face.png -bias 50% -morphology Convolve LoG:0x2 face_log.png
[IM Output] [IM Output] ==> [IM Output]
拉普拉斯核心是無方向性的,但在邊緣的任一側都會產生正負脊值。要定位邊緣,您需要尋找正負脊之間的零交叉點,這是一種稱為Marr 和 Hildreth 邊緣偵測的技術。這個核心也是銳化圖像的理想選擇。
[IM Output]

DoG:高斯差


   DoG:{radius},{sigma1}[,{sigma2}]
這將產生一個「DoG」或「高斯差」核心,其中從「sigma1」產生的高斯中減去「sigma2」產生的高斯。通常,「sigma2」較大,因此核心的「中心峰值」為正。反轉這兩個數字實際上會使產生的核心無效。對高斯差分的主要批評之一是它難以實現,因為它是一種非常不尋常的數學曲線。它也不是一條有充分文獻記載的曲線。另一個方面是,它不能像高斯那樣「分離」成更快的 2 通解決方案(請參閱高斯與模糊核心)。但是,通過產生兩個sigma值略有不同的「高斯」核心(比例約為 1.6),並將它們彼此相減,您實際上可以產生高斯差分的近似值。結果是「DoG」比「LoG」核心更容易在硬體中產生。例如,在這裡,我將「LoG」和「DoG」核心的核心圖像並排放置以進行比較。
[IM Output] [IM Output]
如果您查看高斯差,維基百科網頁,您將看到一些圖表,他們還將「LoG」(或「墨西哥帽」)的輪廓與「DoG」進行了比較,顯示出匹配曲線之間的差異非常小。需要更多關於如何映射 LoG 的 sigma 以產生接近等效的「DoG」的信息。如果您知道,請通過頁腳中的地址給我發送郵件。
應用結果也非常相似。

  magick face.png -bias 50% -morphology Convolve DoG:0,1.8,2.4 face_dog.png
[IM Output]
請注意,兩個「sigma」值都應該被定義,並且至少有一個應該是非零的。任一 sigma 分量的零值將等效於「Unity」核心,這意味著它會保持圖像不變。如果兩個值都為零,則兩個高斯函數將是「Unity」核心,相減將產生完全為零或黑色的結果(加上任何偏差值)。當參數為「Dog:0,0,非零」時,DoG 將變為一個簡單的高通濾波器,它被定義為「Unity」核心(產生原始圖像)減去一個低通濾波器核心(模糊圖像)。在這種情況下,sigma1=0 只是「Unity」核心,而 sigma2=非零 是一個高斯低通(模糊)濾波器核心。因此,以下將產生一個濾波器值為 sigma2=2 的高通濾波圖像。

  magick face.png -bias 50% -morphology Convolve DoG:0,0,2 face_dog_unity.png
[IM Output]
濾波器半徑值為 2 的 Photoshop 高通濾波器會產生相同的結果。請注意,使用「DoG:0,2,0」將返回一個圖像,該圖像基本上是先前圖像的負片版本(圍繞輸出偏差)。此技術還可以用於生成 3x3 的「各向同性拉普拉斯」核心,這意味著「拉普拉斯」核心在所有方向上產生相等的結果,而不是具有不相等的對角線偏差。例如,半徑=1(對於 3x3 核心)和 sigma 為 1 將生成...

  magick face.png -define morphology:showKernel=1 -bias 50% \
          -morphology Convolve DoG:1,0,1 face_laplacian_isotropic.png
[IM Text]
[IM Text]
使用「高斯差分」的另一個重點是,您可以使用速度更快的「-blur」運算符(它在內部使用「Blur」核心)來生成相同的結果。但是,要做到這一點,您需要分別生成兩個「模糊」圖像,然後減去結果,並添加適當的縮放比例和偏差。例如...

  magick face.png \
         \( -clone 0 -blur 0x1.8 \) \( -clone 0 -blur 0x2.4 \) -delete 0 \
         -compose Mathematics -define compose:args=0,-4,4,0.5 -composite \
         face_diff_of_blurs.png
[IM Output]
以上使用特殊的數學合成方法來避免在非HDRI 版本的 IM 中減去圖像時出現「裁剪」問題。有關更多詳細信息,請參閱添加偏差梯度。另一個因素是在減法過程中使用更大的縮放因子(數學合成參數中的兩個「4」)。這是因為減去兩個歸一化模糊不會產生與在「DoG」核心將兩個減去的高斯曲線一起歸一化時相同的(增加的)結果幅度。但是,除了幅度之外,上面的示例圖像等效於第一個「DoG」核心的結果,只是生成速度更快,尤其是在 sigma 值較大的情況下。這就是重點,即使工作量更大,這種複雜的方法也比直接使用「DoG」或「LoG」核心更快。

離散拉普拉斯核心


   Laplacian:{type}
在許多科學研究論文中,已經發表了許多形式的小型「拉普拉斯運算核」。這裡我提供了我在學術文獻中找到的更常見的內建版本。這些運算核基本上是使用「LoG」運算核計算的,但經過縮放以在小型運算核陣列中使用離散整數值。這使您可以使用生成的專用快速影像濾波器,這些濾波器僅使用整數數學來處理影像數據。然而,ImageMagick 是一個更通用的影像處理器,因此不提供這種超快速的專用濾波器。但是人們喜歡使用它們,因為它們更容易理解,所以其中許多已經內建到 IM 中。這裡提供的運算核都不能旋轉,而且大多數是「各向異性」的,這意味著它們不是完美的圓形,尤其是在對角線方向上。但是,請參閱上一節(「DoG」運算核)瞭解生成真正的「各向同性 3x3 拉普拉斯運算核」的方法。前兩個「Laplacian:0」和「Laplacian:1」運算核是「離散拉普拉斯運算核」最常用的形式。它們非常小,這意味著它們可以非常準確地定位邊緣,但也容易增強影像雜訊。請注意,並非所有「類型」編號都已定義,為將來定義更多離散運算核留下了空間。使用的數字經過選擇,以便更好地匹配該數字定義的運算核。

Laplacian:0(預設)

8 鄰域拉普拉斯運算器。可能是最常見的離散拉普拉斯邊緣檢測運算核。在這裡,我使用顯示運算核提取「離散」和「未歸一化」的運算核,然後向您展示帶有輸出偏差的歸一化運算核的結果。

  magick xc: -define morphology:showKernel=1 -precision 2 \
         -morphology Convolve:0 Laplacian:0 null:
  magick face.png -define convolve:scale='!' -bias 50% \
         -morphology Convolve Laplacian:0 face_laplacian_0.png
[IM Text]
[IM Text]
有時,無論是像上一個示例中的離散拉普拉斯運算器,還是生成的「LoG」或「DoG」,拉普拉斯運算器產生的結果都比預期的要複雜。在這種情況下,生成無偏差的影像(没有任何輸出偏差)會更好。所以讓我們重複上面的步驟,但不帶偏差,以便只保留較亮的「正」邊緣。

  magick face.png -define convolve:scale='!' \
         -morphology Convolve Laplacian:0 \
         -auto-level face_laplacian_positives.png
[IM Output]
在這種情況下,我們在較淺(白色)的顏色上得到了深色(黑色)的線條。這反過來又導致濾波器將邊緣「加倍」,這可以在顯示的結果中看到。對於此影像,使用負縮放因子(保留負邊緣,而不是正邊緣)似乎在我們的測試影像上效果更好。

  magick face.png -define convolve:scale='-1!' \
         -morphology Convolve Laplacian:0 \
         -auto-level face_laplacian_negatives.png
[IM Output]
如您所見,對於此影像,使用負大小會產生更強的邊緣,而不會產生正結果產生的「孿生」效果。這是因為在使用的影像中使用了白色背景上的「黑色」邊緣線。旁白:您在黃色星星周圍得到藍色邊緣的原因是「黃色」星星和「白色」背景之間的差異是藍色的減法運算。如果背景是黑色的,您將得到黃色的邊緣顏色。

Laplacian:1

4 鄰域拉普拉斯運算器。也很常用。

  magick xc: -define morphology:showKernel=1 -precision 2 \
         -morphology Convolve:0 Laplacian:1 null:
  magick face.png -define convolve:scale='!' -bias 50% \
         -morphology Convolve Laplacian:1 face_laplacian_1.png
[IM Text]
[IM Text]
結果不是很強烈,但通常比 8 鄰域拉普拉斯運算器更清晰。

Laplacian:2

3x3 拉普拉斯運算器,中心:4 邊緣:1 角落:-2

  magick xc: -define morphology:showKernel=1 -precision 2 \
        -morphology Convolve:0 Laplacian:2 null:
  magick face.png -define convolve:scale='!' -bias 50% \
         -morphology Convolve Laplacian:2 face_laplacian_2.png
[IM Text]
[IM Text]

Laplacian:3

3x3 拉普拉斯運算器,中心:4 邊緣:-2 角落:1

  magick xc: -define morphology:showKernel=1 -precision 2 \
             -morphology Convolve:0 Laplacian:3 null:
  magick face.png -define convolve:scale='400%!' -bias 50% \
         -morphology Convolve Laplacian:3  face_laplacian_3.png
[IM Text]
[IM Text]
此運算核突出顯示對角線邊緣,並傾向於使垂直和水平邊緣消失。但是,您可能需要縮放結果(如我上面所做的那樣)才能使任何結果可見。

Laplacian:5

5x5 拉普拉斯運算器

  magick xc: -define morphology:showKernel=1 -precision 2 \
         -morphology Convolve:0 Laplacian:5 null:
  magick face.png -define convolve:scale='!' -bias 50% \
         -morphology Convolve Laplacian:5 face_laplacian_5.png
[IM Text]
[IM Text]
拉普拉斯運算核的經驗法則是,它們越大,結果越乾淨,尤其是在存在錯誤的情況下。但是,您獲得的細節也更少。

Laplacian:7

7x7 拉普拉斯運算器

  magick xc: -define morphology:showKernel=1 -precision 2 \
         -morphology Convolve:0 Laplacian:7 null:
  magick face.png -define convolve:scale='!' -bias 50% \
         -morphology Convolve Laplacian:7 face_laplacian_7.png
[IM Text]
[IM Text]

Laplacian:15

離散 5x5 LoG(Sigma 約為 1.4)

  magick xc: -define morphology:showKernel=1 -precision 2 \
         -morphology Convolve:0 Laplacian:15 null:
  magick face.png -define convolve:scale='!' -bias 50% \
         -morphology Convolve Laplacian:15 face_laplacian_15.png
[IM Text]
[IM Text]

Laplacian:19

一個離散的 9x9 LoG(Sigma 約為 1.4)

  magick xc: -define morphology:showKernel=1 -precision 2 \
         -morphology Convolve:0 Laplacian:19 null:
  magick face.png -define convolve:scale='!' -bias 50% \
         -morphology Convolve Laplacian:19 face_laplacian_19.png
[IM Text]
[IM Text]

透過邊緣偵測銳化影像(增強原始影像的邊緣)

LoG」和「DoG」核心除了可用於使用模糊來反銳化影像之外,也可以用於銳化影像。基本上,您需要做的就是將核心結果(包括負值結果)加到原始影像中。若要執行此操作,只需將加權 100% 的「Unity」或「Identity」核心加到比例因子即可。這就是提供它的原因。
例如...

  magick face.png -define convolve:scale='100,100%' \
         -morphology Convolve 'Log:0x2' face_sharpen.png
[IM Output]
反銳化技術產生的結果(結果顯示在右側)相比,這是對影像進行更廣泛、更平滑的銳化。也就是說,因為它是對影像進行實際的真正銳化,而不是透過減去模糊來偽造的。 [IM Output]
如前所述,當只執行單次捲積時,您可以直接使用混合核心
例如,銳利度較低...

  magick face.png -define convolve:scale='50,100%' \
         -morphology Convolve 'Log:0x2' face_sharpen_50.png
[IM Output]
或者更銳利...

  magick face.png -define convolve:scale='150,100%' \
         -morphology Convolve 'Log:0x2' face_sharpen_150.png
[IM Output]
您可以使用高斯差分的 2 次傳遞方法來產生更快的多步驟銳化操作,但如上所示,此類方案需要 4 次捲積和一個單獨的混合操作才能達到相同的結果。未來:新增此範例這種複雜性就是使用反銳化更常被視為銳化影像的首選方法的原因。但正如您所見,對於繁重的銳化過程,使用適當的銳化核心比反銳化更可取。然而,對於輕微的銳化,例如銳化調整大小後的影像,使用反銳化沒有問題。

方向性捲積(斜率和羅盤)

與上述類似,這些核心會尋找影像顏色強度的斜率,但這些核心不是尋找任何斜率,而是尋找特定方向的斜率。在數學上,這稱為「導數」,它實際上只是「斜率」的另一種說法。但了解不同方向的斜率資訊也可以作為一種方法,您可以藉此確定斜率或影像邊緣的角度或「羅盤」方向。也就是說,影像中某個特定點的斜率的二維方向。斜率也用於稱為影像「浮雕」和「陰影」的影像處理技術中。目前沒有可用的「生成」核心,只有「命名」的預定義核心,例如SobelRoberts。但是,我確信浮雕和陰影核心生成函數將在未來的某個時候移入形態/捲積核心集中。因此,讓我們來看看一些「命名」的方向性核心。

方向性內核

Sobel


   Sobel:{angle}  
[IM Text]
我們在上面討論零和核心時已經見過「Sobel」核心。此核心是一個原始方向性(一階導數)核心,設計用於透過「convolve」運算傳回某個特定正交方向上的邊緣斜率。根據預設,它設計用於透過「捲積」運算進行從左到右的斜率偵測。結果本質上是影像的 X 導數(斜率)。

  magick -size 60x60 xc:black xc:white +append slope_positive.gif
  magick slope_positive.gif -morphology Convolve Sobel slope_sobel.gif
[IM Output] [IM Output] ==> [IM Output]
如果您查看核心,您可能會認為它被反向宣告了。從某種意義上說,您實際上是正確的。然而,這是由於「捲積」實際上的運作方式。

您可以在下面的捲積與相關中更詳細地了解這種「反轉」。

請注意,此核心也可以產生「負斜率」指示,但除非在此捲積運算中也使用了「50%」的偏差,否則無法看到。雖然在上一個範例中沒有負斜率,但下一個範例中有一個負斜率,因此我還添加了一個偏差設定,以便您可以看到它。

  magick -size 40x60 xc:black xc:white xc:black +append slope_both.gif
  magick slope_both.gif -define convolve:scale='50%!' -bias 50% \
         -morphology Convolve Sobel slope_sobel_bias.gif
[IM Output] [IM Output] ==> [IM Output]
如果您將此核心與「Correlate」一起使用,您會發現斜率「匹配」核心定義的方式。在這種情況下,您會得到一個從左邊高(白色值)到右邊低(黑色值)的斜率的正結果。在上面的例子中,這兩條線將被交換。

然而,上面是「卷積」,而不是「相關」(意思是匹配核心)。有關差異的更多細節,請再次參閱卷積與相關
如您所見,當我們沿著從黑到白的斜坡向上移動時,我們現在得到一條白線(正斜率),而當我們從白到黑向下移動時,則得到一條黑線(負斜率)。以下是使用預設的「Sobel」核心在人臉圖像上的結果。

  magick face.png -define convolve:scale='50%!' -bias 50% \
         -morphology Convolve Sobel face_sobel.png
[IM Output] [IM Output] ==> [IM Output]
請注意,Sobel 和大多數其他邊緣檢測核心傾向於沿著非常強的邊緣產生 2 個像素厚的響應,以及在單個像素寬的線上產生 3 個像素厚的響應。這比拉普拉斯邊緣檢測器強得多。您可以使用「角度」參數旋轉此核心,通常以 90 度的倍數旋轉。但是,您也可以將其旋轉 45 度的倍數,即使它並非為此而設計。這對於從所有 45 度旋轉導數結果的最大值中獲得 45 度量化的方向導數或梯度大小非常有用。
它又來了,但旋轉了 90 度(從上到下)。

  magick face.png -define convolve:scale='50%!' -bias 50% \
         -morphology Convolve Sobel:90 face_sobel_90.png
[IM Output]

使用「Sobel」核心收集圖像所有邊緣的一種方法是在所有方向上應用 4 次核心,並收集看到最大值(使用亮化數學合成。這是對梯度大小的近似值。

   magick face.png -define convolve:scale='!' \
          \( -clone 0 -morphology Convolve Sobel:0 \) \
          \( -clone 0 -morphology Convolve Sobel:90 \) \
          \( -clone 0 -morphology Convolve Sobel:180 \) \
          \( -clone 0 -morphology Convolve Sobel:270 \) \
          -delete 0 -background Black -compose Lighten -flatten \
          face_sobel_maximum.png
[IM Output]
您可以通過利用 IM 形態的多核心處理功能來簡化上述操作。也就是說,您可以創建一個「Sobel」核心的所有 90 度旋轉的旋轉列表。

   magick face.png -define convolve:scale='!' \
          -define morphology:compose=Lighten \
          -morphology Convolve 'Sobel:>' face_sobel_maximum_2.png
[IM Output]
如果您想確切地查看上述操作正在做什麼,請添加顯示核心設定和詳細設定。生成梯度大小的更有效技術是利用 180 度旋轉僅產生與否定核心相同的結果,從而否定結果。因此,X 和 Y 導數(90 度旋轉卷積)以及一些獲得卷積絕對值的技巧,可以以更少的處理量實現這樣的結果。

   magick face.png -define convolve:scale='50%!' -bias 50% \
          \( -clone 0 -morphology Convolve Sobel:0 \) \
          \( -clone 0 -morphology Convolve Sobel:90 \) \
          -delete 0 -solarize 50% -level 50,0% \
          -compose Lighten -composite face_sobel_maximum_3.png
[IM Output]
這對於大多數目的來說通常已經足夠好了。所有斜率的更精確幅度可以通過 X 和 Y 導數的向量加法來提取(根據畢達哥拉斯定理)。

   magick face.png -define convolve:scale='50%!' -bias 50% \
          \( -clone 0 -morphology Convolve Sobel:0 \) \
          \( -clone 0 -morphology Convolve Sobel:90 \) \
          -delete 0 -solarize 50% -level 50,0% \
          +level 0,70% -gamma 0.5 -compose plus -composite -gamma 2 \
          -auto-level face_sobel_magnitude.png
[IM Output]
上述使用中的「-gamma」函數用於對「Sobel」結果返回的值執行數學「平方」和「平方根」。有關更多詳細信息,請參閱數學函數的冪

額外的「+level」確保加法合成不會溢出圖像量化範圍。有關詳細信息,請參閱量化效應,非 HDRI 與 HDRI
您可以從兩個邊緣檢測結果中提取斜率的方向,而不是大小。

  magick -size 30x600 xc:'#0F0' -colorspace HSB \
         gradient: -compose CopyRed -composite \
         -colorspace RGB -rotate 90  rainbow.jpg
  magick shapes.gif -define convolve:scale='50%!' -bias 50% \
         \( -clone 0 -morphology Convolve Sobel:0 \) \
         \( -clone 0 -morphology Convolve Sobel:90 \) \
         -delete 0 \
         \( -clone 0,1 -fx '0.5+atan2(v-0.5,0.5-u)/pi/2' rainbow.jpg -clut \) \
         \( -clone 0,1 -fx 'u>0.48&&u<0.52&&v>0.48&&v<0.52 ? 0.0 : 1.0' \) \
         -delete 0,1 -alpha off -compose CopyOpacity -composite \
         face_sobel_direction.png
[IM Output] ==> [IM Output]
第一個 "-fx" 表達式使用 'atan()' 函數將 X,Y 向量轉換為角度。然後使用外部的 彩虹漸層影像 為其著色,作為 顏色查找表。第二個 "-fx" 表達式建立一個閾值透明遮罩,使任何沒有斜率的區域變為透明。然而,上述技術往往會對真實影像產生大量混亂的信息,因為它沒有考慮到斜率的大小。以下是一個更複雜的版本。它幾乎在綠色 'G' 通道中進行所有計算,以便將所需的影像處理量減少三分之一。然後它使用 HSB 色彩空間來建立方向(色相)和大小(亮度)。

  magick face.png -colorspace Gray    -channel G \
         -define convolve:scale='50%!' -bias 50% \
         \( -clone 0 -morphology Convolve Sobel:0 \) \
         \( -clone 0 -morphology Convolve Sobel:90 \) \
         -delete 0 \
         \( -clone 0,1 -fx '0.5 + atan2(v-0.5,0.5-u)/pi/2' \) \
         \( -clone 0   -fill white -colorize 100% \) \
         \( -clone 0,1 -fx 'hypot(u-0.5,v-0.5)*2' \) \
         -delete 0,1 -separate +channel \
         -set colorspace HSB -combine -colorspace RGB \
         face_sobel_magnitude_n_direction.png
[IM Output]

Roberts


   Roberts:{angle}  
[IM Text]
'Roberts' 核心比之前的 'Sobel' 核心簡單得多,並且會產生更精確的邊緣位置(低至 2 個像素)。當然,這也使其更容易受到雜訊影響。通常,這個核心由一個小得多的 2x1 甚至 2x2 核心表示,但是通過將其實現為一個 3x3 核心,我可以以 45 度的增量“循環”旋轉核心。
例如,以下是一個 45 度的結果,更常見的名稱是“Roberts-Cross”核心。

  magick face.png -define convolve:scale='50%!' -bias 50% \
         -morphology Convolve Roberts:45 face_roberts.png
[IM Output]
與 'Sobel' 一樣,您也可以使用 多核心處理 從所有方向生成最大斜率。但是這一次我們將獲得 8 x 45 度的方向,而不仅仅是 4 個。

   magick face.png -define morphology:compose=Lighten \
          -morphology Convolve 'Roberts:@' face_roberts_maximum.png
[IM Output]
請注意,將此核心旋轉 180 度不會產生負值結果(由於偏移)。因此,您不能像使用 'Sobel' 那樣簡單地合併一半數量的卷積。基本上,僅由一個 'Roberts' 卷積生成的斜率偏離實際影像對齊半個像素。也就是說,計算出的斜率位於像素之間的 '+1' 和 '-1' 值之間的點,但存儲在中心的 '-1' 像素中。然而,這也意味著通過保存像素周圍的所有斜率並將它們加在一起,您可以獲得一個小得多的銳利邊緣檢測,只有 2 個像素(而不是 4 個像素)突出顯示銳利的邊緣邊界。

Prewitt


   Prewitt:{angle}  
[IM Text]
'Prewitt' 核心與 'Sobel' 非常相似,但在特定邊緣檢測的確切方向上要鬆散得多。因此結果會更加模糊。

  magick face.png -define convolve:scale='50%!' -bias 50% \
         -morphology Convolve Prewitt face_prewitt.png
[IM Output]

Compass


   Compass:{angle}  
[IM Text]
這是“Prewitt Compass”核心,據說它比 'Sobel' 具有更強的方向感。

  magick face.png -define convolve:scale='50%!' -bias 50% \
         -morphology Convolve Compass face_compass.png
[IM Output]

Kirsch


   Kirsch:{angle}  
[IM Text]
這是另一個強方向感應邊緣檢測器。

  magick face.png -define convolve:scale='50%!' -bias 50% \
         -morphology Convolve Kirsch face_kirsch.png
[IM Output]

Frei-Chen

此內建功能提供了三組核心。第一個是 'Sobel' 的“各向同性”(均勻方向)變體,其中 '2' 值已被 2 的平方根替換。

   Frei-Chen:[{type},][{angle}]  
[IM Text]
上面的核心是作為 'Frei-Chen' 核心核心的默認未加權核心。

  magick face.png -define convolve:scale='50%!' -bias 50% \
         -morphology Convolve Frei-Chen face_freichen.png
[IM Output]
與 'Sobel' 一樣,應使用 90 度倍數的角度應用此核心。為了使事情變得更容易,提供了兩個核心(具有相同的權重),一個像上面那樣用於正交使用,另一個用於對角線使用。
Frei-Chen:1
[IM Text]
Frei-Chen:2
[IM Text]
第三組類型包含 9 個經過特殊設計和加權的內核,這些內核不僅用於特定方向的邊緣檢測,還用於確定銳邊的實際角度。此處的「類型」是從「11」到「19」的數字,允許您提取集合中的任何一個內核。但是,如果您提供的「類型」值為「10」,您將獲得所有 9 個預先加權內核的多內核列表。
The kernels are each applied to the original image, then the results are added
together to generate the edge detection result.

This is best done using a HDRI version of
ImageMagick.


   magick image.png \
          \( -clone 0 -morphology Convolve FreiChen:11 \) \
          \( -clone 0 -morphology Convolve FreiChen:12 \) \
          \( -clone 0 -morphology Convolve FreiChen:13 \) \
          \( -clone 0 -morphology Convolve FreiChen:14 \) \
          \( -clone 0 -morphology Convolve FreiChen:15 \) \
          \( -clone 0 -morphology Convolve FreiChen:16 \) \
          \( -clone 0 -morphology Convolve FreiChen:17 \) \
          \( -clone 0 -morphology Convolve FreiChen:18 \) \
          \( -clone 0 -morphology Convolve FreiChen:19 \) \
          -delete 0 -background Black -compose Plus -flatten \
          result.pfm
If a type of 10 is given then a multi-kernel list of all the 9 weighted kernels
shown above is generated. This lets you use multi-kernel composition to do the
above, much more simply...


    magick image.png -define morphology:compose=Plus \
           -morphology Convolve FreiChen:10 \
           result.pfm
I have not however found out what the supposed meaning of the results are.  If
anyone has any experience or knowledge about how this is actually used, please
let me know, so I can include it here for others to use.  


相關  ( )

卷積」方法基本上用於圖像處理,而「相關」方法則更多地設計用於模式匹配。也就是說,它執行圖像及其內核的「互相關」,在圖像中尋找給定形狀的匹配。實際上,「卷積」和「相關」是相同的操作。它們之間的唯一區別實際上非常小,即內核的 x 和 y 反射(相當於 180 度旋轉)。我找到的關於相關和卷積如何工作以及它們之間如何不同的最佳指南是David Jacobs 的 CMSC 426 秋季班課程筆記,2005 年

卷積與相關(不對稱內核效應)

正如我上面提到的,兩個運算符「卷積」和「相關」在本質上是相同的。事實上,用戶經常說卷積,而他們真正指的是相關。此外,相關實際上是更容易理解的方法。對於圍繞中心「原點」對稱的內核(這是非常典型的情況),這兩種方法實際上是相同的。只有當您使用不對稱或不均勻的內核時,差異才會變得明顯。例如,在這裡我對「單像素」圖像使用「L」形的「平面」內核。

  magick pixel.gif  \
         -morphology Convolve '3: 1,0,0
                                  1,0,0
                                  1,1,0' convolve_shape.gif
[IM Output] [IM Output] ==> [IM Output]
如您所見,「卷積」擴展了中心的單個像素,在其周圍形成「L」形。即使原點本身不是「鄰域」的一部分。現在讓我們重複這個例子,但使用「相關」。

  magick pixel.gif  \
         -morphology Correlate '3: 1,0,0
                                   1,0,0
                                   1,1,0' correlate_shape.gif
[IM Output] [IM Output] ==> [IM Output]
如您所見,「相關」也擴展了單個像素,形成了一個「L」形,但它是一個「旋轉的」「L」形。這本質上是這兩種方法之間的唯一區別。「相關」方法「按原樣」應用內核,這會導致單個像素擴展為「旋轉」形式。另一方面,「卷積」實際上使用內核的 180 度「旋轉」形式,以便每個像素都被擴展為相同的非旋轉形狀。如果您想查看一些關於「卷積」實際工作原理的很好的例子,我建議您也看看EECE \ CS 253 圖像處理,第 7 講,空間卷積。第 22 頁上的圖表,它實際上將「反射」內核應用於單個像素,就像我上面所做的那樣。
這個旋轉差異看起來可能不大,但這意味著在數學上,卷積運算(以星號 ('*') 表示)是可交換的,也就是說,如果將內核和圖像都視為值數組(或兩個圖像),則 F * G == G * F。這也意味著卷積是結合的,也就是說 ( F * G ) * H == F * ( G * H )。有關這方面的更多信息,請參見維基百科的卷積性質。'相關' 運算既不是可交換的 也不是結合的。即使它與內核的旋轉密切相關。基本上,'卷積' 的作用更像數學上的“乘法”,而 '相關' 則不是。所有這些爭論的例外情況是,當使用的內核旋轉 180 度時是相同的。也就是說,內核關於“原點”是對稱的。在這種特殊情況下,兩種操作會產生等效的結果。令人困惑的是,大多數用於卷積的內核,例如高斯模糊、拉普拉斯算子等都是對稱的,在這種情況下,您實際上是在進行卷積還是相關運算並不重要。所以人們對含義變得輕鬆和模糊。只有當它們不對稱時,例如在形狀搜索(見下文)或使用諸如Sobel 之類的定向內核時,這種差異才會變得真正重要。

相關性和形狀搜尋

'相關' 方法的真正用途(按原樣應用內核鄰域而不旋轉)是一種古老但簡單的方法,用於定位與提供的內核中發現的形狀大致匹配的形狀對象。例如,如果我們要對“L”形內核使用“相關”並嘗試搜索我們使用上面的卷積方法示例創建的圖像,我們得到...

  magick convolve_shape.gif -define convolve:scale='1!' \
         -morphology Correlate '3: 1,0,0
                                   1,0,0
                                   1,1,0' correlate.gif
[IM Output] [IM Output] ==> [IM Output]
旁白:請注意,上面內核圖像中的“黑色”區域表示值為零。此內核中沒有負值,只有要匹配的形狀的正值。

請注意,我使用了 IM 的內核歸一化來防止最終結果變得太亮,並在白色的點海中淹沒“峰值”。如您所見,'相關' 方法在內核“原點”與圖像中的相同形狀完全匹配的點產生了最大亮度。但是,當您只獲得形狀的部分匹配時,它也會產生不太亮的结果。匹配的形狀越多,像素就越亮。但是,我要提醒您,雖然 '相關' 在這種情況下取得了成功,但它並不是一個很好的方法。例如,它會在亮度非常高的區域中產生大量的誤報。通過對應與圖像的暗背景匹配的區域使用負值可以緩解此問題。也就是說,與背景不匹配的區域會使生成的像素亮度降低。

  magick convolve_shape.gif -define convolve:scale='1^'  \
         -morphology Correlate '4x5+2+2:  0 -1  0  0
                                         -1 +1 -1  0
                                         -1 +1 -1  0
                                         -1 +1 +1 -1
                                          0 -1 -1  0 ' correlate_pattern.gif
[IM Output] [IM Output] ==> [IM Output]
旁白:為了使內核圖像更清晰,我生成了內核圖像,以便正(前景)值為白色,負(背景)值為黑色,零(無關緊要)值為透明。但是,實際使用的內核是根據數字完全定義的,並且它的“鄰域”是一個完整的矩形。

如您所見,匹配峰值更加明顯,因為您現在不僅匹配了前景像素,還匹配了背景像素。請注意上面使用的特殊歸一化標記 '^'。這一點很重要,因為它將分別對內核中的正值和負值進行歸一化。也就是說,您希望平等地搜索前景像素和背景像素。這意味著您可以使用 HDRI 版本的 IM 或適當使用 輸出偏差(見上文)來搜索給定形狀的正匹配和負匹配。例如,在這裡,我將“L”形搜索應用於包含正負“L”形的測試圖像。(顯示的圖像已被放大)

  magick test_morphology.gif  -bias 50% -define convolve:scale='50%^' \
         -morphology Correlate '4x5+2+2:  0 -1  0  0
                                         -1  1 -1  0
                                         -1  1 -1  0
                                         -1  1  1 -1
                                          0 -1 -1  0 ' correlate_bias.gif
[IM Output] [IM Output] ==> [IM Output]
輸出偏差 使搜索的正常輸出為中間灰色,而匹配的形狀根據實際匹配“形狀內核”的像素數量給予更亮或更暗的顏色。如果僅檢查輸出圖像的實際值,則會產生一個純白色像素和一個純黑色像素,表示完美匹配。然而,也有相當多的近似匹配。如果我不對負或“黑色”匹配感興趣,我可以刪除 輸出偏差 和“50%”縮放因子,這樣不匹配的像素是黑色的,完美匹配的是白色的。獲得“相關”匹配圖像後,您需要嘗試找到匹配的“峰值”。這可以使用另一個 相關 來完成,但並不總是有效。更好的方法是使用更精確的模式匹配方法,“擊中與錯過”形態學,以及為此目的創建的特殊“峰值”。這會找到任何僅被顏色較深的像素包圍的單個像素。其他“峰值”內核可用於查找“更寬鬆”的匹配。

  magick correlate_bias.gif  -morphology hitandmiss peaks:1.9 \
         -auto-level correlate_peaks.gif
[IM Output] [IM Output] ==> [IM Output]
在這裡,您可以輕鬆找到形狀最佳匹配的位置,儘管匹配的程度已經丟失。您可能想查看 比較和子圖像搜索 中的“峰值查找”部分。但也請查看 Fred Weinhaus 的腳本“maxima”。 未來:使用快速傅立葉變換進行歸一化互相關,以生成具有非常大的圖像(源圖像和子圖像)的非常快速的圖像相關性。

相關與擊中和錯過形態學

如果您將我表示的內核圖像與 擊中和錯過形態學方法 使用的內核進行比較,您會發現它們實際上代表了同一件事。
'擊中與錯過' '相關'
前景 值為 '1.0' 值為 '1.0'(歸一化之前)
無關緊要 值為 'Nan' 或 '0.5' 值為 'Nan' 或 '0.0'
背景 值為 '0.0' 值為 '-1.0'(歸一化之前)
結果 從背景最大值中減去前景最小值。因此,只有精確匹配才會產生正結果,並且閾值化將產生二進制匹配圖像。 生成圖像與形狀匹配程度的範圍。只要存在整體模式,一些背景像素的值就可能大於前景像素。可能難以找到特定的“匹配”峰值。您也可以找到負匹配。
如您所見,它們彼此對應。因此,一個核可以轉換成另一個核。但是,「擊中與錯過」只會找到前景與背景差異明確的完美精確匹配。因此,與「相關」相比,它對噪聲和近似匹配的容忍度要低得多。另一方面,「相關」可以使用線性圖像處理來執行,更具體地說,可以使用快速傅立葉變換。這可以使使用較大模式和核的模式匹配速度更快,尤其是在涉及多個模式時,可以節省將圖像和模式轉換到頻域的成本。它也適用於實際圖像,但可能也需要一些預處理和使用HDRI。您使用哪一個取決於您自己,以及您追求的結果。僅限完美匹配,或包含更多錯誤的近似匹配,以及可能使用更快的算法。請注意,為了在較大圖像中找到小的彩色圖像的精確匹配,「magick compare」程序的子圖像定位功能將提供比「擊中與錯過」或「相關」方法更好的方法。這是因為它使用「顏色向量差異的最小平方」來進行子圖像匹配,這可以為匹配結果產生更好的指標。但是,它同樣很慢,尤其是對於大型圖像。

鄰居計數

卷積可以應用於更不尋常的事情之一被稱為鄰居計數。也就是說,計算出圖像中每個像素點周圍特定區域中存在的像素數量。

計算相鄰像素

基本上,通過使用非常簡單的卷積核,您可以創建一個圖像,其中包含二值圖像中特定點周圍的鄰居數量計數。通過使用大小為「1.5」的環形核進行卷積,您將獲得鄰居計數。以下是一個小區域中每個像素的鄰居計數,並顯示了之前和之後的單個像素的放大圖(使用放大圖像腳本生成)...

  magick area.gif -define convolve:scale=\! \
         -morphology Convolve Ring:1.5 neighbour.gif
[IM Output] ==> [IM Output]
如您所見,所有像素的灰度級都顯示了它們有多少個鄰居,包括沿著邊緣的任何虛擬像素鄰居。如果要在計數中包含當前像素,則可以使用方形核。通過適當的轉換(包括級別調整)並使用PbmPlus 文件格式,您可以將上述灰度級轉換為實際數字(如果需要)。

  magick neighbour.gif +depth +level 0,8 pgm: | pnmnoraw | tail -n +4
[IM Text]
如果要排除實際形狀內部的像素,可以使用中心像素為強負值的核,然後鉗制任何負結果(如果您使用的是IM 的 HDRI 版本)。生成一個由正 1 包圍的大的負中心核的簡單方法是負向縮放標準的離散拉普拉斯核

  magick area.gif -define convolve:scale=-1\! \
         -morphology Convolve Laplacian:0 -clamp neigh_edge.gif
[IM Output] ==> [IM Output]
當然,我們也可以使用原始圖像作為遮罩來移除不感興趣的像素。

生命遊戲

1970 年,英國數學家約翰·何頓·康威在《科學美國人》雜誌上發表了一項特殊的模擬,該模擬迅速流行起來。它現在被稱為康威的生命遊戲。它基於一個點網格,其中每個點要么是「活著」的,要么是「死的」。然後,根據一組非常簡單的規則,僅基於周圍活著的鄰居細胞的數量,將哪些「細胞」歸類為下一「代」中的「活著」或「死的」。
  • 鄰域是每個「細胞」周圍的 8 個像素。
  • 如果一個「活」細胞有 2 個或 3 個鄰居,它將繼續存活。
  • 如果一個「死亡」的細胞周圍正好有 3 個「活著」的細胞,它就會變成「活著」的(誕生)。
  • 否則,該細胞會變成或保持「死亡」狀態。
這些規則在二進制模式上的結果非常顯著,你會得到一組「細胞」,它們似乎會擴張、收縮、振盪,甚至在網格上緩慢移動。這成為理論研究的一個重點,看看是否可以產生「DNA」風格的更大「生命模式」的複製。題外話:這似乎是可能的,但它非常脆弱,不切實際,這使得當前的 DNA 生命更加非凡。它也引發了人們對研究和實現其他形式的細胞自動機的濃厚興趣,作為一種在非常小的尺度上使用非常簡單的規則來產生和研究大規模效應的方法。很像在原子和分子層面的化學中發生的情況,但複雜性更高。所以讓我們使用 ImageMagick 來實現「生命遊戲」。首先,為了使事情變得簡單,我們將「活著」的細胞設為白色,「死亡」的細胞設為黑色。這樣我們只需計算每個細胞周圍 8 個像素鄰域中的「白色」像素。但是,我們也可以將黑白交換來實現,儘管這樣做會更難以理解它是如何完成的。然而,這些規則很大程度上取決於中心細胞是活著還是死亡。因此,我們需要將「死亡」細胞的鄰居計數與「活著」細胞的鄰居計數分開。這可以通過給中心細胞一個比所有鄰居的總和大得多的值來簡單地完成。值「10」很適合這個目的。它是一個很好的整數,大於最大鄰居計數 8。這使得「生命遊戲」卷積核等價於..

    '3: 1,  1,  1     
        1, 10,  1
        1,  1,  1'
其結果將是每個像素周圍 8 個鄰居的計數(如果是「白色」),如果中心像素是「活著」或「白色」,則加上值 10。因此,對於「死亡」像素,此內核的值將為「0」到「8」,對於「活著」像素,此內核的值將為「10」到「18」。如果我們將此內核縮放 20 倍(實際上是縮放「0.05」以生成漸變,見下文),您將生成具有 21 個可能灰度的圖像。也就是說,對於「0」灰度級,您將獲得「黑色」值,對於「21」灰度級,您將獲得白色值,而不是內核實際上可以生成這樣的值。現在,我們可以將「生命遊戲」規則編碼到顏色查找表圖像中,以便根據「生命規則」將上述內核生成的相鄰計數「灰度級」轉換為適當的「生與死」結果。

  magick -size 21x1 xc:black -fill white \
          -draw 'point 3,0  point 12,0  point 13,0' \
          life_clut.gif
  enlarge_image -25.3 -ml 'Life Rules' life_clut.gif life_clut_enlarged.png
[IM Output]
圖片非常小,所以我使用了放大圖片腳本生成了一個更大的版本顯示在上方,每個像素都清晰可辨。基本上,前 10 個像素表示對「死細胞」的操作,後 10 個像素表示對「活細胞」的操作。左側第一個白色像素(死細胞周圍鄰居數量 = 3)表示「誕生」,而右側的兩個白色像素(活細胞旁邊的鄰居數量為 2 和 3)允許現有的「活細胞」繼續存活。任何其他結果都會使結果為黑色(死亡)。顏色查找表長度為 21 個像素,因為我將除以縮放因子 20,這意味著我們可以生成 0 到 20 範圍內的值,或 21 個不同的灰度級別。我們實際上可以使用與中心(細胞先前狀態)的 10 和縮放的 20 不同的值,但這些值很容易處理。總之,我們將卷積核除以 20,並使用 21 個像素長的 CLUT(帶有整數插值)來將卷積結果(灰度級)與正確的輸出顏色值相匹配。旁白:這個「生命規則」CLUT 可以被視為一個通用的細胞自動機規則表。用於鄰居計數的鄰域模式也是細胞自動機的一部分。這種技術也在細胞自動機規則詞典規則表部分中概述,作為定義其列出的細胞自動機的一般「無限制」形式的一種方式。基本上,幾乎任何自動機都可以使用這種鄰域/表格組合來定義,儘管大多數自動機都是使用更簡化的形式定義的。因此,讓我們將其應用於包含「生命」模式的圖像,多次應用以查看模式如何從一代變為下一代,並檢查其是否按預期工作。

  magick -size 15x15 xc:black -fill white \
         -draw 'line  3,2 3,4  line 10,10 12,10  point 10,11  point 11,12' \
         life_gen_000.gif
  magick life_gen_000.gif -define convolve:scale=0.05 \
         -morphology Convolve '3:1,1,1 1,10,1 1,1,1' \
         life_clut.gif -interpolate integer -clut \
         life_gen_001.gif
  magick life_gen_001.gif -define convolve:scale=0.05 \
         -morphology Convolve '3:1,1,1 1,10,1 1,1,1' \
         life_clut.gif -interpolate integer -clut \
         life_gen_002.gif
  magick life_gen_002.gif -define convolve:scale=0.05 \
         -morphology Convolve '3:1,1,1 1,10,1 1,1,1' \
         life_clut.gif -interpolate integer -clut \
         life_gen_003.gif
  magick life_gen_003.gif -define convolve:scale=0.05 \
         -morphology Convolve '3:1,1,1 1,10,1 1,1,1' \
         life_clut.gif -interpolate integer -clut \
         life_gen_004.gif
[IM Output] ==> [IM Output] ==> [IM Output] ==> [IM Output] ==> [IM Output]
請記住,上面的圖像已被放大,要查看生成的原始「微小」圖像,請單擊放大的圖像。如您所見,「生命」模式的行為符合預期(如果您熟悉這些模式)。左上角的「閃爍器」來回翻轉,而底部的「滑翔機」在我們迭代生命規則的 4「代」中朝著它移動了 1 個對角線步。[IM Output]這裡是一個更大的例子,稱為高斯帕滑翔機槍,我從一個特殊的生命模式生成了 60 幀的動畫。正在使用的圖像的實際大小顯示在右側,但我縮放了生成的動畫以便於觀看。

  magick glider_gun.gif life_pattern.gif
  for i in `seq 59`; do
    magick life_pattern.gif -define convolve:scale=0.05 \
           -morphology Convolve '3:1,1,1 1,10,1 1,1,1' \
           life_clut.gif -interpolate integer -clut \
           -write life_pattern.gif miff:-
  done | magick - -scale 500% \
                -set delay 10 -layers Optimize -loop 0  glider_gun_anim.gif
  magick glider_gun.gif -scale 500% life_pattern.gif
[IM Output] ==> [IM Output]
請注意,滑翔機在底部邊緣「爆炸」的原因是卷積使用的默認「虛擬像素」處理,以及生命信息超出圖像邊界時的丟失。更多生命模式圖像可以在生命模式目錄中找到,儘管您需要重新著色(反轉)圖像以在上述生命處理器中使用。我將把它作為一個練習留給某人,將上述內容放入一個腳本中,該腳本可以為某些特定輸入圖像生成一個生命序列。
這僅僅是 IM 可以處理的「*細胞自動機*」的眾多例子之一。當然,還有許多針對「生命」和「細胞自動機」的更快專用程序,它們通常做完全相同的事情,但我想表明 IM 也足夠靈活地做到這一點。由於結果是簡單的二進制圖像,您還可以使用 IM 的形態學方法,例如命中和未命中模式搜索互相關來搜索特定的生命模式,從而使使用 IM 進行生命研究更加實用,儘管速度較慢。