1. 程式人生 > >《Detecting Text in Natural Image with Connectionist Text Proposal Network》論文閱讀之CTPN

《Detecting Text in Natural Image with Connectionist Text Proposal Network》論文閱讀之CTPN

前言

2016年出了一篇很有名的文字檢測的論文:《Detecting Text in Natural Image with
Connectionist Text Proposal Network》,這個深度神經網路叫做CTPN,直到今天這個網路框架一直是OCR系統中做文字檢測的一個常用網路,極大地影響了後面文字檢測演算法的方向。

這個演算法很有創新,我打算一步一步介紹其閃光點。

摘要

問題分析

文字檢測不是一件簡單的任務,尤其是複雜場景下的文字檢測,非常具有挑戰性。自然場景下的文字檢測有如下幾個難點:

  • 文字存在多種分佈,文字排布形式多樣;
  • 文字存在多個方向;
  • 多種語言混合。

文字目標的特殊性,一個很大的先驗是,文字總是水平排列的。文字的特徵總感覺體現在edge上。

自然場景文字檢測的難點在於:小目標,遮擋,仿射畸變。本文使用VGG16,只使用conv5,可能對小文字的檢測效果不好。

文字檢測和一般目標檢測的不同——文字線是一個sequence(字元、字元的一部分、多字元組成的一個sequence),而不是一般目標檢測中只有一個獨立的目標。這既是優勢,也是難點。優勢體現在同一文字線上不同字元可以互相利用上下文,可以用sequence的方法比如RNN來表示。難點體現在要檢測出一個完整的文字線,同一文字線上不同字元可能差異大,距離遠,要作為一個整體檢測出來難度比單個目標更大。

因此,作者認為預測文字的豎直位置(文字bounding box的上下邊界)比水平位置(文字bounding box的左右邊界)更容易。

Top-down先檢測文字區域,再找出文字線)的文字檢測方法比傳統的bottom-up的檢測方法(先檢測字元,再串成文字線)更好。自底向上的方法的缺點在於沒有考慮上下文,不夠魯棒,系統需要太多子模組,太複雜且誤差逐步積累,效能受限。
 

本文中利用RNN和CNN的無縫結合可以提高檢測精度。CNN用來提取深度特徵,RNN用來序列的特徵識別(2類),二者無縫結合,用在檢測上效能更好。

具體的說,作者的基本想法就是去預測文字的豎直方向上的位置,水平方向的位置不預測。因此作者提出了一個vertical anchor的方法。與faster rcnn中的anchor類似,但是不同的是,vertical anchor的寬度都是固定好的了,論文中的大小是16個畫素。而高度則從11畫素到273畫素變化,總共10個anchor.

同時,對於水平的文字行,其中的每一個文字段之間都是有聯絡的,因此作者採用了CNN+RNN的一種網路結構,檢測結果更加魯棒。

基於檢測的方法能很好地解決水平文字的檢測問題,缺點是對於非水平的文字不能檢測。

網路結構為RPN,針對文字檢測的特點做了一些修改,最重要的有兩點,

一是改變了判斷正負樣本的方法,不同於物體檢測,文字檢測中proposal如果只框住了一行文字中的幾個文字其實也算正樣本,而用IOU計算的話會被當成負樣本,所以判斷正負樣本只需要計算proposal與ground truth高度的overlap就可以了。

第二點是anchor的選取,既然我們判斷正負樣本的時候不考慮寬度,自然選anchor的時候也不用選擇不同寬度的了,只需要固定寬度然後根據具體任務選擇幾個合適的高度就可以了。其他地方和RPN基本一樣。

 

過程及思想


我們回顧一下Faster RCNN(請閱讀《論文閱讀之Faster R-CNN》)做目標檢測的一個缺點就是,沒有考慮帶文字自身的特點。文字行一般以水平長矩形的形式存在,而且文字行中每個字都有間隔。針對這個特點,CTPN剔除一個新奇的想法,我們可以把文字檢測的任務拆分,第一步我們檢測文字框中的一部分,判斷它是不是一個文字的一部分,當對一幅圖裡所有小文字框都檢測之後,我們就將屬於同一個文字框的小文字框合併,合併之後就可以得到一個完整的、大的文字框了,也就完成了文字的檢測任務。這個想法真的很有創造性,有點像“分治法”,先檢測大物體的一小部分,等所有小部分都檢測出來,大物體也就可以檢測出來了。

 

