文本檢測之CTPN

文本檢測之CTPN

來自專欄小石頭的碼瘋窩

簡介

文章基本信息

論文題目:Detecting Text in Natural Image with Connectionist Text Proposal Network,簡稱CTPN.該文章是ECCV2016喬宇老師的文章

論文地址:arxiv.org/pdf/1609.0360

代碼實現:https://github.com/tianzhi0549/CTPN(作者的caffe實現),https://github.com/eragonruan/text-detection-ctpn(其他人tensorflow實現)

作者提供的caffe實現沒有訓練代碼,不過訓練代碼可以參考faster-rcnn的訓練代碼

文本檢測概述

文本檢測可以看成特殊的目標檢測,但它有別於通用目標檢測.在通用目標檢測中,每個目標都有定義好的邊界框,檢測出的bbox與當前目標的groundtruth重疊率大於0.5就表示該檢測結果正確.文本檢測中正確檢出需要覆蓋整個文本長度,且評判的標準不同於通用目標檢測,具體的評判方法參見(ICDAR 2017 RobustReading Competition).所以通用的目標檢測方法並不適用文本檢測

論文關鍵idea

  1. 採用垂直anchor回歸機制,檢測小尺度的文本候選框
  2. 文本檢測的難點在於文本的長度是不固定,可以是很長的文本,也可以是很短的文本.如果採用通用目標檢測的方法,將會面臨一個問題:**如何生成好的text proposal**.針對上述問題,作者提出了一個vertical anchor的方法,具體的做法是只預測文本的豎直方向上的位置,水平方向的位置不預測。與faster rcnn中的anchor類似,但是不同的是,vertical anchor的寬度都是固定好的了,論文中的大小是16個像素。而高度則從11像素到273像素(每次除以0.7)變化,總共10個anchor.
  3. 採用RNN循環網路將檢測的小尺度文本進行連接,得到文本行.
  4. 採用CNN+RNN端到端的訓練方式,支持多尺度和多語言,避免後處理.

整體實現流程

CTPN的具體實現流程包含三個部分:**檢測小尺度文本框**,**循環連接文本框**,**文本行邊細化**.具體的實現步驟如下:

  1. 使用VGG16作為base net提取特徵,得到conv5_3的特徵作為feature map,大小是W×H×C
  2. 在上述的feature map上使用大小為$3 imes3$的滑動窗進行滑動,每個窗口都能得到一個長度為3×3×C的特徵向量,每個滑動窗口中心都會預測k個相對於anchor的偏移
  3. 將上一步得到的特徵輸入到一個雙向的LSTM中,得到長度為W×256的輸出,然後接一個512的全連接層,準備輸出。
  4. 輸出層部分主要有三個輸出。2k個vertical coordinate,因為一個anchor用的是中心位置的高(y坐標)和矩形框的高度兩個值表示的,所以一個用2k個輸出。(注意這裡輸出的是相對anchor的偏移)。2k個score,因為預測了k個text proposal,所以有2k個分數,text和non-text各有一個分數。k個side-refinement,這部分主要是用來精修文本行的兩個端點的,表示的是每個proposal的水平平移量。
  5. 使用一個標準的非極大值抑制演算法來濾除多餘的text proposal。
  6. 最後使用基於圖的文本行構造演算法,將得到的一個一個的文本段合併成文本行。

具體實現細節

垂直anchor

  • k個anchor的設置:寬度固定為16,高度範圍為11~273像素(每次除以0.7)
  • 預測k個垂直坐標:

雙向LSTM

  • 本文使用了雙向的lstm,每個lstm有128個隱藏層
  • lstm可以利用文本序列的上下文信息,使得檢測的文本行更加精確,儘可能減少誤檢(如窗戶,磚塊,葉子等造成的誤檢)

文本行的構造和細化

所有的text proposals只保留score大於0.7的proposal

  • 文本行構造規則

判斷text proposals是否屬於同一個文本行的定義規則如下:

Bj到Bi的距離最近(水平距離)Bj與Bi之間的距離小於50個pixel垂直方向重疊大於0.7Bj->Bi,同時Bi->Bj

  • 文本行的side-refinement

由於text proposal的寬度是固定16,這可能造成定位不準,部分text proposal被丟棄等

預測文本行的left和right的水平坐標該處理過程融合在模型內,而非後處理

訓練

訓練labels

  • 正樣本

與真值IoU大於0.7的anchor作為正樣本,與真值IoU最大的那個anchor也定義為正樣本

這個時候不考慮IoU大小有沒有到0.7,這樣做有助於檢測出小文本,這是有別於通用目標檢測的關鍵點

  • 負樣本

與真值IoU小於0.5的anchor定義為負樣本

訓練loss

模型的損失函數包含3部分:文本/非文本loss[採用的是softmax],垂直坐標loss[採用的是L1回歸],side-refinement loss[採用的是L1回歸],具體公式如下:

這裡$lambda_{1}=1,lambda_{2}=2$,

訓練參數

  • 對於每一張訓練圖片,總共抽取128個樣本,64正64負,如果正樣本不夠就用負樣本補齊。這個和faster rcnn的做法是一樣的。
  • 訓練圖片都將短邊放縮到600像素,並且保持原圖的縮放比
  • RNN層和output層採用隨機均值為0,方差為1的參數進行初始化
  • 在訓練時CNN的前兩層參數固定

測試集上的評估結果

利用CTPN訓練自己的數據

這裡採用的代碼是github.com/eragonruan/t

編譯源碼

cd lib/utilschmod +x Make.sh | Design and Development./make.sh

準備數據

  • 數據標註

這裡我在標註數據的時候採用的是順時針方向,一次是左上角坐標點,右上角坐標點,右下角坐標點,左下角坐標點(即x1,y1,x2,y2,x3,y3,x4,y4),,這裡的標註方式與通用目標檢測的目標檢測方式一樣,這裡我標註的數據是生成到txt中,具體格式如下:

  • 數據處理

根據ctpn訓練數據的要求,需要對上述數據(txt標註數據)進一步處理,生成對應的xml文件,具體格式參見pascal voc.具體的訓練數據截圖和生成的pascal voc格式如下圖:

處理數據的時候可以執行:

cd lib/prepare_training_datapython split_label.pypython ToVoc.pycd ../../dataln -s TEXTVOC VOCdevkit2007

注意:這裡生成的數據會在當前目錄下,文件夾為TEXTVOC,需要將該文件夾移至/data目錄下,然後在做VOCdevikt2007的軟連接

訓練

這裡你可以指定在哪塊顯卡上運行,我這裡選擇在第一塊顯卡上訓練,訓練中間過程圖在這裡就不放了,具體的訓練命令如下:

CUDA_VISIBLE_DEVICES="0" python ./ctpn/train_net.py

部分檢測結果

以下展示了部分檢測結果,可以發現ctpn在檢測水平文字效果確實不錯,但是在垂直方向和傾斜方向效果相對較差:

總結及存在的困惑

總結

  • ctpn在檢測在水平方向的文字效果比較好,但是在其它方向的檢測效果相對較差

困惑

  • side-refinement的輸出為什麼是k個?它是bbox最左邊和最右邊相對ground truth的偏移

推薦閱讀:

車輛檢測識別(YOLOV2)
video segmentation 論文思想概述
3D卷積神經網路Note01
菜鳥學tensorflow.3
從VGG到NASNet,一文概覽圖像分類網路

TAG:計算機視覺 | 深度學習DeepLearning | TensorFlow |