1. 程式人生 > >【OCR技術系列之五】場景文字檢測技術綜述(CTPN, SegLink, EAST)

【OCR技術系列之五】場景文字檢測技術綜述(CTPN, SegLink, EAST)

文字識別分為兩個具體步驟:文字的檢測和文字的識別,兩者缺一不可,尤其是文字檢測,是識別的前提條件,若文字都找不到,那何談文字識別。今天我們首先來談一下當今流行的文字檢測技術有哪些。

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

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

我們先從直觀上理解文字檢測任務。給定一張圖片,我們需要找出這張圖裡文字出現的所有位置位置,那這個任務其實跟目標檢測任務差別不大,即找出每個物體在圖片中的位置,並標出該包圍框裡的物體的類別。而文字檢測就是,找出每個文字在圖片中出現的位置,因為我們的類別只有2個(有文字和沒文字),看起來就像一個簡單的單類別目標檢測的任務,自然而然我們就會想到用經典的目標檢測網路來進行文字檢測,比如經典的Faster R-CNN。

Faster RCNN

Faster RCNN來做文字檢測從任務上分析是可行的,畢竟文字說到底還是一個Object。我們回顧一下Faster RCNN做目標檢測的關鍵步驟有哪些:

  1. 基礎網路做特徵提取;
  2. 特徵送入RPN做候選框提取;
  3. 分類層對候選框內物體進行分類,迴歸層對候選框的(x,y,w,h)進行精細調整。

Faster RCNN做文字檢測感覺問題不大,但是從效果來看,僅套用Faster RCNN來做文字檢測效果並不好,原因在於,文字有自己獨有的特點,這種通用的文字檢測框架並不能很好地解決文字的這些特點。那文字有什麼特點呢?我總結如下:

  1. 文字大多數以長矩形形式存在,即長寬比一般較大或較小,這與普通的目標檢測中的物體不一樣(這些長寬比較接近1)
  2. 普通物體(比如貓)存在明顯的閉合邊緣輪廓,而文字沒有;
  3. 文字中包含多個文字,而文字之間是有間隔的,如果檢測做得不好,我們就會把每個字都當成文字行給框出來而非整行作為文字框,這與我們的期望不一樣。

基於以上文字檢測的特點,我們必須對Faster RCNN這類通用網路進行改進,設計出適合文字檢測的全新網路架構。

CTPN(2016)

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

這個演算法很有創新,我打算一步一步介紹其閃光點。我們回顧一下Faster RCNN做目標檢測的一個缺點就是,沒有考慮帶文字自身的特點。文字行一般以水平長矩形的形式存在,而且文字行中每個字都有間隔。針對這個特點,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來進行連線來構建。

接下來我們就較為細節地學習一下這個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後的效果。

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

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

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

SegLink(2017)

CVPR2017的一篇spotlight論文《Detecting Oriented Text in Natural Images by Linking Segments》介紹以一種可以檢測任意角度文字的檢測演算法,我們一般稱這個演算法為SegLink,這篇論文既融入CTPN小尺度候選框的思路又加入了SSD演算法的思路,達到了當時自然場景下文字檢測state-of-art的效果。

現在我想先介紹為什麼要針對多方向的文字檢測做特定的研究。對於普通目標檢測,我們並不需要對其做所謂的多方向目標檢測,比如下面這個檢測任務,我們直接把單車和狗的位置找出來即可。

但是對於文字檢測任務可不一樣,文字的特點就是高寬比特別大或小,而且文字通常存在一定的旋轉角度,如果我們對於帶角度的文字仍然使用目標檢測那個思路迴歸四個引數(x,y,w,h)來指定一個目標的位置的話(如下圖紅色框),那顯然誤差太大了,這個檢測效果並不是我們所能接受的。作為對比,下圖的綠色框的檢測效果才是我們的終極目標。那麼怎麼基於原來經典的目標檢測演算法做相應的優化以適應這種檢測效果的要求呢?

一個最直接的思路就是讓模型再學習一個引數\(\theta\)!這個\(\theta\)表示文字框的旋轉角度,也就是我們最終要回歸的引數從原來的\((x,y,w,h)\)變成\((x,y,w,h,\theta)\)。SegLink確實也採取了這個思路,除此之外,他還提出了Segment和Linking兩個重要概念,這個才是這篇CVPR論文的核心創新點。

什麼是segment?segment從中文上理解為文字行的一部分,這一部分可以是一個字元或文字行的任意一部分。如下圖示,黃色框表示一個segment,一個完整的文字行中包含多個segment,每個sgment之間通過link(圖中的綠色線)連線組合起來。那麼Segment做文字檢測的思路其實跟CTPN的思路很像,先檢測文字行的一部分,再把他們連線起來構成一個完整文字行。

我們把圖片的關鍵部位放大看看細節:首先每個segment是有一定的重合區域的,然後每兩個segment連線的部位是兩個segment的中心點。每一個segment和link僅依靠區域性影象的紋理資訊即可完成檢測,而無需整張影象的資訊。

