手寫數字識別系統之圖像分割

背景

本文,主要介紹我以前在學校時候,研究的一些跟手寫數字識別相關的技術心得,主要涉及:數字圖像處理、特徵提取、神經網絡等等相關的一些技術。。c++

雖然不少用到的仍是網上現有的比較成熟的算法,可是在這些基礎上,我仍是有作了很多算法上的改進的。。算法

而且爲了寫這個項目,我當時還特意寫了一整套神經網絡庫,從圖像處理開始到最後的識別過程,沒有使用任何第三方庫,都是從0仍是寫起 也沒有用到opencv啊什麼的。編程

上層ui當時用的qt,雖然當時也算是爲了跨平臺,但那個時候畢竟仍是學生,代碼經驗欠缺,所以個人基礎庫對跨平臺處理的並非很好。。網絡

那個基礎庫,我稍微簡單說下,那是個人第一個開發庫,是一個相似boost的c++模板庫,裏面用到了不少c++的模板元編程的特性,可是如今已經對c++無愛了,因此早已廢棄不用了。

不過也就是這個庫的開發,很大程度上影響了我以後的編碼風格,也是至此以後,我重點轉向了對c的開發上。。

這套識別系統,僅僅是我當時爲了學習神經網絡,拿來練手用的,無法跟那些成熟的相比,識別率不是很高哈,只能給你們用來參考學習了。性能

簡介

本文在基本BP算法和數字圖像與處理的基礎上,經過改進網絡、圖像處理算法,並結合實踐來探索如何實現具備高魯棒的、高精度的、高效率的脫機數字識別。學習

在這我主要研究脫機單體數字識別,其主要步驟爲:優化

overview_1

數字樣本的採集

主要採用5行10列的數字樣本規格。採集方式是經過掃描樣本卡片來獲取圖像,也儘可能避免樣本了的失真,如圖:ui

overview_2

圖像二值化

主要採用全局閾值分割法和自適應的局部閾值分割法,來實如今不一樣亮度背景下的自適應分割,並對結果進行比對。編碼

數字提取

目前主要考慮聚類法、矩陣式分割法、連通區域標記法,並比較其優劣,選取效果最好的一種算法。code

圖像歸一化

主要採用雙線性內插和最鄰近內插來實現放大,爲了減小圖像在收縮時帶來的失真,目前打算採用求平均法來實現。

特徵提取

主要採用逐像素提取法,PCA主成分提取兩種方法來實現。

樣本學習

主要採用基於BP算法(反向傳播學習算法)的神經網絡進行識別,並對BP進行必定的改進和優化,來改進訓練效果而且適當的提升訓練速率。

目前,針對BP的改進算法,主要採添加動量項和自適應步長法。

而對於BP算法,其主要步驟爲:

前向計算=〉反向計算=〉權值修正=〉循環迭代

爲了進一步改進網絡,實現高精度、高效率的識別,打算考慮採用多網絡集成法,來進行優化。 主要針對不一樣權值、隱層數的基本BP網絡進行集成。經過每一個網絡分類的結果進行加權輸出,來達到有效的分類。

閾值分割

閾值分割法是一種基於區域的圖像分割技術,其基本原理是:經過設定不一樣的特徵閾值,把圖像像素點分爲若干類。

在本文中,咱們主要處理針對兩類的分割,令閾值爲T,圖像像素對應的灰度級爲f(x, y),那麼經閾值分割後的圖像g(x, y)定義爲:

split_1

所以,標記爲1的像素對應於對象,也就是前景,而標記爲0的對象對應於背景,也就是咱們一般所說的圖像二值化。

利用閾值分割進行圖像二值化的主要難題就是閾值的選取,事實證實,閾值的選擇的恰當與否對分割的效果起着決定性的做用。

經常使用的閾值分割方法有如下三種:

總體閾值法

利用整幅圖像的信息對圖像求出最優閾值, 在二值化分割過程當中只使用這一個固定閾值,所以計算量小,但對於亮度條件很差的圖像的分割效果較差。

局部閾值法

它是把原始圖像分爲幾個小的子圖像,再對每一個子圖像求出最佳閾值。所以效果較好,但開銷較大,且局部大小不太好肯定,過小容易失真,太大效果不顯著。

動態閾值法

它的閾值求取方法不只取決於該像素的灰度值及其領域內像素灰度值, 並且還與像素的座標位置有關, 這種方法靈活性大, 可是複雜度高, 計算量和時間開銷都比較大。