如圖所示,左邊的圖是直接使用Faster RCNN中的RPN來進行候選框提取,可以看出,這種候選框太粗糙了,效果並不好。而右圖是利用許多小候選框來合併成一個大文字預測框,可以看出這個演算法的效果非常不錯,需要說明的是,紅色框表示這個小候選框的置信度比較高,而其他顏色的候選框的置信度比較低,我們可以看到,一個大文字的邊界都是比較難預測的,那怎麼解決這個邊界預測不準的問題呢?後面會提到。

剛提到CTPN的其中一個閃光點,即檢測小框代替直接檢測大文字框。除了這個新意,CTPN還提出了在文字檢測中應加入RNN來進一步提升效果。為什麼要用RNN來提升檢測效果?文字具有很強的連續字元,其中連續的上下文資訊對於做出可靠決策來說很重要。我們知道RNN常用於序列模型,比如事件序列,語言序列等等,那我們CTPN演算法中,把一個完整的文字框拆分成多個小文字框集合,其實這也是一個序列模型,可以利用過去或未來的資訊來學習和預測,所以同樣可以使用RNN模型。而且,在CTPN中,用的還是BiLSTM(雙向LSTM),因為一個小文字框,對於它的預測,我們不僅與其左邊的小文字框有關係,而且還與其右邊的小文字框有關係!這個解釋就很有說服力了,如果我們僅僅根據一個文字框的資訊區預測該框內含不含有文字其實是很草率的,我們應該多參考這個框的左邊和右邊的小框的資訊後(尤其是與其緊挨著的框)再做預測準確率會大大提升。

如上圖所示,如果我們單純依靠1號框內的資訊來直接預測1號框中否存在文字(或者說是不是文字的一部分),其實難度相當大,因為1號框只包含文字的很小一部分。但是如果我們把2號框和3號框的資訊都用上,來預測1號框是否存在文字,那麼我們就會有比較大的把握來預測1號框確實有文字。我們還可以看看為什麼邊緣的文字框的置信度會較中間的低呢?個人認為很大一部分原因就在於因為這些框都位於總文字的邊緣,沒有辦法充分利用左右相鄰序列的資訊做預測(比如位於最左的文字框丟失了其右邊的資訊)。這就是雙向LSTM的作用,把左右兩個方向的序列資訊都加入到學習的過程中去。

我們已經對CTPN這個演算法的總體思路有了一點理解,那關鍵問題來了,我們怎麼把這些小文字框準確地檢測出來呢?

CTPN藉助了Faster RCNN中anchor迴歸機制,使得RPN能有效地用單一尺寸的滑動視窗來檢測多尺寸的物體。當然CTPN根據文字檢測的特點做了比較多的創新。比如RPN中anchor機制是直接回歸預測物體的四個引數(x,y,w,h),但是CTPN採取之迴歸兩個引數(y,h),即anchor的縱向偏移以及該anchor的文字框的高度,因為每個候選框的寬度w已經規定為16個畫素,不需要再學習,而x座標直接使用anchor的x座標,也不用學習,所以CTPN的思路就是隻學習y和h這兩個引數來完成小候選框的檢測!跟RPN相類似,CTPN中對於每個候選框都使用了K個不同的anchors(k在這裡預設是10),但是與RPN不同的是,這裡的anchors的width是固定的16個畫素,而height的高度範圍為11~273(每次對輸入影象的height除以0.7,一共K個高度)。當然CTPN中還是保留了RPN大多數的思路,比如還是需要預測候選框的分數score(該候選框有文字和無文字的得分)。

這麼多小尺度候選框怎麼才能串聯成一個完整的文字行呢?

文字行構建很簡單,通過將那些text/no-text score > 0.7的連續的text proposals相連線即可。文字行的構建如下。首先,為一個proposal Bi定義一個鄰居(Bj):Bj−>Bi,其中:

  1. Bj在水平距離上離Bi最近
  2. 該距離小於50 pixels
  3. 它們的垂直重疊(vertical overlap) > 0.7