接下來我們通過分析SegLink的網路架構進一步理解SegLink如何做到高效的多角度文字檢測。下圖是SegLink的網路架構,顯然這個架構採取了SSD的思路,首先使用VGG16作為backbone進行特徵提取,其中VGG16的全連線層(fc6,fc7)替換成卷積層(conv6,conv7),再接卷積層conv8到conv11。值得說明的是,conv4~conv11之間的尺寸依次減少(每一層是前一層的1/2)。這個做法是為了做多尺度下的目標檢測,即大的feature map擅長做小物體的檢測,而小的feature map則擅長檢測大物體。藉助多個不同尺度的feature map,從6個feature layer上檢測segment和link,我們就可以檢測出不同尺寸的文字行了。

觀察後面的卷積層可以發現,對不同層的feature map使用3×3的卷積層產生最終的輸出(包括segment和link),不同特徵層輸出的維度是不一樣的,因為除了conv4_3層外,其它層存在跨層的link。這裡segment是text的帶方向bbox資訊(它可能是個單詞,也可能是幾個字元,總之是文字行的部分),link是不同segment的連線資訊(文章將其也增加到網路中自動學習)。

當所有segments都被檢測出來後,我們就可以通過融合規則(combining segments),將各個feature map的segment的box資訊和link資訊進行融合,得到最終的文字行。

SegLink所使用的目標函式由三個部分構成,是否是text的二類分類的softmax損失,box的smooth L1 regression損失,是否link的二類的softmax損失。λ1和λ2控制權重,最後都設為1。

現在計算一下每個feature map輸出的引數有哪些呢?

  • segment的位置資訊:\((x,y,w,h,\theta)\),一共5個引數
  • 每個segment內的分類分數,即判斷框內有字元還是無字元的分數(2分類),共2個引數
  • 同層(within-layer)的每個segment的link的分數,表示該方向有link還是沒link(2分類問題),而一個segment有八鄰域所以有八個方向,引數一共有2×8=16
  • 相鄰層(cross-layer)之間也存在link,同樣是該方向有link還是沒link(2分類問題),而link的個數是4個,所以引數總數為2×4=8

下圖很清楚地表示出每個feature map輸出的引數有多少個,輸出引數總數為(2+5+16+8=31)。假設當前的feature map的尺度為(w,h),那麼該層卷積後輸出為w×h×31。

這裡想再談談Within-Layer Link和Cross-Layer Link的作用。

within-layer link表示在同一層feature layer裡,每個Segment與8鄰域內的segment的連線狀況,如下圖(a)所示。且每個link有2維,一維是正分,表示兩個segment屬於同一文字,一維是負分,表示兩個segment不屬於同一文字。所以,每個predictor輸出16(8×2)維向量。   

cross-layer link:在不同的feature layer上有可能會檢測到同一文字的segments,造成冗餘,cross-layer link的提出就是為了解決這個問題。cross-layer link連線了兩個相鄰feature layer上的segments,如圖(b)所示。需要注意的是,由於下采樣使後一層為前一層scale的1/2,定義一個segment的cross-layer鄰居為前一層4鄰域更小的segment,即前一層是後一層的鄰居,但後一層不是前一層的鄰居,所以conv4_3的feature layer沒有cross-layer鄰居。圖中所示的黃框為當前層的segment,藍框為上一層更小更細的segment,綠色的線代表cross-layer link有連線,屬於同一文字,在後續的combine演算法中會將他們融合,即去除了冗餘。

讀到這裡我們已經知道如何獲取segment和相應的link了,那接下來要做的就是怎麼把這些link和segment合併成一個完整的文字行。先貼一下論文中使用到的合併演算法:

