CTPN/CRNN的OCR自然場景文字識別理解(一)

水果先生發表於2018-03-15

CTPN

前言

需閱讀faster-rcnn相關


摘要

問題分析

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

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

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

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

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。

第三,將每一行的所有視窗對應的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)中的細長的矩形)合併成文字線。


網路結構

這裡寫圖片描述

  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畫素。


問題

  1. 沒有很好地處理多方向的文字行
  2. 訓練的時候由於有regression和LSTM,需要小心控制梯度爆炸。
  3. 正如上文所提的,這個網路預測的是一些固定寬度的text proposal,所以真值也應該按照這樣來標註。但是一般資料庫給的都是整個文字行或者單詞級別的標註。因此需要把這些標註轉換成一系列固定寬度的box。
  4. 整個repo是基於RBG大神的faster rcnn改的,所以根據他的輸入要求。要再將資料轉換為voc的標註形式

相關文章