ImageMagick 範例 —
影像卷積
- 索引
-
ImageMagick 範例 前言與索引
-
卷積簡介
-
影像模糊化(低通濾波)
- 模糊化內核
- 高斯 vs 模糊內核
- 柔化模糊(與原始影像混合)
- 使用模糊 '反銳化' 影像(從原始影像中減去)
-
邊緣偵測卷積(高通濾波)
- 邊緣偵測內核
- 使用邊緣偵測銳化影像(增強原始影像的邊緣)
-
方向性卷積(斜率、羅盤濾波)
-
相關性
- 卷積 vs 相關性(非對稱內核效應)
- 相關性和形狀搜尋
- 相關性 vs 命中與遺漏
-
相鄰像素計數
卷積簡介
「Convolve
」方法以及與其密切相關的「Correlate
」方法,在許多方面與形態學非常相似。事實上,它們的工作方式幾乎完全相同,在每個位置匹配一個鄰域「核心」,使其成為形態學的另一種特殊「方法」。事實上,它們也使用了許多相同的程式碼,甚至與基本核心和使用者自訂核心中定義的相同核心定義。如需專為此運算子設計的更具體核心(有很多),請參閱模糊核心和邊緣偵測核心。最重要的核心是「高斯
」核心。但是,卷積比形態學歷史更悠久,它產生更多灰階漸變效果,而不是形態學通常產生的二元形狀研究效果。這就是為什麼它經常被認為是一種與形態學截然不同或獨立的運算,並且是影像處理中更核心的運算。基本上,卷積或相關性會對指定鄰域中的所有像素執行「加權平均」。也就是說,它將附近每個像素的值乘以核心給定的數量,然後將所有這些值加總在一起以產生最終結果。因此,最終影像中的每個像素通常至少包含原始影像中局部環繞它的所有其他像素的一小部分。換個角度來看,影像中每個像素的顏色將根據所使用的核心,被添加到(模糊)或減去(銳化/邊緣偵測)其所有鄰近像素的顏色。「卷積」和「相關性」是相同的運算,只有一個非常微小但重要的區別,對於我們現在將看到的示例和控件,您可以將它們視為基本相同。稍後(請參閱卷積與相關性),我們將仔細研究這兩個運算子的真正區別,以及為什麼它們的區別如此微小。但在大多數情況下,它們是相同的方法。卷積 (
)
如上所述,「Convolve
」方法的工作原理是根據核心中的浮點值對局部鄰域中的每個像素進行加權。然後將加權值簡單地加總在一起,以在結果影像中產生新的替換像素。例如,讓我們使用一個非常小的使用者自訂卷積核心來卷積單個像素。我還設定了特殊的顯示核心設定,因此您可以看到正在定義和使用的核心的詳細資訊(顯示的影像已放大)。
|
![]() |
![[IM Output]](pixel_mag.gif)

![[IM Output]](kernel_spread.gif)

![[IM Output]](pixel_spread_mag.gif)
0.5
」值加權,並將生成的「半亮」像素添加到生成的圖像中。類似地,當內核的原點精確定位在原始像素上時,它將獲得「1.0
」的值,從而複製原始像素,並且周圍沒有其他值(黑色)添加任何分量到結果。請注意,任何「0.0
」的內核值都不會參與最終計算。零值實際上不是「鄰域」的一部分,就像形態學內核中的任何「Nan
」值都不會參與一樣。因此,此內核由 5 個元素鄰域組成。在許多方面,「卷積
」方法與形態學「膨脹
」方法非常相似,但是「膨脹
」僅將內核視為一種位圖遮罩,定位鄰域內的最大值。另一方面,「卷積
」是鄰域中所有值的加權和,因此每個內核元素的值都對整體結果起作用。卷積運算的語法是...-morphology Convolve {convolution_kernel}
-convolve {convolution_kernel}
![]() ![]() |
在 IM v6.5.9 之前,舊的「-convolve 」不理解形態學內核定義。它只接受「舊樣式」的使用者定義內核,僅包含一個由逗號分隔的值組成的字串,以生成一些奇數大小的方形內核。它現在將接受「新樣式」的卷積內核定義。但是它仍然限於「奇數大小」的方形內核。並且將保持這種狀態,直到它開始使用新的「形態學」卷積方法。 |
![]() ![]() |
舊的「-convolve 」運算符與較新的形態學「卷積 」方法並不完全相同。以下是兩個操作的不同之處的列表...
最終,隨著與更新的形態學「 Convolve 」方法的合併,上述大部分差異將會發生變化。 |
Convolve
」實際運作方式的一些絕佳範例,我建議您也查看 EECE \ CS 253 影像處理,第 7 講,空間卷積。 維基百科,卷積 文章中有一些關於卷積過程的精美 1D 動畫。 卷積核缩放
上述範例適用於大部分為黑色的影像(例如單一像素),但如果您將其應用於真實影像,則會遇到問題...
|
![[IM Output]](../images/face.png)

![[IM Output]](kernel_spread.gif)

