作者:馬健
郵箱:stronghorse_mj@hotmail.com
主頁:http://www.comicer.com/stronghorse/
發布:2017.07.23
教程十七:二值化圖像去毛刺
在灰度圖像處理成純黑白(二值化)圖像以后,經常出現的一個問題是輪廓邊緣出現毛刺。如下面這個圖像:
為了看得更清楚,放大到800%並加網格線:
可以看出在“工”字的上面一橫中,上邊緣有幾個突出點,下邊緣有兩個凹陷點,而在“業”字左側豎條中有突出點,下面一橫中有凹陷點。
產生毛刺的原因是:在掃描或拍攝所生成的原始圖像中,輪廓邊緣像素點的值其實是介於“白”與“黑”之間的“灰”,所以整個邊緣看起來很光滑、不生硬,但變成純黑白后,像素點非黑即白,不再有中間灰,所以總有那么幾個點可能就因為值稍微差了一點,就與周圍的不一樣了。 具體可以參見本系列教程“后記”中“常見問題之二:掃描圖像中的黑、白、灰”部分。
所以解決的辦法就是:
- 讓模糊來得更猛烈一些吧!如果模糊得更均勻一些,這種毛刺現象其實會更少一點。所以在本系列教程的其它部分給出的處理參數中,經常會看到在選擇純黑白后,用高斯模糊來消毛刺。另外對圖像進行放大也會拉出一些模糊空間,一方面可以減輕毛刺,另一方面可以避免轉成純黑白圖像后出現筆畫粘連——所以我一直覺得在 針對掃描書籍的圖像處理教程中,如果只提二值化卻不提放大,就是在騙鬼。
- 用數字圖像處理中的形態學方法識別孤立點、凹陷點,然后去除或填平。
在ScanTailor(以下簡稱ST)中用的就是第2種方法,在CEP v4.13中被引進:在“色彩設置”界面中如果在“色彩數”中選擇“純黑白”,再勾選“邊緣去毛刺”,即可使用這種方法。
這種方法的原理是:
- 先總結常見的邊緣毛刺形狀(孤立點或凹陷點)及修正方法(去除或填平),並以字符串的形式定義成模板。
- 用形態學中的擊中-擊不中變換(Hit-Miss Transform),在整張圖像中查找能與模板匹配的像素點,然后按照模板對像素進行去除或填充。
在ST中總結出來的模板共有6個,分別是:
1 | 2 | 3 | 4 | 5 | 6 |
"XXX" " - " " " |
"X ?" "X " "X- " "X- " "X " "X ?" |
"X ?" "X ?" "X " "X- " "X- " "X- " "X " "X ?" "X ?" |
"XX?" "XX?" "XX " "X+ " "X+ " "X+ " "XX " "XX?" "XX?" |
"XX?" "XX " "X+ " "X+ " "XX " "XX?" |
" " "X+X" "XXX" |
在模板中共有5種符號:X表示黑點,空格表示白點,問號表示黑點白點均可,減號表示去除點,加號表示填充點。所以上表中的前3個模板就表示如果在一排黑點外有孤立點,則孤立點應去除,如上面示例圖中“工”字上面一橫中的幾個孤立點;后3個模板則表示如果黑點中間有凹陷點,則應該進行填充,如上面示例圖中“業”字底下一橫中的幾個凹陷點。
在ST中,每個模板會在上、下、左、右4個方向分別匹配,以模板1為例,其實在內部會擴充為以下4個模板進行匹配:
"XXX" " - " " " |
" " " - " "XXX" |
"X " "X- " "X " |
" X" " -X" " X" |
因此6個模板其實內部要匹配24次,在圖像較大時就會顯得很慢,這也是我平時更喜歡用模糊來進行平滑的原因:CEP中的高斯模糊還是很快的。
整個處理過程的核心是在圖像中查找模板的所有匹配點,即需要去除、填充的點,用的是擊中-擊不中變換(Hit-Miss Transform)。在我看過的教科書中包括ST的源代碼本身,都是用腐蝕、膨脹等形態學基本操作的組合來實現這個變換,但我個人認為多次雙循環會拖累代碼的整體執行速度,所以在實現時我是按照這個變換最原始的定義實現的,一次雙循環周游整個圖像就找出所有匹配點,速度比ST略快,但內存消耗比ST大。
上面示例圖用CEP去除毛刺后的效果:
放大到800%並加網格線的效果:
可以看出,橫線、豎線上的孤立點都被去除,凹陷點也被填平,文字看起來干凈了許多。