而岡薩雷斯寫的那本書數字圖像處理裏面,給出了一種最小偏差閾值,經過利用共軛梯度法對灰度直方圖進行雙峯的高斯密度曲線進行擬合,求取最佳閾值,效果至關好,可是計算太大,並且對於雙峯不顯著的圖像比較難處理,還需進行附加的單峯檢測,並進行插值處理,因爲過於複雜且實現也至關困難。

split_2

而本文采用具備自適應性的OTSU局部閾值法來分割圖像,並對OTSU和局部閾值法進行了改進,不只提升了性能並且改善了分割效果,對於亮度不均勻的圖像也能實現較好的分割。

最大類間方差法(OTSU)

由Otsu於1978年提出的最大類間方差法以其計算簡單、穩定有效,一直廣爲使用。其主要思想就是選取閾值使其類內方差最小化或類間方差最大化。Otsu算法不只計算簡單,並且可以應用於多閾值肯定,所以能夠說是一種至關好的閾值選取方法。 咱們一般採用最大化類間方差,來實現閾值分割,其類間方差定義爲:

otsu_1

其中

|| u || 圖像中總的灰度均值 || || u1 || 圖像中小於閾值T的像素灰度均值 || || u2 || 圖像中大於閾值T的像素灰度均值 || || n1 || 圖像中小於閾值T的像素數 || || n2 || 圖像中大於閾值T的像素數 ||

所以,只需經過遍歷256個灰度級,尋找使其類間方差最大的那個灰度值就是最佳閾值T。

OTSU的實現與改進

然而若是每次遍歷都須要從新計算閾值兩邊的均值與像素數的話計算量是至關大的,若是可以在下次遍歷時利用上次計算的結果,那麼計算量能夠大大減小。 假設灰度直方圖爲,圖像總均值爲,圖像總像素數爲,那麼其遞推方式以下:

otsu_2

爲了進一步簡化計算,咱們能夠經過用otsu_3來替換,獲得

otsu_4

因爲n在遞歸中不變能夠省略,所以能夠改成

otsu_5

因爲本文是針對字符圖像的分割,因爲字符的筆畫一般較細,一般只佔圖像的1/4都不到,所以能夠適當的調整閾值,以實現較好的分割效果,改進後的閾值爲

otsu_6

局部閾值的實現與改進

然而在實際圖像中, 因爲噪聲或其餘干擾等因素的影響,OTSU閾值分割並不能使圖像分割獲得滿意的結果, 每每會產生嚴重的分割錯誤。這是由於圖像的灰度直方圖分佈不必定 出現明顯的峯和谷, 像素灰度值僅僅反映了像素灰度級的幅值大小, 並無反映出像素與鄰域的空間相關信息。

經過具體的實驗發現:

當圖像亮度分佈不均勻時,每每沒法獲得好的分割效果,一般會出現大塊的黑塊,或者過渡分割而丟失信息的狀況。

所以,能夠經過對圖像進行分塊,針對每一小塊進行OTSU分割,能夠減小這些狀況的發生,可是這又會出現不但願的「棋盤」效果,爲了不這種狀況的發生,能夠採用以下改進的局部閾值算法:

遍歷圖像中每一像素,在該像素的鄰域內進行灰度統計,計算OTSU閾值,並僅對該點進行閾值分割。

這樣就能在較好的分割效果下實現像素平滑過渡,避免了「棋盤」效應,因爲在當像素移動時,只有一行或一列改變,因此能夠在每步移動中,以新數據更新前一個位置獲得的直方圖,從而避免了每次從新計算整個直方圖,大大減小了計算量,使其在一個可接受的範圍內。

爲了防止部分區域受到噪聲干擾而產生的黑塊現象,能夠在進行局部閾值處理前,進行三階的平滑處理,效果至關顯著。

結果

原圖

split_3

經全局閾值處理後的圖象

split_4

經改進的局部閾值處理後的圖像

split_5

總結

由上圖可見,經改進的局部閾值處理後的圖像的效果仍是至關明顯的,但是仍是有些不足之處。。

就是處理後的圖像筆畫較粗,容易填掉數字中的空洞,尤爲是4,6,8,9這些含有小孔的數字,這些都有待進一步改進。

後續,我還會總結下:傾斜矯正、數字提取、特徵提取、神經網絡相關的一些心得和改進算法。。

最後,再貼兩張hnr項目,界面截圖哈。。

before after


TBOOX項目主頁

相關文章
相關標籤/搜索