另外,如果同時滿足Bj−>Bi和Bi−>Bj,會將兩個proposals被聚整合一個pair。接著,一個文字行會通過連續將具有相同proposal的pairs來進行連線來構建。

步驟:

第一,首先,使用VGG16作為base net提取特徵,得到conv5_3的特徵作為feature map,大小是W×H×C;

第二,然後在這個feature map上做滑窗,視窗大小是3×3。也就是每個視窗都能得到一個長度為3×3×C的特徵向量。這個特徵向量將用來預測和10個anchor之間的偏移距離,也就是說每一個視窗中心都會預測出10個text propsoal。

第三,將每一行的所有視窗對應的3*3*C的特徵(W*3*3*C)輸入到RNN(BLSTM)中,得到W*256的輸出;

第四,將RNN的W*256輸入到512維的fc層;

第五,fc層特徵輸入到三個分類或者回歸層中。 
第二個2k scores 表示的是k個anchor的類別資訊(是字元或不是字元)。第一個2k vertical coordinate和第三個k side-refinement是用來回歸k個anchor的位置資訊。2k vertical coordinate因為一個anchor用的是中心位置的高(y座標)和矩形框的高度兩個值表示的,所以一個用2k個輸出。(注意這裡輸出的是相對anchor的偏移),k個side-refinement這部分主要是用來精修文本行的兩個端點的,表示的是每個proposal的水平平移量。這邊注意,只用了3個引數表示迴歸的bounding box,因為這裡默認了每個anchor的width是16,且不再變化(VGG16的conv5的stride是16)。迴歸出來的box如Fig.1中那些紅色的細長矩形,它們的寬度是一定的。

第六,這是會得到密集預測的text proposal,所以會使用一個標準的非極大值抑制演算法來濾除多餘的box。 
第七,用簡單的文字線構造演算法,把分類得到的文字的proposal(圖Fig.1(b)中的細長的矩形)合併成文字線。


網路結構

接下來我們就較為細節地學習一下這個CTPN經典網路。

首先CTPN的基礎網路使用了VGG16用於特徵提取,在VGG的最後一個卷積層CONV5,CTPN用了3×3的卷積核來對該feature map做卷積,這個CVON5 特徵圖的尺寸由輸入影象來決定,而卷積時的步長卻限定為16,感受野被固定為228個畫素。卷積後的特徵將送入BLSTM繼續學習,最後接上一層全連線層FC輸出我們要預測的引數:2K個縱向座標y,2k個分數,k個x的水平偏移量。看到這裡大家可能有個疑問,這個x的偏移到底是什麼,為什麼需要回歸這個引數?如果需要X的引數,為什麼不在候選框引數迴歸時直接預測成(x,y,h)三個引數呢,而要多此一舉把該引數單獨預測?這個X的作用作者提到這也是他們論文的一大亮點,稱之為Side-refinement,我理解為文字框邊緣優化。我們回顧一下上面提到的一個問題,文字框檢測中邊緣部分的預測並不準確。那麼改咋辦,CTPN就是用這個X的偏移量來精修邊緣問題。這個X是指文字框在水平方向的左邊界和右邊界,我們通過迴歸這個左邊界和右邊界引數進而可以使得我們對文字框的檢測更為精準。在這裡想舉個例子說明一下回歸這個x引數的重要性。

我們觀察下圖,第一幅圖張我們看到我們有很多小候選框,位於左邊的候選框我標記為1、2、3、4號框,1號框和2號框為藍色,表明得分不高我們不把這兩個框合併到大文字框內,對於3號框和4號框那就比較尷尬了,如果取3號框作為文字框的邊緣框,那麼顯然左邊邊緣留白太多,精準度不夠,但如果去掉3號框而使用4號框作為左邊緣框,則有些字型區域沒有檢測出來,同樣檢測精度不足。這種情況其實非常容易出現,所以CTPN採取了Side-refinement 思路進一步優化邊緣位置的預測即引入迴歸X引數,X引數直接標定了完整文字框的左右邊界,做到精確的邊界預測。第二幅圖中的紅色框就是經過Side-refinement後的檢測結果,可以看出檢測準確率有了很大的提升。 side-refinement確實可以進一步提升位置準確率,在SWT的Multi-Lingual datasets上產生2%的效果提升。