![[IM Output]](face_spread.png)
0.5
」,再加上原始像素的完整副本。也就是說,核心中的所有值的總和為 3,這使得產生的影像亮了三倍!如果您回頭查看上面的「showKernel」輸出,您將會看到它將此核心列為「卷積輸出範圍從 0 到 3」。這表明此核心通常會使影像變亮 3 倍。要解決此問題,您需要將核心中的所有值除以 3。也就是說,「0.5
」的值實際上應該是「0.1667
」左右,而「1.0
」的中心值應該是「0.3333
」。此過程稱為「核心正規化」。例如,以下是手動「正規化」的結果以及核心定義...
|
![]() |
![[IM Output]](../images/face.png)

![[IM Output]](kernel_spread_norm.gif)

![[IM Output]](face_spread_norm.png)
![]() ![]() |
上面顯示的「核心影像」(使用特殊的 核心轉影像腳本 生成)也顯示了產生的正規化核心。正如您所見,核心本身現在非常暗,因為它的所有值也很暗,儘管它們加起來的值為「1.0 」。從現在開始,所有顯示的卷積核心影像都將始終進行調整,以便將最大值設為白色,否則您通常會看到的是一張黑暗且基本上無用的「核心影像」。 |
-define convolve:scale={kernel_scale}
」允許您為核心指定全局縮放係數,從而調整整體結果的亮度。
|
![]() |
內核歸一化(自動縮放)
您可以簡單地要求 IM 通過為其提供特殊的“!
”歸一化標誌,在內部計算出這個“歸一化比例因子”,而不是計算出比例因子(如上所述)。
|
![]() |
![]() ![]() |
“! ”字符有時也被各種 UNIX 命令行 shell 用於特殊目的。 因此,即使在引號中,您也可能必須使用反斜杠來轉義字符。 建議謹慎使用。 |
-convolve
”變體將自動執行此歸一化。 您可以讓 IM 對內核進行歸一化,然後再次按給定量進一步縮放它以調整其輸出範圍。 為了更容易,您可以將縮放因子指定為百分比。 例如,在這裡我對內核進行了歸一化,但隨後將值重新縮放到計算大小的 50%,以便產生更暗的結果。
|
![]() |
!
”實際上等同於使用“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/3
”或 3 的任何其他分數因子指定為精確的浮點十進制數。 - 數學曲線被內核大小(半徑)“剪裁”,因此它可能不再是零和。 例如,這發生在基於無限響應曲線的“
LoG
”或“DoG
”內核中。 出於這個原因,IM 實際上在這些內核上內部使用了這種特殊的歸一化。 - 確保 相關性“形狀蒙版”為零和,以便在搜索中,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 |
0 | -0.125 | 0 |
---|---|---|
-0.125 | 0.5 | -0.125 |
0 | -0.125 | 0 |
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'
-bias
",您仍然可以保留正負結果。非 HDRI 版本 IM 的設定是...
-define convolve:scale=50%\! -bias 50% |
-1.0
',白色將代表 '+1.0
'。在下面的 相關形狀搜索 示例中顯示了一個這樣做的示例。模糊圖像(低通濾波)
IM 示例的另一部分,特別是 模糊和銳化圖像,實際上處理了這個主題的實際方面。在這裡,我們將查看更具體的細節。但是,我們首先將描述基本內核以及如何在不修改的情況下直接使用它們。稍後我們將研究修改模糊以產生其他效果的方法。模糊化內核
![[IM Output]](kernel_unity.gif)
統一
這是一個實際上什麼都不做的特殊內核。只指定了一個內核元素,因此每個像素都被自身替換而沒有變化。例如,這裡是一個無操作 卷積...從 IM v 6.6.9-4 開始,內核可以採用單個參數,作為特定於內核的比例參數。這允許您使用它來乘以圖像的值,例如使圖像變亮或變暗。
|
![]() |
Disk:0.5
' 生成相同的單元素內核,這也允許您指定一個額外的縮放參數作為內核生成的一部分。(例如:最後一個示例為 'Disk:0.5,0.5
')。類似的內核(用於 卷積)也可以由 'sigma' 為 '0.0
' 的 '高斯
' 內核生成器生成。但是,這只能產生一個小的 3x3 內核,它由一個被 8 個 '0.0
' 值包圍的中心 '1.0
' 值組成。
![[IM Output]](kernel_shape.gif)
使用形狀內核進行均值或平均濾波
雖然下面定義的大多數卷積內核通常都以某種方式使用高斯曲線,但您仍然可以使用之前的形態學形狀內核之一來簡單地對給定(大)區域內的像素求平均值。當然,您需要標準化內核,以便實際生成平均值,而不僅僅是鄰域的總和。例如,這裡我使用一個較小的“八邊形
”形狀的內核,來平均每個像素周圍圓形區域內的所有像素值。結果是每個像素的值在定義的鄰域中的所有 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]](shape.png)