看起來真的是頭都大,其實思想很簡單,我嘗試用中文解釋一下:

  1. 假設我們有一個集合B,裡面有很多相關聯的segment待合併;
  2. 每一個segment都有自己的角度\(\theta\),那我們求集合B中所有segment角度的平均值\(\theta_{b}\);
  3. 求一條直線L使得所有segment的中心到這條直線的距離最小,也就是最小二乘法線性迴歸啦;
  4. 每個segment的中心往直線L做垂直投影;
  5. 從所有投影點中選出相距最遠的兩個點,記做(xp,yp)和(xq,yq);
  6. 最終合併好的文字框的位置引數記為\((x_{b},y_{b},w_{b},h_{b},\theta_{b})\)那麼\(x_{b}:=1/2(x_{p} + x_{q}\)\(y_{b}:=1/2(y_{p}+y_{q})\)
  7. 文字行的寬度wb就是兩個最遠點的距離(即(xp,yp)和(xq,yq))再加上最遠兩個點所處的segment的寬度的一半(Wp和Wq)。
  8. 文字行高度hb就是所有segment高度求平均值

我畫了下圖輔助理解合併演算法,橙色直線是擬合出的最佳直線,紅色點表示segment的中心,黃點表示紅點在直線上的投影,綠框就是合併後的完整本文框。

這樣子我們就求解完一個完整文字框的所有引數,也就完成了segment合併成文字行的任務。

SegLink演算法對於各種角度的文字檢測具有很強的魯棒性。

SegLink論文中並沒有提到該演算法能不能檢測彎曲的文字,從理論上解讀,SegLink是可以做到的。比如下圖,只是合併演算法要做一些改變而已。

EAST(2017)

對於以上把完整文字行先分割檢測再合併的思路,有人提出質疑,覺得這種做法比較麻煩,把文字檢測切割成多個階段來進行,這無疑增大了文字檢測精度的損失和時間的消耗,對於文字檢測任務上中間處理越多可能效果越差。所以有篇CVPR2017的文章提出,我們有一種方法能優雅且簡潔地完成多角度文字檢測,這個演算法叫做EAST,論文為《EAST: An Efficient and Accurate Scene Text Detector》。

通過下圖我們知道,一個文字檢測有多個階段,就以region proposals系的檢測演算法為例,他們通常包含候選框提取、候選框過濾、bouding box迴歸、候選框合併等階段,EAST的作者認為,一個文字檢測演算法被拆分成多個階段其實並沒有太多好處,實現真正端到端的文字檢測網路才是正確之舉。所以EAST的pipeline相當優雅,只分為FCN生成文字行引數階段和區域性感知NMS階段,網路的簡潔是的檢測的準確性和速度都有了進一步的提高。

我們從網路架構來理解EAST做文字檢測的優勢。首先EAST採取了FCN的思路,一開始我以為EAST是一個通過語義分割來解決文字檢測的難題,深入閱讀後才發現並不是,而只是藉助了FCN的架構做特徵提取和學習,最終還是一個迴歸問題,在EAST最後預測出相應的文字行引數。

EAST網路分為特徵提取層+特徵融合層+輸出層三大部分。

特徵提取層: backbone採取PVANet來做特徵提取,接下來送入卷積層,而且後面的卷積層的尺寸依次遞減(size變為上一層的一半),而且卷積核的數量依次遞增(是前一層的2倍)。抽取不同level的feature map,這樣可以得到不同尺度的特徵圖,目的是解決文字行尺度變換劇烈的問題,size大的層可用於預測小的文字行,size小的層可用於預測大的文字行。

特徵合併層,將抽取的特徵進行merge.這裡合併的規則採用了U-net的方法,合併規則:從特徵提取網路的頂部特徵按照相應的規則向下進行合併,這裡描述可能不太好理解,具體參見下述的網路結構圖。

網路輸出層:網路的最終輸出有5大部分,他們分別是:

  • score map:一個引數,表示這個預測框的置信度;
  • text boxes: 4個引數,(x,y,w,h),跟普通目標檢測任務的bounding box引數一樣,表示一個物體的位置;
  • text rotation angle: 1個引數,表示text boxe的旋轉角度;
  • text quadrangle coordinates:8個引數,表示任意四邊形的四個頂點座標,即(x1,y1),(x2,y2),(x3,y3),(x4,y4)。

所以從整體看來,EAST就是藉助FCN架構直接回歸出文本行的\((x,y,w,h,\theta)\)+置信度+四邊形的四個座標!非常簡潔!但是看到這裡或許會有個問題,為什麼要生成四邊形的四個座標呢?\((x,y,w,h,\theta)\)這個引數不足以解決文字行定位問題?還真不能,看看下面這個圖片。

對於這種帶放射變換的文字行(可能還有的是透視變換),呈現出來的形狀是平行四邊形(黃色虛線為ground true),如果我們以\((x,y,w,h,\theta)\)來表示這個文字的位置,就是粉色框所示,顯然不合適。所以對於這種場合,直接預測四邊形的四個頂點座標才是正確之舉。

EAST目標函式分兩部分,如下,第一部分是分類誤差,第二部分是幾何誤差,文中權衡重要性,λg=1。

Ls稱為分類誤差函式 ,採用 class-balanced cross-entropy,這樣做可以很實用的處理正負樣本不均衡的問題。

其中β=反例樣本數量/總樣本數量 (balance factor)

Lg為幾何誤差函式

對於RBOX,採用IoU loss

角度誤差則為:

對於QUAD採用smoothed L1 loss CQ={x1,y1,x2,y2,x3,y3,x4,y4},NQ*指的是四邊形最短邊的長度

下面看看EAST文字檢測的效果,注意觀察一些帶放射變換or透視變換的文字行的檢測效果。

總結

文字介紹了我一直關注且實驗效果都相當不錯的三個經典的文字檢測演算法,他們都是基於深度學習,可以這麼說,現在做文字檢測都是深度學習的天下了。當然深度學習流派做文字檢測遠不止以上幾個思路,比如基於語義分割的思路做文字檢測的、基於角點檢測做文字檢測、各種方法混合的文字檢測的論文也非常多,同時也取得非常不錯的效果。可以說,現在基於深度學習的文字檢測論文可謂百花齊放。