譯者 | 朱先忠
審校 | 孫淑娟
讓我們從一個非常技術性的概念開始。
將圖像作為2D信號來瀏覽、分析和處理
這里有其他一些恰當?shù)亩x:
- 信號是一種隨空間或時間變化的量,它可以用來傳輸某種形式的信息。
- 圖像只不過是照射到光學系統(tǒng)上的光量,也就是你用來呈現(xiàn)它的相機或畫布。
從這種意義上來說,圖像只不過是一種2D信號,這種電磁信號攜帶了物理系統(tǒng)檢索到的一些信息。
因此,當我們確定了圖像確實是一種信號時,我們可以考慮將信號處理技術應用于圖像處理任務?,F(xiàn)在,我們可以停止哲學討論,從具體的編碼部分開始。
說到哲學,不妨讓我們拍下這張照片:?
圖片來源:Tingey Injury律師事務所
圖片中的哲學家正在做他的工作:思考。雕塑后面是一片非常白的背景,當然我們并不在乎它。然而,我們能擺脫它嗎?我們能得到這樣的東西嗎?
圖片來源:本文作者
如果我這樣問你,那就意味著我們可以。
每個略懂一些Photoshop的人都可以做到這一點,但你如何使用Python自動做到這樣呢?下面我將為你展示如何做到這一點。
1.總的想法
現(xiàn)在,讓我們來舉一個簡單的例子。
一個大正方形里面裝著一個小正方形。這是一個極其簡單的案例。我們要做的是將較小正方形中的所有數(shù)值設置為1,將外部的所有數(shù)值都設置為0。
我們可以使用此代碼提取這兩個值:
然后,做諸如以下的操作:
上述代碼將圖像從兩個值轉換為1和0。
這非常簡單,對吧?下面,讓我們做一點更大的嘗試。
現(xiàn)在,我們將在較大的正方形內做一個小正方形,但兩個正方形都有一些噪音數(shù)據(jù)。
我的意思是,我們不僅有2個值,而且理論上我們還可以有0到255之間的所有值,這是這個編碼中全部數(shù)值的范圍。
那么,我們該怎樣做呢?
我們要做的第一件事是將圖像(2D信號)扁平化,并將其更改為1D信號。
圖片來源:本文作者
這張圖片是一張50x50的圖片,我們有了一個更加“紛亂”一些的50x50=2500長的1D信號。
現(xiàn)在,如果我們研究1D信號的分布,那么,我們將會得到這樣的結果:
正如我們所看到的,我們有兩個正態(tài)分布。這正是Otsu算法表現(xiàn)最好的地方。其基本思想是,圖像的背景和主題具有兩種不同的性質和兩個不同的領域。例如,在這種情況下,第一個高斯鐘形是與背景相關的鐘形(假設從0到50),而第二個高斯鐘形則是較小正方形(從150到250)中的一個。
所以,假設我們決定將大于100的所有值都設置為1,將小于0的所有值設置為0:?
這樣做的結果是在背景和主體之間形成了以下遮罩:?
這就是Otsu算法的全部思想:
- 將圖像作為2D信號導入/讀取。
- 將圖像展平為1D矢量。
- 選擇一個閾值。
- 將低于該閾值的所有內容設置為0,將高于該閾值的全部內容設置為1。很簡單,對吧?
但是,我們如何選擇合適的閾值呢?什么是最好的?讓我們談談數(shù)學。
2.理論介紹
讓我們將這個概念形式化一點。
我們在圖像中有一個像素域。完整的域從0到255(白色到黑色),但不一定要那么寬(例如,可以從20到200)。
現(xiàn)在,多個點可以具有相同的像素強度(我們可以在同一圖像中具有兩個黑色像素)。假設在一個有100個像素的圖像中,我們有3個強度為255的像素?,F(xiàn)在,在該圖像中具有強度255的概率是3/100。
通常,我們可以說圖像中具有像素i的概率為:?
圖片來源:本文作者
現(xiàn)在,讓我們假設我們正在進行分割的像素是像素k(在我們之前的例子中,k是100)。這將對數(shù)據(jù)點進行分類。k之前的所有點屬于類別0,k之后的所有點都屬于類別1。
這意味著,從類別0中選擇一個點的概率如下:?
圖片來源:本文作者
而從類別1中選擇一個點的概率如下:?
圖片來源:本文作者
正如我們所看到的,這兩種概率顯然都依賴于k。
現(xiàn)在,我們可以計算的另一個值是每個類別的方差:?
其中:?
圖片來源:本文作者
然后這樣:
圖片來源:本文作者
西格瑪值是每個類別的方差,也就是該類別在mu_0和mu_1的平均值周圍分布的程度。
現(xiàn)在,理論上的想法是找到創(chuàng)造我們之前在這張照片中看到的那個小山谷的值:?
但我們使用的方法略有不同,而且更加嚴格。通過使用線性判別分析(LDA:https://en.wikipedia.org/wiki/Linear_discriminant_analysis#Fisher's_linear_discriminant)的相同思想。在(費舍爾)LDA中,我們希望找到一個超平面,以使類別間的方差最大化(這樣兩個均值彼此相距最遠)并且類別內的方差盡可能?。ㄟ@樣我們就不會在兩個類別數(shù)據(jù)點之間有太多重疊)。
在這種情況下,我們沒有任何超平面,而我們設置的閾值(我們的k)甚至不是一條直線,但它更像是一個我們用來區(qū)分數(shù)據(jù)點并對其進行分類的概率值。
可以證明(原始論文中提供完整的證明),在假設背景域與主題域不同的情況下,背景和主題之間的最佳分割是通過最小化此量來實現(xiàn)的。
圖片來源:本文作者
這意味著,我們可以嘗試所有不同的k值,而且只選擇k值最小的那一個。
3.編程實現(xiàn)
這個理論看起來可能很復雜,很難理解,但實現(xiàn)起來非常容易,它由三個部分組成:
3.1 導入庫
我們要做的第一件事是導入我們需要的4個基本庫。
3.2 閾值函數(shù)
一旦你找到了完美的閾值,接下來就是如何將其應用于你的圖像:
3.3 Otsu算法的標準
計算此數(shù)量的函數(shù)如下:
圖片來源:本文作者
相關代碼如下所示:
3.4 最佳閾值計算
另一個函數(shù)只是在所有可能的ks上運行,并根據(jù)上面的標準找到最好的一個:
3.5 完整的實現(xiàn)
因此,我們使用的是接下來的這幅圖像:
圖片來源:Ben Dumond on Unsplash
如果我們將該圖像保存在路徑中,并應用Otsu算法,我們會得到:
如果我們比較im(原始圖像)和im_otsu(算法之后的圖像),我們得到:
正如我們所看到的,圖片右上部分的黑色部分被誤解為主題,因為它與一些主題的色調相同。人并不總是完美的,算法亦然。
4.尾聲
感謝您在Otsu算法教程的整個過程中一直陪伴在我身邊。
在這篇簡短的文章中,我們看到:
- 圖像可以被視為2D信號,然后可以使用信號處理技術進行分析。
- Otsu算法的假設是,圖像的背景和主題有兩個連續(xù)的、不重疊的、可區(qū)分的域。
- 如何在給定Otsu算法的情況下找到圖像的背景和主題之間的最佳區(qū)分。我們如何將Otsu算法解釋為Fisher線性判別式。
- 如何使用Python實現(xiàn)Otsu算法。
- 如何在真實圖像中應用此算法。
譯者介紹
朱先忠,51CTO社區(qū)編輯,51CTO專家博客、講師,濰坊一所高校計算機教師,自由編程界老兵一枚。
原文標題:??Hands on Otsu Thresholding Algorithm for Image Background Segmentation, using Python??,作者:Piero Paialunga