![[IM Output]](shape_mean_square.png)
![[IM Output]](shape_mean_disk.png)
-blur 5x65535
來實現。這在形態學可用之前,Fred Wienhaus 在他的腳本中經常使用這種方法。
![[IM Output]](kernel_gaussian.gif)
高斯內核(二維高斯模糊)
您可能已經了解到,“高斯
”內核是用於對圖像進行卷積的最常用內核。這是用於模糊效果的數學理想內核。例如,這裡是一個小型“高斯
”內核的顯示內核(它們可以很快變得非常大)...我實際上並不想對上面應用卷積,因為我只想顯示它要使用的內核。因此,我使用了“:0
”迭代次數,所以它什麼也不做。類似地,我使用特殊的“null:
”文件格式丟棄生成的圖像輸出。正如您從卷積輸出範圍中看到的那樣,“高斯
”內核已經為您進行了標準化(縮放)。但是,您還會注意到它仍然是一個相當大的內核,充滿了小的分數值。如果您仔細觀察,您會發現最大值(2.48678,也在第一行列出)位於中心,最小值朝向邊緣和角落(值約為 .000000194)。以下是使用卷積的典型高斯模糊...內核語法非常簡單...
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]](kernel_blur.gif)
模糊核心(一維高斯模糊)
「模糊
」核心與高斯核心非常相似,甚至採用相同的參數(見下文)。但是,高斯是一個二維曲線,「模糊
」核心產生一個一維曲線。也就是說,它生成一長串單行值。以下是小型「模糊
」核心的顯示核心輸出。
|
![]() |
||
|
模糊
」核心的實際輪廓。它是使用核心圖像腳本「kernel2image
」創建的,然後使用「im_profile
」腳本繪製該圖像。它清楚地顯示了該核心代表的「高斯鐘形曲線」。以下是如何使用此核心水平模糊圖像的示例。
|
![]() |
高斯
」完全相同,但帶有一個額外的可選旋轉角度。
Blur:[{radius}]x{sigma}[,{angle}] |
單位
」核心的線性等效值。「角度」允許您將核心旋轉 90 度,從而可以垂直模糊圖像。
|
![]() |
高斯
」核心產生的二維圖像模糊更快的形式。有關如何做到這一點的詳細信息,請參閱下面的高斯與模糊核心。
![[IM Output]](kernel_comet.gif)
彗星核心(半一維高斯模糊)
「彗星
」核心幾乎與「模糊
」核心完全相同,但實際上只是半個模糊核心。請注意,原點的定義位置是如何在左邊緣,而不是在核心的中心。這對於卷積核心來說非常不尋常,因此會產生非常不尋常的結果。它會沿一個方向模糊圖像,就像手指塗抹了濕繪畫的表面,留下了一條顏色軌跡。它有點像彗星的尾巴,或者流星或流星留下的軌跡。
|
![]() |
|
![]() |
![[IM 輸出]](kernel_blur_profile.gif)
高斯 vs 模糊內核
如前所述,「高斯
」和「模糊
」內核密切相關,實際上可以完成相同的工作。兩者都是 高斯曲線 的表示,第一個是二維表示,而另一個是一維表示。例如,這裡重複「-gaussian-blur 0x2
」,它等效於「-morphology Convolve Gaussian:0x2
」運算。
|
![]() |
|
![]() |
|
>
」執行 90 度旋轉列表(在這種情況下為兩個內核),要求 IM 將一個內核展開為 旋轉內核列表,從而進一步簡化上述內容。例如...
magick face.png -morphology Convolve 'Blur:0x2>' face_blur_x2.png |
以上所有範例都是等效的,這就是「-blur 」運算子的工作原理。
|
![]() |
-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]](../images/face.png)

![[IM Output]](face_strong_blur.png)

![[IM Output]](face_soft_blur.png)
混合
」合成方法,將「60%
」的模糊圖像(合成源圖像)與「40%
」的原始圖像(合成目標圖像)混合,以在最終圖像上產生「柔化模糊」效果。但是,您可以通過使用相同的比率 將內核與恆等內核混合 來直接執行相同的操作。
|
![]() |
60%
」)會縮放給定的內核,以減少其對輸出的影響,而第二個數字(「40%
」)會加入足夠的「Unity
」(或「Identity」)內核,以防止結果變暗。重點是,對於模糊內核,這兩個數字加起來等於「100%
」,就像合成混合一樣。您也可以使用更快的兩次通過模糊,但在這種情況下,我們無法將「混合」直接合併到內核中,因為兩個獨立的卷積不會「乾淨地」分離。因此,我們需要在之後再次執行混合合成。
|
![]() |
100
」的值將給出模糊的圖像,而「0
」將給出原始圖像。![]() ![]() |
請記住,「-blur 」運算符與使用更快的兩次通過模糊內核完全相同。 |
使用模糊「銳化」圖像(從原始圖像中減去)
通過進一步混合內核,以便開始使用負縮放,您可以從原始圖像中減去模糊效果。結果是一種稱為「銳化」的技術。有關其如何獲得如此不幸的名稱,請參閱Unsharp, Wikipedia。
|
![]() |
100%
」,與上面的完全相同。您也可以使用合成混合來做到這一點。上面的示例實際上是錯誤命名的「-sharpen
」運算符的工作原理,但只有「sigma」模糊控制。但是,沒有提供對操作的其他控制。混合與上面給出的完全相同。您可以使用更快的兩次通過、一維模糊內核,但同樣需要將混合操作作為單獨的步驟執行。
|
![]() |
|
![]() |
-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]](shapes.gif)