再看多幾幅圖,體驗一下Side-refinement後的效果。

1.輸入為3*600(h)*900(w),首先vgg-16提取特徵,到conv5-3時(VGG第5個block的第三個卷積層),大小為512*38*57。
2.im2col層 512*38*57 ->4608 * 38 * 57 其中4608為(512*9 (3*3卷積展開))
3.而後的lstm層,每個lstm層是128個隱層 57*38*4608 ->57*38*128 reverse-lstm同樣得到的是57*38*128。(雙向lstm沒有去研 究,但我個人理解應該是左邊的結果對右邊會產生影響,同樣右邊也會對左邊產生影響,有空再去看) merge後得到了最終lstm_output的結果 256* 38 * 57
4.fc層 就是一個256*512的矩陣引數 得到512*38*57 fc不再展開;
5.rpn_cls_score層得到置信度 512*38*57 ->20*38*57 其中20 = 10 * 2 其中10為10個尺度 同樣為512*20的引數,kernel_size為1的卷積層;
6.rpn_bbox_pre層 得到偏移 512*38*57 ->20*38*57。同樣是十個尺度 2 * 10 * 38 * 57 
因為38*57每個點每個scale的固定位置我們是知道的。而它與真實位置的偏移只需兩個值便可以得到。 
假設固定位置中點( Cx,Cy) 。 高度Ch。實際位置中點(x,y) 高度h 
則log(h/Ch)作為一個值 
(y-Cy) / Ch作為一個值 
20 * 38 * 57 便是10個尺度下得到的這兩個值。有了這兩個值,我們便能知道真實的文字框位置了。
 

方法細節


k個anchor尺度和長寬比設定

寬度都是16,k = 10,高度從11~273(每次除於0.7)

迴歸的高度和bounding box的中心的y座標如下,帶*的表示是groundTruth,帶a的表示是anchor 


Side-refinement 


文字線構造演算法(多個細長的proposal合併成一條文字線) 
主要思想:每兩個相近的proposal組成一個pair,合併不同的pair直到無法再合併為止(沒有公共元素) 
判斷兩個proposal,Bi和Bj組成pair的條件: 
Bj->Bi, 且Bi->Bj。(Bj->Bi表示Bj是Bi的最好鄰居) 
Bj->Bi條件1:Bj是Bi的鄰居中距離Bi最近的,且該距離小於50個畫素 
Bj->Bi條件2:Bj和Bi的vertical overlap大於0.7

訓練


對於每一張訓練圖片,總共抽取128個樣本,64正64負,如果正樣本不夠就用負樣本補齊。這個和faster rcnn的做法是一樣的。

訓練圖片都將短邊放縮到600畫素。
 

 

本文工作基於faster RCNN , 區別在於

1.改進了rpn,anchor產生的window的寬度固定為3。
2.rpn後面不是直接接全連線+分類/迴歸,而是再通過一個LSTM,再接全連線層。 座標僅僅迴歸一個y,而不是x1, y1, x2, y2
3.新增 side-refinement offsets(可能這個就是4個迴歸值中的其中2個)
 

最後總結一下CTPN這個流行的文字檢測框架的三個閃光點:

  • 將文字檢測任務轉化為一連串小尺度文字框的檢測;
  • 引入RNN提升文字檢測效果;
  • Side-refinement(邊界優化)提升文字框邊界預測精準度。

當然,CTPN也有一個很明顯的缺點:對於非水平的文字的檢測效果並不好。CTPN論文中給出的文字檢測效果圖都是文字位於水平方向的,顯然CTPN並沒有針對多方向的文字檢測有深入的探討。那對於任意角度的文字檢測應該採取什麼的演算法思路呢?後面將介紹的SegLink演算法給出了一個新奇的解決方案。

 

 

 

 

全文翻譯:

Detecting Text in Natural Image with Connectionist Text Proposal Network 中文版 中英文對照

參考連結:

1.https://www.cnblogs.com/skyfsm/p/9776611.html