1. 程式人生 > >SWT(Detecting Text in Natural Scenes with Stroke Width Transform)演算法詳解

SWT(Detecting Text in Natural Scenes with Stroke Width Transform)演算法詳解

《Detecting Text in Natural Scenes with Stroke Width Transform》,這是微軟公司的一篇發表於CVPR2010的文章,使用傳統方法來檢測自然場景中的文字。程式碼地址:https://github.com/aperrau/DetectText

因為算是一個比較經典的文章,所以看完記錄一下。當然github還有其他版本的實現程式碼,上面的程式碼幾乎和原文的原理一樣,方便和文章一起閱讀,因此放在這。

下面根據原文的結構和上述提供的程式碼詳細的解讀一下該演算法

總的來說該演算法分為四步:

  1. 利用canny運算元檢測圖片的邊界
  2. 筆畫寬度變換-Stroke Width Transform(這一步輸出的影象我們稱為SWT影象)
  3. 通過SWT影象得到多個連通域
  4. 通過自定義的規則過濾一些連通域,得到候選連通域
  5. 將連通域合併得到文字行

一、利用canny運算元檢測圖片的邊界

這步不用多說,基礎的影象處理知識,利用OpenCV 的Canny函式可以得到圖片邊緣檢測的結果。

二、筆畫寬度變換(Stroke Width Transform)

先要劇透一點,也是需要明確的一點,這一步輸出影象和輸入影象大小一樣,只是輸出影象畫素為筆畫的寬度,具體如下。
在這裡插入圖片描述

如上圖所示,通過邊緣檢測得到上圖a,假設現在從邊緣上的點p開始,根據p點梯度的反方向找到邊緣另一邊的點q,如果p點的梯度與q點梯度的反方向夾角在 ±

π / 6 \pm\pi/6 之間,那麼這兩點間的距離為一個筆畫寬度,那麼p點和q點以及它們之間的畫素在SWT輸出影象中對應位置的值為p和q點的距離大小。

按照上述的計算方法會有兩種情況需要考慮。如下圖所示,
下圖a表示一個筆畫中的畫素可能得到兩個筆畫寬度,這種情況下將紅點出的筆畫寬度設定為最小的那個值,下圖b表示當一個筆畫出現更為複雜情況,b圖中的紅點計算出的兩個筆畫寬度用兩個紅線表示,這兩紅線都無法真正表示筆畫的寬度,這時候筆畫寬度取這裡面所有畫素計算得到的筆畫寬度的中值作為紅點出的筆畫寬度。
在這裡插入圖片描述

因為有文字比背景更亮和背景比文字更亮兩種情況,這樣會導致邊緣的梯度方向相反,所以這一個步驟要執行兩遍。這個步驟結束後得到一張SWT影象。

三、通過SWT影象得到多個連通域

在通過上述步驟得到SWT輸出影象後,該影象大小與原影象大小一致,影象中的畫素值為對應畫素所在筆畫的寬度(下面稱為SWT值)。現將相鄰畫素SWT值比不超過3.0的歸為一個連通域。這樣就能得到多個連通域。

四、過濾連通域

上述步驟輸出的多個連通域中,並不是所有的連通域都被認為是筆畫候選區域,需要過濾一些噪聲的影響,過濾的規則有:

  1. 如果某連通域的方差過大(方差大於連通域的一半為方差過大為過大),則認為該連通域不是有效的
  2. 如果某連通域過大(寬大於300)或者過小(寬小於10),則認為該連通域不是有效的(程式碼中只過濾了過大的連通域,連通域的長寬為連通域外接矩形的長寬)
  3. 如果某連通域的長寬比不在0.1-10的範圍內,則認為該連通域不是有效的(連通域的長寬為連通域外接矩形的長寬)
  4. 如果某連通域的外接矩形包含其他兩個連通域,則認為該連通域不是有效的(程式碼中判定,如果某個連通域的外接矩形包含兩個或兩個以上連通域外接矩形的中心時,認為其包含了兩個連通域)

上述條件都滿足的連通域,認為是筆畫候選區域,用於輸入給下一步操作。

五、將連通域合併得到文字行

文中認為,在自然場景中,一般不會只有單個字母出現,所有將連通域合併為文字有利於進一步將噪聲排除。

當兩個連通域滿足下面條件時,認為這兩個連通域是一對:

  1. 兩個連通域中值的比小於2.0(連通域中值,指的是連通域中所有畫素值的中值)
  2. 兩個連通域高的比小於2.0(連通域的高,指其外界矩形的高)
  3. 兩個連通域之間的距離小於較寬的連通域寬度的3倍(連通域之間的距離為連通域外界矩形中心點之間的距離)
  4. 兩個連通域的顏色相似(程式碼用兩個連通域對應於原圖區域的畫素均值代表該連通域的顏色)

得到兩兩連通域組成的多對連通域後,如果有兩連通域有共享的連通域,共享的連通域都在連通域對的一端(即連通域的首端或者尾端),且方向相同(方向用一個連通域中心到另一個連通域中心的方向),就將這兩對連通域合併為一個新的連通域組,依次進行,知道沒有連通域對需要合併則合併結束。

最後將合併完的結果中濾除小於3的連通域的連通域組得到的最終結果,認為是一行文字。

到這裡SWT的文字檢測演算法就介紹完了。

中文字定位與識別的評測方法

歡迎加入OCR交流群:785515057

參考
1.《Detecting Text in Natural Scenes with Stroke Width Transform》
2.https://sites.google.com/site/roboticssaurav/strokewidthnokia
3.https://github.com/aperrau/DetectText
4.https://www.cnblogs.com/dawnminghuang/p/3807678.html