![[IM Output]](shapes_sobel.gif)
索貝爾
」內核定義)。但是它只找到了一組邊緣,即「正」的從左到右的黑到白的斜坡。要獲得「負」斜坡,您需要使用內核縮放設置來否定內核。例如...
|
![]() |
索貝爾
」內核,您也可以將其旋轉 180 度以獲得與「尺度否定」相同的結果,但並非所有內核都以這種方式對稱。另一種解決方案是向結果添加輸出偏差。也就是說,向生成的圖像添加 50% 的灰色,以便負值比這個值淺,而正值比這個值亮。但是,您還需要縮放內核,以確保結果保持在圖像的「黑色」和「白色」限制內「未裁剪」。
|
![]() |
|
![]() |
Sobel
」核心。除了使用輸出偏差之外,另一個選擇是建置 Imagemagick 的特殊HDRI版本。這會使用浮點值將圖像儲存在記憶體中,這表示圖像值不會因為使用整數而被「裁剪」或「捨入」。但是,即使您確實使用這個特殊版本的 IM,您仍然需要在儲存到一般圖像檔案格式之前對結果進行後處理,或者您需要使用特殊的啟用浮點數的圖像檔案格式。但是,您不需要擔心中間圖像結果中的裁剪或捨入效應,從而使事情更容易處理。邊緣偵測核心
![[IM Output]](kernel_log.gif)
LoG:高斯差分
LoG:{radius},{sigma} |
LoG
」或「高斯差分」是您可以獲得的最佳邊緣偵測核心之一。它也被稱為「墨西哥帽」核心。基本上,它是一個「拉普拉斯
」微分(斜率)運算器,它已經通過添加高斯模糊進行了平滑處理。這反過來又消除了圖像中大部分的雜訊影響,這可以通過「sigma」設定進行調整。核心包含負值,這些負值在強中心峰值周圍形成環。在上面顯示的「核心圖像」中,負值顯示為深色(接近黑色),邊緣向邊緣衰減為零(深灰色)。這是它的效果。顯示它如何突出顯示圖像的邊緣。拉普拉斯核心是無方向性的,但在邊緣的任一側都會產生正負脊值。要定位邊緣,您需要尋找正負脊之間的零交叉點,這是一種稱為Marr 和 Hildreth 邊緣偵測的技術。這個核心也是銳化圖像的理想選擇。![[IM Output]](kernel_dog.gif)
DoG:高斯差
DoG:{radius},{sigma1}[,{sigma2}] |
DoG
」或「高斯差」核心,其中從「sigma1」產生的高斯中減去「sigma2」產生的高斯。通常,「sigma2」較大,因此核心的「中心峰值」為正。反轉這兩個數字實際上會使產生的核心無效。對高斯差分的主要批評之一是它難以實現,因為它是一種非常不尋常的數學曲線。它也不是一條有充分文獻記載的曲線。另一個方面是,它不能像高斯那樣「分離」成更快的 2 通解決方案(請參閱高斯與模糊核心)。但是,通過產生兩個sigma值略有不同的「高斯
」核心(比例約為 1.6),並將它們彼此相減,您實際上可以產生高斯差分的近似值。結果是「DoG
」比「LoG
」核心更容易在硬體中產生。例如,在這裡,我將「LoG
」和「DoG
」核心的核心圖像並排放置以進行比較。如果您查看高斯差,維基百科網頁,您將看到一些圖表,他們還將「LoG
」(或「墨西哥帽」)的輪廓與「DoG
」進行了比較,顯示出匹配曲線之間的差異非常小。需要更多關於如何映射 LoG 的 sigma 以產生接近等效的「DoG」的信息。如果您知道,請通過頁腳中的地址給我發送郵件。應用結果也非常相似。
|
![]() |
請注意,兩個「sigma」值都應該被定義,並且至少有一個應該是非零的。任一 sigma 分量的零值將等效於「Unity 」核心,這意味著它會保持圖像不變。如果兩個值都為零,則兩個高斯函數將是「Unity 」核心,相減將產生完全為零或黑色的結果(加上任何偏差值)。當參數為「Dog:0,0,非零 」時,DoG 將變為一個簡單的高通濾波器,它被定義為「Unity」核心(產生原始圖像)減去一個低通濾波器核心(模糊圖像)。在這種情況下,sigma1=0 只是「Unity」核心,而 sigma2=非零 是一個高斯低通(模糊)濾波器核心。因此,以下將產生一個濾波器值為 sigma2=2 的高通濾波圖像。
|
![]() |
DoG:0,2,0
」將返回一個圖像,該圖像基本上是先前圖像的負片版本(圍繞輸出偏差)。此技術還可以用於生成 3x3 的「各向同性拉普拉斯」核心,這意味著「拉普拉斯
」核心在所有方向上產生相等的結果,而不是具有不相等的對角線偏差。例如,半徑=1(對於 3x3 核心)和 sigma 為 1 將生成...
|
![]() |
||
|
-blur
」運算符(它在內部使用「Blur
」核心)來生成相同的結果。但是,要做到這一點,您需要分別生成兩個「模糊」圖像,然後減去結果,並添加適當的縮放比例和偏差。例如...
|
![]() |
4
」)。這是因為減去兩個歸一化模糊不會產生與在「DoG
」核心將兩個減去的高斯曲線一起歸一化時相同的(增加的)結果幅度。但是,除了幅度之外,上面的示例圖像等效於第一個「DoG
」核心的結果,只是生成速度更快,尤其是在 sigma 值較大的情況下。這就是重點,即使工作量更大,這種複雜的方法也比直接使用「DoG
」或「LoG
」核心更快。離散拉普拉斯核心
Laplacian:{type} |
LoG
」運算核計算的,但經過縮放以在小型運算核陣列中使用離散整數值。這使您可以使用生成的專用快速影像濾波器,這些濾波器僅使用整數數學來處理影像數據。然而,ImageMagick 是一個更通用的影像處理器,因此不提供這種超快速的專用濾波器。但是人們喜歡使用它們,因為它們更容易理解,所以其中許多已經內建到 IM 中。這裡提供的運算核都不能旋轉,而且大多數是「各向異性」的,這意味著它們不是完美的圓形,尤其是在對角線方向上。但是,請參閱上一節(「DoG
」運算核)瞭解生成真正的「各向同性 3x3 拉普拉斯運算核」的方法。前兩個「Laplacian:0
」和「Laplacian:1
」運算核是「離散拉普拉斯運算核」最常用的形式。它們非常小,這意味著它們可以非常準確地定位邊緣,但也容易增強影像雜訊。請注意,並非所有「類型」編號都已定義,為將來定義更多離散運算核留下了空間。使用的數字經過選擇,以便更好地匹配該數字定義的運算核。 Laplacian:0
(預設)
8 鄰域拉普拉斯運算器。可能是最常見的離散拉普拉斯邊緣檢測運算核。在這裡,我使用顯示運算核提取「離散」和「未歸一化」的運算核,然後向您展示帶有輸出偏差的歸一化運算核的結果。LoG
」或「DoG
」,拉普拉斯運算器產生的結果都比預期的要複雜。在這種情況下,生成無偏差的影像(没有任何輸出偏差)會更好。所以讓我們重複上面的步驟,但不帶偏差,以便只保留較亮的「正」邊緣。
|
![]() |
|
![]() |
Laplacian:1
4 鄰域拉普拉斯運算器。也很常用。
|
![]() |
||
|
Laplacian:2
3x3 拉普拉斯運算器,中心:4 邊緣:1 角落:-2
|
![]() |
||
|
Laplacian:3
3x3 拉普拉斯運算器,中心:4 邊緣:-2 角落:1
|
![]() |
||
|
Laplacian:5
5x5 拉普拉斯運算器
|
![]() |
||
|
Laplacian:7
7x7 拉普拉斯運算器
|
![]() |
||
|
Laplacian:15
離散 5x5 LoG(Sigma 約為 1.4)
|
![]() |
||
|
Laplacian:19
一個離散的 9x9 LoG(Sigma 約為 1.4)
|
![]() |
||
|
透過邊緣偵測銳化影像(增強原始影像的邊緣)
「LoG
」和「DoG
」核心除了可用於使用模糊來反銳化影像之外,也可以用於銳化影像。基本上,您需要做的就是將核心結果(包括負值結果)加到原始影像中。若要執行此操作,只需將加權 100% 的「Unity
」或「Identity」核心加到比例因子即可。這就是提供它的原因。例如...
|
![]() |
與反銳化技術產生的結果(結果顯示在右側)相比,這是對影像進行更廣泛、更平滑的銳化。也就是說,因為它是對影像進行實際的真正銳化,而不是透過減去模糊來偽造的。 |
![]() |
例如,銳利度較低...
|
![]() |
或者更銳利...
|
![]() |
方向性捲積(斜率和羅盤)
與上述類似,這些核心會尋找影像顏色強度的斜率,但這些核心不是尋找任何斜率,而是尋找特定方向的斜率。在數學上,這稱為「導數」,它實際上只是「斜率」的另一種說法。但了解不同方向的斜率資訊也可以作為一種方法,您可以藉此確定斜率或影像邊緣的角度或「羅盤」方向。也就是說,影像中某個特定點的斜率的二維方向。斜率也用於稱為影像「浮雕」和「陰影」的影像處理技術中。目前沒有可用的「生成」核心,只有「命名」的預定義核心,例如Sobel 和Roberts。但是,我確信浮雕和陰影核心生成函數將在未來的某個時候移入形態/捲積核心集中。因此,讓我們來看看一些「命名」的方向性核心。方向性內核
Sobel
我們在上面討論零和核心時已經見過「Sobel」核心。此核心是一個原始方向性(一階導數)核心,設計用於透過「
Sobel:{angle}![]()
convolve
」運算傳回某個特定正交方向上的邊緣斜率。根據預設,它設計用於透過「捲積
」運算進行從左到右的斜率偵測。結果本質上是影像的 X 導數(斜率)。
|
![[IM Output]](slope_positive.gif)

