(轉)
CTPN篇
1.OCR文字檢測難點
小目標,遮擋,仿射畸變。
2.與一般目標檢測的比較
- 文本線是一個sequence(字符、字符的一部分、多字符組成的一個sequence),而不是一般目標檢測中只有一個獨立的目標。這既是優勢,也是難點。優勢體現在同一文本線上不同字符可以互相利用上下文,可以用sequence的方法比如RNN來表示。難點體現在要檢測出一個完整的文本線,同一文本線上不同字符可能差異大,距離遠,要作為一個整體檢測出來難度比單個目標更大。
3.檢測方法
- Top-down(先檢測文本區域,再找出文本線)的文本檢測方法比傳統的bottom-up的檢測方法(先檢測字符,再串成文本線)更好。
- 自底向上的方法的缺點在于沒有考慮上下文,不夠魯棒,系統需要太多子模塊,太復雜且誤差逐步積累,性能受限。
本文工作基于faster RCNN , 區別在于
- 改進了rpn,anchor產生的window的寬度固定為3。
- rpn后面不是直接接全連接+分類/回歸,而是再通過一個LSTM,再接全連接層。 坐標僅僅回歸一個y,而不是x1, y1, x2, y2
- 添加 side-refinement offsets(可能這個就是4個回歸值中的其中2個)!
本文中利用RNN和CNN的無縫結合可以提高檢測精度。CNN用來提取深度特征,RNN用來序列的特征識別(2類),二者無縫結合,用在檢測上性能更好。
具體的說,作者的基本想法就是去預測文本的豎直方向上的位置,水平方向的位置不預測。因此作者提出了一個vertical anchor的方法。與faster rcnn中的anchor類似,但是不同的是,vertical anchor的寬度都是固定好的了,論文中的大小是16個像素。而高度則從11像素到273像素變化,總共10個anchor.
同時,對于水平的文本行,其中的每一個文本段之間都是有聯系的,因此作者采用了CNN+RNN的一種網絡結構,檢測結果更加魯棒。RNN和CNN的無縫結合可以提高檢測精度。CNN用來提取深度特征,RNN用來序列的特征識別(2類),二者無縫結合,用在檢測上性能更好。
基于檢測的方法能很好地解決水平文字的檢測問題,缺點是對于非水平的文字不能檢測。
網絡結構為RPN,針對文字檢測的特點做了一些修改,最重要的有兩點,
一是改變了判斷正負樣本的方法,不同于物體檢測,文字檢測中proposal如果只框住了一行文字中的幾個文字其實也算正樣本,而用IOU計算的話會被當成負樣本,所以判斷正負樣本只需要計算proposal與ground truth高度的overlap就可以了。
第二點是anchor的選取,既然我們判斷正負樣本的時候不考慮寬度,自然選anchor的時候也不用選擇不同寬度的了,只需要固定寬度然后根據具體任務選擇幾個合適的高度就可以了。其他地方和RPN基本一樣。
基本過程
整個檢測分六步:
第一,首先,使用VGG16作為base net提取特征,得到conv5_3的特征作為feature map,大小是W×H×C;
第二,然后在這個feature map上做滑窗,窗口大小是3×3。也就是每個窗口都能得到一個長度為3×3×C的特征向量。這個特征向量將用來預測和10個anchor之間的偏移距離,也就是說每一個窗口中心都會預測出10個text propsoal。
第三,將每一行的所有窗口對應的33C的特征(W33C)輸入到RNN(BLSTM)中,得到W256的輸出;
第四,將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)中的細長的矩形)合并成文本線。
網絡結構
輸入為3600(h)900(w),首先vgg-16提取特征,到conv5-3時(VGG第5個block的第三個卷積層),大小為5123857。
im2col層 5123857 ->4608 * 38 * 57 其中4608為(5129 (33卷積展開))
而后的lstm層,每個lstm層是128個隱層 57384608 ->5738128 reverse-lstm同樣得到的是5738128。(雙向lstm沒有去研 究,但我個人理解應該是左邊的結果對右邊會產生影響,同樣右邊也會對左邊產生影響,有空再去看) merge后得到了最終lstm_output的結果 256* 38 * 57
fc層 就是一個256512的矩陣參數 得到5123857 fc不再展開;
rpn_cls_score層得到置信度 5123857 ->203857 其中20 = 10 * 2 其中10為10個尺度 同樣為51220的參數,kernel_size為1的卷積層;
rpn_bbox_pre層 得到偏移 5123857 ->203857。同樣是十個尺度 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像素。
問題
- 沒有很好地處理多方向的文本行
- 訓練的時候由于有regression和LSTM,需要小心控制梯度爆炸。
- 正如上文所提的,這個網絡預測的是一些固定寬度的text proposal,所以真值也應該按照這樣來標注。但是一般數據庫給的都是整個文本行或者單詞級別的標注。因此需要把這些標注轉換成一系列固定寬度的box。
- 整個repo是基于RBG大神的faster rcnn改的,所以根據他的輸入要求。要再將數據轉換為voc的標注形式