![[IM Output]](kernel_sobel.gif)

![[IM Output]](slope_sobel.gif)
![]() ![]() |
如果您查看核心,您可能會認為它被反向宣告了。從某種意義上說,您實際上是正確的。然而,這是由於「捲積」實際上的運作方式。 您可以在下面的捲積與相關中更詳細地了解這種「反轉」。 |
50%
」的偏差,否則無法看到。雖然在上一個範例中沒有負斜率,但下一個範例中有一個負斜率,因此我還添加了一個偏差設定,以便您可以看到它。
|
![[IM Output]](slope_both.gif)

![[IM Output]](kernel_sobel.gif)

![[IM Output]](slope_sobel_bias.gif)
![]() ![]() |
如果您將此核心與「Correlate 」一起使用,您會發現斜率「匹配」核心定義的方式。在這種情況下,您會得到一個從左邊高(白色值)到右邊低(黑色值)的斜率的正結果。在上面的例子中,這兩條線將被交換。然而,上面是「卷積」,而不是「相關」(意思是匹配核心)。有關差異的更多細節,請再次參閱卷積與相關。 |
Sobel
」核心在人臉圖像上的結果。請注意,Sobel 和大多數其他邊緣檢測核心傾向於沿著非常強的邊緣產生 2 個像素厚的響應,以及在單個像素寬的線上產生 3 個像素厚的響應。這比拉普拉斯邊緣檢測器強得多。您可以使用「角度」參數旋轉此核心,通常以 90 度的倍數旋轉。但是,您也可以將其旋轉 45 度的倍數,即使它並非為此而設計。這對於從所有 45 度旋轉導數結果的最大值中獲得 45 度量化的方向導數或梯度大小非常有用。它又來了,但旋轉了 90 度(從上到下)。
|
![]() |
使用「
Sobel
」核心收集圖像所有邊緣的一種方法是在所有方向上應用 4 次核心,並收集看到最大值(使用亮化數學合成。這是對梯度大小的近似值。
|
![]() |
Sobel
」核心的所有 90 度旋轉的旋轉列表。
|
![]() |
|
![]() |
|
![]() |
![]() ![]() |
上述使用中的「-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]](shapes.gif)

![[IM Output]](face_sobel_direction.png)
-fx
" 表達式使用 'atan()' 函數將 X,Y 向量轉換為角度。然後使用外部的 彩虹漸層影像 為其著色,作為 顏色查找表。第二個 "-fx
" 表達式建立一個閾值透明遮罩,使任何沒有斜率的區域變為透明。然而,上述技術往往會對真實影像產生大量混亂的信息,因為它沒有考慮到斜率的大小。以下是一個更複雜的版本。它幾乎在綠色 'G' 通道中進行所有計算,以便將所需的影像處理量減少三分之一。然後它使用 HSB 色彩空間來建立方向(色相)和大小(亮度)。
|
![]() |
Roberts
'
Roberts:{angle}![]()
Roberts
' 核心比之前的 'Sobel
' 核心簡單得多,並且會產生更精確的邊緣位置(低至 2 個像素)。當然,這也使其更容易受到雜訊影響。通常,這個核心由一個小得多的 2x1 甚至 2x2 核心表示,但是通過將其實現為一個 3x3 核心,我可以以 45 度的增量“循環”旋轉核心。例如,以下是一個 45 度的結果,更常見的名稱是“Roberts-Cross”核心。
|
![]() |
Sobel
' 一樣,您也可以使用 多核心處理 從所有方向生成最大斜率。但是這一次我們將獲得 8 x 45 度的方向,而不仅仅是 4 個。
|
![]() |
Sobel
' 那樣簡單地合併一半數量的卷積。基本上,僅由一個 'Roberts
' 卷積生成的斜率偏離實際影像對齊半個像素。也就是說,計算出的斜率位於像素之間的 '+1
' 和 '-1
' 值之間的點,但存儲在中心的 '-1
' 像素中。然而,這也意味著通過保存像素周圍的所有斜率並將它們加在一起,您可以獲得一個小得多的銳利邊緣檢測,只有 2 個像素(而不是 4 個像素)突出顯示銳利的邊緣邊界。 Prewitt
Prewitt:{angle}![]()
'Prewitt ' 核心與 'Sobel ' 非常相似,但在特定邊緣檢測的確切方向上要鬆散得多。因此結果會更加模糊。
|
![]() |
Compass
Compass:{angle}![]()
這是“Prewitt Compass”核心,據說它比 'Sobel ' 具有更強的方向感。
|
![]() |
Kirsch
Kirsch:{angle}![]()
這是另一個強方向感應邊緣檢測器。
|
![]() |
Frei-Chen
此內建功能提供了三組核心。第一個是 'Sobel
' 的“各向同性”(均勻方向)變體,其中 '2
' 值已被 2 的平方根替換。
Frei-Chen:[{type},][{angle}]![]()
上面的核心是作為 'Frei-Chen ' 核心核心的默認未加權核心。
|
![]() |
Sobel
' 一樣,應使用 90 度倍數的角度應用此核心。為了使事情變得更容易,提供了兩個核心(具有相同的權重),一個像上面那樣用於正交使用,另一個用於對角線使用。
第三組類型包含 9 個經過特殊設計和加權的內核,這些內核不僅用於特定方向的邊緣檢測,還用於確定銳邊的實際角度。此處的「類型」是從「
Frei-Chen:1 ![]()
Frei-Chen:2 ![]()
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」形的「平面」內核。
如您所見,「卷積
」擴展了中心的單個像素,在其周圍形成「L」形。即使原點本身不是「鄰域」的一部分。現在讓我們重複這個例子,但使用「相關
」。如您所見,「相關
」也擴展了單個像素,形成了一個「L」形,但它是一個「旋轉的」「L」形。這本質上是這兩種方法之間的唯一區別。「相關
」方法「按原樣」應用內核,這會導致單個像素擴展為「旋轉」形式。另一方面,「卷積
」實際上使用內核的 180 度「旋轉」形式,以便每個像素都被擴展為相同的非旋轉形狀。如果您想查看一些關於「卷積
」實際工作原理的很好的例子,我建議您也看看EECE \ CS 253 圖像處理,第 7 講,空間卷積。第 22 頁上的圖表,它實際上將「反射」內核應用於單個像素,就像我上面所做的那樣。這個旋轉差異看起來可能不大,但這意味著在數學上,卷積運算(以星號 ('
*
') 表示)是可交換的,也就是說,如果將內核和圖像都視為值數組(或兩個圖像),則 F * G == G * F
。這也意味著卷積是結合的,也就是說 ( F * G ) * H == F * ( G * H )
。有關這方面的更多信息,請參見維基百科的卷積性質。'相關
' 運算既不是可交換的 也不是結合的。即使它與內核的旋轉密切相關。基本上,'卷積
' 的作用更像數學上的“乘法”,而 '相關
' 則不是。所有這些爭論的例外情況是,當使用的內核旋轉 180 度時是相同的。也就是說,內核關於“原點”是對稱的。在這種特殊情況下,兩種操作會產生等效的結果。令人困惑的是,大多數用於卷積的內核,例如高斯模糊、拉普拉斯算子等都是對稱的,在這種情況下,您實際上是在進行卷積還是相關運算並不重要。所以人們對含義變得輕鬆和模糊。只有當它們不對稱時,例如在形狀搜索(見下文)或使用諸如Sobel 之類的定向內核時,這種差異才會變得真正重要。 相關性和形狀搜尋
'相關
' 方法的真正用途(按原樣應用內核鄰域而不旋轉)是一種古老但簡單的方法,用於定位與提供的內核中發現的形狀大致匹配的形狀對象。例如,如果我們要對“L”形內核使用“相關
”並嘗試搜索我們使用上面的卷積方法示例創建的圖像,我們得到...
|
![[IM Output]](convolve_shape_mag.gif)

![[IM Output]](kernel_lshape.gif)

![[IM Output]](correlate_mag.gif)
旁白:請注意,上面內核圖像中的“黑色”區域表示值為零。此內核中沒有負值,只有要匹配的形狀的正值。 |
相關
' 方法在內核“原點”與圖像中的相同形狀完全匹配的點產生了最大亮度。但是,當您只獲得形狀的部分匹配時,它也會產生不太亮的结果。匹配的形狀越多,像素就越亮。但是,我要提醒您,雖然 '相關
' 在這種情況下取得了成功,但它並不是一個很好的方法。例如,它會在亮度非常高的區域中產生大量的誤報。通過對應與圖像的暗背景匹配的區域使用負值可以緩解此問題。也就是說,與背景不匹配的區域會使生成的像素亮度降低。
|
![[IM Output]](convolve_shape_mag.gif)

![[IM Output]](kernel_lpattern.gif)

![[IM Output]](correlate_pattern_mag.gif)
旁白:為了使內核圖像更清晰,我生成了內核圖像,以便正(前景)值為白色,負(背景)值為黑色,零(無關緊要)值為透明。但是,實際使用的內核是根據數字完全定義的,並且它的“鄰域”是一個完整的矩形。 |
^
'。這一點很重要,因為它將分別對內核中的正值和負值進行歸一化。也就是說,您希望平等地搜索前景像素和背景像素。這意味著您可以使用 HDRI 版本的 IM 或適當使用 輸出偏差(見上文)來搜索給定形狀的正匹配和負匹配。例如,在這裡,我將“L”形搜索應用於包含正負“L”形的測試圖像。(顯示的圖像已被放大)
|
![[IM Output]](test_mag.gif)

![[IM Output]](kernel_lpattern.gif)

![[IM Output]](correlate_bias_mag.gif)
50%
”縮放因子,這樣不匹配的像素是黑色的,完美匹配的是白色的。獲得“相關
”匹配圖像後,您需要嘗試找到匹配的“峰值”。這可以使用另一個 相關 來完成,但並不總是有效。更好的方法是使用更精確的模式匹配方法,“擊中與錯過
”形態學,以及為此目的創建的特殊“峰值
”。這會找到任何僅被顏色較深的像素包圍的單個像素。其他“峰值
”內核可用於查找“更寬鬆”的匹配。
在這裡,您可以輕鬆找到形狀最佳匹配的位置,儘管匹配的程度已經丟失。您可能想查看 比較和子圖像搜索 中的“峰值查找”部分。但也請查看 Fred Weinhaus 的腳本“maxima
”。 未來:使用快速傅立葉變換進行歸一化互相關,以生成具有非常大的圖像(源圖像和子圖像)的非常快速的圖像相關性。 相關與擊中和錯過形態學
如果您將我表示的內核圖像與 擊中和錯過形態學方法 使用的內核進行比較,您會發現它們實際上代表了同一件事。'擊中與錯過 ' |
'相關 ' |
|
---|---|---|
前景 | 值為 '1.0 ' |
值為 '1.0 '(歸一化之前) |
無關緊要 | 值為 'Nan ' 或 '0.5 ' |
值為 'Nan ' 或 '0.0 ' |
背景 | 值為 '0.0 ' |
值為 '-1.0 '(歸一化之前) |
結果 | 從背景最大值中減去前景最小值。因此,只有精確匹配才會產生正結果,並且閾值化將產生二進制匹配圖像。 | 生成圖像與形狀匹配程度的範圍。只要存在整體模式,一些背景像素的值就可能大於前景像素。可能難以找到特定的“匹配”峰值。您也可以找到負匹配。 |
擊中與錯過
」只會找到前景與背景差異明確的完美精確匹配。因此,與「相關
」相比,它對噪聲和近似匹配的容忍度要低得多。另一方面,「相關
」可以使用線性圖像處理來執行,更具體地說,可以使用快速傅立葉變換。這可以使使用較大模式和核的模式匹配速度更快,尤其是在涉及多個模式時,可以節省將圖像和模式轉換到頻域的成本。它也適用於實際圖像,但可能也需要一些預處理和使用HDRI。您使用哪一個取決於您自己,以及您追求的結果。僅限完美匹配,或包含更多錯誤的近似匹配,以及可能使用更快的算法。請注意,為了在較大圖像中找到小的彩色圖像的精確匹配,「magick compare
」程序的子圖像定位功能將提供比「擊中與錯過
」或「相關
」方法更好的方法。這是因為它使用「顏色向量差異的最小平方」來進行子圖像匹配,這可以為匹配結果產生更好的指標。但是,它同樣很慢,尤其是對於大型圖像。鄰居計數
卷積可以應用於更不尋常的事情之一被稱為鄰居計數。也就是說,計算出圖像中每個像素點周圍特定區域中存在的像素數量。計算相鄰像素
基本上,通過使用非常簡單的卷積核,您可以創建一個圖像,其中包含二值圖像中特定點周圍的鄰居數量計數。通過使用大小為「1.5
」的環形核進行卷積,您將獲得鄰居計數。以下是一個小區域中每個像素的鄰居計數,並顯示了之前和之後的單個像素的放大圖(使用放大圖像腳本生成)...如您所見,所有像素的灰度級都顯示了它們有多少個鄰居,包括沿著邊緣的任何虛擬像素鄰居。如果要在計數中包含當前像素,則可以使用方形核。通過適當的轉換(包括級別調整)並使用PbmPlus 文件格式,您可以將上述灰度級轉換為實際數字(如果需要)。如果要排除實際形狀內部的像素,可以使用中心像素為強負值的核,然後鉗制任何負結果(如果您使用的是IM 的 HDRI 版本)。生成一個由正 1 包圍的大的負中心核的簡單方法是負向縮放標準的離散拉普拉斯核。
magick area.gif -define convolve:scale=-1\! \ -morphology Convolve Laplacian:0 -clamp neigh_edge.gif |
![[IM Output]](area_enlarged.png)

![[IM Output]](neigh_edge_enlarged.png)
生命遊戲
1970 年,英國數學家約翰·何頓·康威在《科學美國人》雜誌上發表了一項特殊的模擬,該模擬迅速流行起來。它現在被稱為康威的生命遊戲。它基於一個點網格,其中每個點要么是「活著」的,要么是「死的」。然後,根據一組非常簡單的規則,僅基於周圍活著的鄰居細胞的數量,將哪些「細胞」歸類為下一「代」中的「活著」或「死的」。- 鄰域是每個「細胞」周圍的 8 個像素。
- 如果一個「活」細胞有 2 個或 3 個鄰居,它將繼續存活。
- 如果一個「死亡」的細胞周圍正好有 3 個「活著」的細胞,它就會變成「活著」的(誕生)。
- 否則,該細胞會變成或保持「死亡」狀態。
其結果將是每個像素周圍 8 個鄰居的計數(如果是「白色」),如果中心像素是「活著」或「白色」,則加上值 10。因此,對於「死亡」像素,此內核的值將為「
'3: 1, 1, 1 1, 10, 1 1, 1, 1'
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]](life_clut_enlarged.png)
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]](life_gen_000_mag.gif)

![[IM Output]](life_gen_001_mag.gif)

![[IM Output]](life_gen_002_mag.gif)

![[IM Output]](life_gen_003_mag.gif)

![[IM Output]](life_gen_004_mag.gif)
![[IM Output]](../images/glider_gun.gif)
|
![[IM Output]](life_pattern.gif)

![[IM Output]](glider_gun_anim.gif)
這僅僅是 IM 可以處理的「*細胞自動機*」的眾多例子之一。當然,還有許多針對「生命」和「細胞自動機」的更快專用程序,它們通常做完全相同的事情,但我想表明 IM 也足夠靈活地做到這一點。由於結果是簡單的二進制圖像,您還可以使用 IM 的形態學方法,例如命中和未命中模式搜索或互相關來搜索特定的生命模式,從而使使用 IM 進行生命研究更加實用,儘管速度較慢。