【2021年版】文字検出ってなんですか？

# はじめに
2年目社員の川波（@dcm_ryou-kawanami）です。
この記事は、[NTTドコモ R&D Advent Calendar 2021](https://qiita.com/advent-calendar/2021/nttdocomo)の14日目の記事になります。

我々 NTTドコモ R&Dでは`通信技術`はもちろんのこと、`自然言語処理`，`画像処理`，`ビッグデータ解析`，`クラウド`，`IoT`といった様々な先端技術を学んでおり、若手社員から中堅社員まで日々自己研鑽を行っています。
習得した技術を業務で活かつつ、積極的に社外に発信していくための有志の取り組みとして始めたのが[こちら](https://qiita.com/advent-calendar/2021/nttdocomo)の**NTTドコモ R&D Advent Calendar**になります。

今年度は運営としてNTTドコモ R&D Advent Calendar 2021の取りまとめを行っていますが、今年度投稿者は分野が幅広くギークで面白い人ばかりですのでぜひ[他の記事](https://qiita.com/advent-calendar/2021/nttdocomo)も見ていただけると嬉しいです！

さて、今回の記事ではData Science Cafe #5 [[1]](#参考)で発表した内容をアップデートして`文字検出`のあれこれについて紹介していきたいと思います。

きっと読み終わる頃には「文字検出 *完全に理解した！[^1]*」状態になっていることでしょう...！

<img width="1100" alt="CRAFTの検出結果サンプル画像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/2419dbfb-b263-076e-c27c-af28713738c2.jpeg">
（文字検出データセット[ICDAR2015](https://rrc.cvc.uab.es/?ch=2&com=mymethods&task=1)より）


# 忙しい人向けのまとめ

**4行でわかる「文字検出って何ですか？」**

時間がない人向けにこの記事でお伝えしたいことを4行でまとめました！

- 文字認識を行う前段として、画像中の文字領域を1行で検出する必要がある
- そこで文字を検出するための方法として、`物体検出`よりも文字に特化させた`文字検出`というタスクを解くためのモデルがある
    - **文字検出のポイント1**：さまざまな形状の文字領域を検出できるため、**文字認識の適用範囲を拡張**することができる
    - **文字検出のポイント2**：**文字以外の背景ノイズを除ける**ため、文字認識の精度向上に寄与する

この4行を見て理解できた方は「文字検出 *完全に理解した！[^1]*」人の仲間入りです。

<img width="200" alt="忙しいひと？" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/4df5f5e2-51ca-8eea-1b2b-000fcbf48433.png">

# 想定している読者
もっと記事を見てくれるというそこのあなた、ありがとうございます！
この記事で想定している読者は以下のような方です。

- 近年のOCR技術に興味がある人
- Deep LearningとComputer Visionに興味がある人
- タイトルを見て「**文字検出ってなんですか？**」と思った人

昨今では、文字検出もDeep Learningベースの手法が中心になっているので、Computer Visionの分野に興味がある人には物体検出以外にもこんなタスク・モデルがあったんだという感じで面白いかなと思います！（2年前の自分の感想）

<img width="200" alt="対象としている読者の方" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/529f53d2-faac-d7c9-5d18-8405f66bdb62.png">

# 画像中から文字情報を取得する
まず画像中の文字をデジタル情報としてどのように抽出するのかについて説明します。

基本的には、**「文字検出→文字認識の流れで画像中の文字情報を抽出する」**のが基本的な流れになります。

もっと詳しく説明すると、

- 画像には文字以外の領域も多く含まれているので、文字領域の座標を取得するために**文字検出**を行った後、その文字領域に対して**文字認識**を行うことで**画像中の文字をデジタル情報として抽出**します。
- よって、文字検出と文字認識は別のタスクですが、画像中の文字をデジタル情報にする際には文字検出→文字認識の順に使用することになります。
- ここで、文字認識側で**1行の文字を認識すること**を想定しているため、文字検出で取得する文字領域も1行で取得するタスクになることに注意が必要です。
    - `文字検出`とは画像中から文字を検出するタスク・モデル
    - `文字認識`とは画像中の文字を認識するタスク・モデル

- この**画像から文字をデジタル情報に変換する一連の流れのこと**を`OCR`と呼びます。
- また、最近では`文字検出`・`文字認識`を**同時にEnd2Endで行うDeep Learningベースのモデル**が提唱されており、このタスク・モデルは`Text Spotting` [[3]](#参考)（※FOTS [[5]](#参考)の論文中で提唱）と呼ばれています。


<img width="1000" alt="文字検出とは？" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/53b88cec-714a-2faf-b393-06353f3590ea.png">

# 文字検出と物体検出ってどう違うの？
Computer Vision（画像認識）の分野に詳しい人は
**「[物体検出](https://qiita.com/mshinoda88/items/9770ee671ea27f2c81a9)とどう違うの？」**
と思われるのではないかなと思います。

結論を言うと、**「文字検出は物体検出から派生したものであり、用途の観点で見るとほぼ同じ」**です。
しかし、近年ではより文字を検出することに特化したタスク・モデルが登場しています。
これについては、後半の『[文字検出手法の紹介] (#文字検出手法の紹介)』の見出しで触れていますのでもう少々お待ちください。

- **文字検出と物体検出の違い**：
    - 物体検出を文字を検出するために使うこともできるため、**用途としてはほぼ同じ**
    - しかし物体検出よりもさらに**文字に特化**したタスク・モデルが文字検出である
    
- **文字に特化した点**：
    - さまざまな大きさ・形状を持つ文字を柔軟に検出できるようにした（以下のような例）
        - 斜めに回転した文字
        - アーチ状に曲がったような文字

<img width="650" alt="文字検出と物体検出ってどう違うの？" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/d403f415-4279-9bd9-92c1-c5aca5a254fd.png">

# 文字検出の難しさ
物体検出と比べて文字検出が難しい点は以下のような点です。

- **文字の難しさ：**
    - 検出対象である文字が極端に大きかったり極端に小さかったりスケールが異なる
    - 斜めに傾いたり回転している文字は特徴が異なる
    - フォントやロゴなど多種多様である
    - 横に長いような極端なアスペクト比がある [[2]](#参考)

<img width="1200" alt="画像中の文字の多様性" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/8642a69e-6fc7-1f17-31bc-45ad4909138f.jpeg">
（文字検出データセット[ICDAR2015](https://rrc.cvc.uab.es/?ch=2&com=mymethods&task=1)より）

- **日本語ならではの難しさ：**
    - `英数字`、`記号`に加え、`ひらがな`、`カタカナ`、`漢字`と文字の種類が多いため、**学習データが大量に必要**となります。 [[2]](#参考)
        - アルファベット大文字/小文字（52字）
        - 記号（、。！＠＃＄％＾＆＊（）など）
        - ひらがな（46字）
        - カタカナ（46字）
        - 漢字（常用漢字のみで1945字）

![2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/b886a8d5-646a-be87-ae9e-165fa2397d78.gif)
（[芸術新聞社](http://www.gei-shin.co.jp/books/ISBN978-4-87586-278-9.html)より）

# 文字検出の歴史
**「ふむふむなるほど、次は文字の難しさを解消した最新のモデルが紹介されるんだな...」**と思った方、ちょっと待ってください。

誰かに**「文字検出ってなんですか？」**と聞かれた時、

**「最近ではこう言う文字検出のモデルがあってだね...」**というアンサーだけだとちょっと弱い気がしませんか？
これでは**「最新の文字検出は分かったけど昔はどうやったん？」**と突っ込まれた時に「うぅぅ...」となりかねません。

**「そんなこと言うんだったら、もうちょっと昔の歴史も教えてくれよーーー！」**
そんな方へ向けて、近年の文字検出に至るまでの歴史をまとめてみました。

<img width="850" alt="文字検出の歴史" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/bf6f010e-3a94-91d5-6f9c-fae94b2b2298.png">

- 基本的には、物体検出の派生系なだけあって、**途中までは物体検出の歴史と同じ**です。

- スライディングウィンドウ+局所特徴量を用いるSliding Window + MSER から Deep Learningが登場し、YOLOやSSDといったDeep LearningベースのOne-Shotモデルが登場した2015年あたりまでは物体検出のタスクを文字検出として応用させていただけなので、アーキテクチャも物体検出と同じものを使用しています。
（ちょっと詳しめの方向けの記事ですが、**物体検出手法YOLOまでの歴史**を知りたい方は[こちらの記事](https://qiita.com/cv_carnavi/items/68dcda71e90321574a2b#:~:text=YOLO%E3%81%A8%E3%81%84%E3%81%86%E3%81%AE%E3%81%AF%E3%82%82%E3%81%A8%E3%82%82%E3%81%A8,%E3%83%A2%E3%83%87%E3%83%AB%E3%82%92%E5%90%8D%E4%BB%98%E3%81%91%E3%81%BE%E3%81%97%E3%81%9F%EF%BC%8E)が参考になるかもしれません。）

- **新しいアーキテクチャを持つ文字検出手法**が本格的に登場してきたのは、2015年に発表された**TextBoxes** [[4]](#参考)あたりからです。このTextBoxesも物体検出手法のSSDを文字検出用に改良したものであり、この辺りから『[文字検出の難しさ](#文字検出の難しさ)』の見出しで紹介した、文字特有の難しさに対処するモデルが台頭してきました。

- 近年では、傾いていることの多い文字に対応するべく、2017年に回転した斜めの文字領域を取得できる**EAST** [[5]](#参考)が登場し、2018年には、文字検出と文字認識を同じモデルでEnd2Endに同時に出力してしまう**FOTS** [[6]](#参考)（**Text Spotting**モデル）まで現れました。2019年には湾曲した文字領域まで取得できるモデルである**CRAFT** [[7]](#参考)が登場するなど、多種多様な発展が見られます。

- これからの文字検出の注目分野としては、Youtubeの字幕のような**「画像を横断くらい横に長いアスペクト比の文字領域をどのように検出するのか」**、アラビア文字のように絵に近く風景に溶け込んでいるような**「多種多様な言語をどのように検出するのか」**といったところのようです。[[7]](#参考)

これからも発展し続ける文字検出に要チェックです！

# 文字検出手法の紹介
それでは簡単ではありますが最近の文字検出手法のうち気になる手法について紹介していきたいと思います。
今回紹介する文字検出手法3つは全てCVPR[^2]で発表された手法です。
余談ですが、文字検出でTextというだけあって手法の名前に**"T"**がつくものが多いですね！

## 1. EAST [[5]](#参考)
まずはCVPR2017で発表されたEASTです。
屋外で撮影された画像中の文字は斜めに回転して傾いているような文字が多く、これによって文字以外の背景領域の画像が入ることが後段の文字認識の精度を悪化させる一つの要因になっていました。
EASTはそんな斜めに回転して傾いている文字領域を背景が入らないように、**文字が斜めに傾いた状態のまま検出してくれるモデル**です。

<img width="1500" alt="文字検出の歴史" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/56a8edc5-7314-0c28-3753-6094c625abd7.png">

### 1.1. アーキテクチャ
- 特徴抽出を行うバックボーンはピクセル単位でのクラスを分類するセマンティックセグメンテーションのタスクで使われる**FCN**を採用しています。
    - FCNを採用した理由は、論文中に明示的にはなかったのですが、画像中の文字は小さくて複雑なものが多いため、より小さくて複雑な文字でも検出できるようにピクセル単位のセグメンテーションベースのモデルを採用しているのだと思います。
- アーキテクチャからの出力は以下です。
    - **text score map**: 文字領域である確率をピクセル単位のスコア付したマップ情報（Figure4. (a)(b)）
    - **text boxes**: RBOX geometryを元に作成
        - **RBOX geometry**: それぞれのピクセルからピンクの長方形の境界までの距離情報を書くチャネルとして用意（Figure4. (c)(d)）
    - **text rotation angle**: 水平線に対して文字領域を示すピンクの矩形が傾いている回転角を用意（Figure4. (e)）

<img width="1100" alt="EAST アーキテクチャ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/2e5e04d1-8fd4-9cce-3267-9d60bf2b9cd8.png">

### 1.2. Loss
- Lossでは**Text Score Mapの項**に加えて、Text Boxesが正解とどれだけ一致しているのかを示す**IoUの項**と、斜めに回転した文字に対応するために追加された**回転角の項**を入れていることが特徴的です。

<img width="1100" alt="EAST Loss" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/43235c25-aceb-c600-d4c8-8803ddd870bf.png">

### 1.3. モデル出力後の後処理
- モデルの出力である斜め文字領域の頂点を示す(x.y)座標4点の出力は、アーキテクチャの出力であるtext boxesとtext rotation angleを元に後処理で出力

## 2. FOTS [[6]](#参考)
次にCVPR2018で発表されたFOTSです。
これまでは文字検出モデルと文字認識モデルをそれぞれ組み合わせてOCRを行う方法が主流でした。
しかしこのFOTSは**1つのモデルで文字検出+文字認識を同時に行うことのできるモデル**になっています。
前半でもお話しした**Text Spottingモデル**です。
文字検出と文字認識をEnd2Endに学習するため、文字検出と文字認識に使う学習データがセットとして必要になってきますが、それぞれ独立していたものを1つのモデルで行えるようにしたというところが本手法のすごいところです。
1つのモデルにしたことで処理計算のロスを減らすこともできており、文字認識とのマルチタスクにすると文字検出の方も精度が向上したりと、処理時間の削減・精度向上を実現しています。
文字を検出するだけでなく、その場所の文字も1つのモデルで同時に予測している結果が右側の図から見てとれますね。

<img width="750" alt="EAST Loss" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/cc796070-f0d1-5d12-67b6-1e1b27cbd114.png">


### 2.1. アーキテクチャ
- Faster RCNN構造のRoI部分が回転に対応(RoIRotate)し、**文字認識のBranch**を追加した構造になっています。
- **RoIRotate**により、検出において回転したbboxから得られる畳み込みの特徴を認識のBranchで共有することができる。
- 回転矩形を水平に戻すときに、NW内でAffine変換してBilinear補間する方法を実現した。
- max-poolを使う方法だと出力特徴の長さが丸められてしまう欠点を、Bilinear補間により長さを可変することで解消し、これにより細長い文字にも対応できて認識でも使える特徴になった。

<img width="1100" alt="EAST Loss" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/31c771fa-559a-1f88-1d2e-aff846ec5dbf.png">


## 3. CRAFT [[7]](#参考)
最後にCVPR2019で発表されたCRAFTです。
文字の中には様々な形状の文字があり、斜めに回転しているものもそうですし、中には図に示すようなアーチ状の文字などもあります。
CRAFTは1文字単位のレベルで文字を検出し、後処理でくっつけることにより、いろんな向き・形状の文字を検出することのできるモデルです。

<img width="1100" alt="CRAFTの検出結果サンプル画像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/afe38d9c-6b9f-7cef-c64e-d8ac39a40f5c.png">


### 3.1. アーキテクチャ
アーキテクチャの基本構成はVGGベースのFCN

<img width="500" alt="CRAFT アーキテクチャ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/b7de828e-06f2-2da4-39b7-9d9028b966e2.png">


### 3.2. 文字の隙間を学習させる
- 1文字ごとに分けて認識する上で、**文字間隔の狭い日本語に対応**するために文字の隙間に注目する**affinity score**を持ちます。
- また、1文字単位で細かい特徴を扱いたいので**heatmapを採用**しています。

<img width="1000" alt="CRAFT 文字の隙間を学習させる" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/411b1513-947e-2cf1-e7d3-80d065f7f580.png">

### 3.3. 弱教師あり学習の工夫
以下の2つのステップで弱教師学習を行うことにより**文字単位のアノテーションでコストがかかる**という課題を改善しています。

- 1stステップ：**文字を合成した画像を生成**してそのheatmapを事前学習
- 2ndステップ：**実画像の単語単位のアノテーションを文字単位に分割**してheatmapの正解データを作り追加学習

<img width="1000" alt="CRAFT 弱教師あり学習の工夫" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238004/430c6ebc-cc96-dec6-a890-59fa5c0dbe78.png">

### 3.4. モデル出力後の後処理
- 推論時は**1文字単位のBBoxを繋げて**斜めに傾いた文字やアーチ状など文字など**様々な形状の文字領域を出力**します。

# さいごに
本稿では「文字検出ってなんですか？」の質問にアンサーすべく、文字検出とは何かから最新手法までをご紹介してきました。
個人的にも分野的にも「OCRなんてオワコンじゃん、文字認識なんてMNISTでやってるし簡単でしょ」ということは全然なく、**文字検出・文字認識を含めOCRはまだまだ発展している分野**なのだということをお伝えできていれば嬉しい限りです！

また、[NTTドコモ R&D Advent Calendar 2021](https://qiita.com/advent-calendar/2021/nttdocomo)はまだまだ続きますので、面白いと思っていただけたら[こちら](https://qiita.com/advent-calendar/2021/nttdocomo)の**「タイトル右下の☆ボタン」**を押して購読していただき続きの記事をチェックしてみてください。

それではー！

# 参考
- [1] [Data Science Cafe #5](https://data-science-cafe.connpass.com/event/215286/)
<iframe src="//www.slideshare.net/slideshow/embed_code/key/eFJDsFNQa0DA3T" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/RyoKawanami/text-detection-datasciencecafe210309slideshare-248543439" title="Text detection data_sciencecafe_210309_slideshare" target="_blank">Text detection data_sciencecafe_210309_slideshare</a> </strong> from <strong><a href="https://www.slideshare.net/RyoKawanami" target="_blank">RyoKawanami</a></strong> </div>

- [2] [日本語OCRはなぜ難しい？NAVERのエンジニアが語る、テキスト検出における課題と解決策](https://logmi.jp/tech/articles/322529)
- [3] [Paper with Code : Text Spotting
](https://paperswithcode.com/task/text-spotting)
- [4] [TextBoxes: A Fast Text Detector with a Single Deep Neural Network (AAAI2017)](https://arxiv.org/abs/1611.06779)
- [5] [EAST: An Efficient and Accurate Scene Text Detector (CVPR2017)](https://openaccess.thecvf.com/content_cvpr_2017/html/Zhou_EAST_An_Efficient_CVPR_2017_paper.html)
- [6] [FOTS: Fast Oriented Text Spotting with a Unified Network (CVPR2018)](https://openaccess.thecvf.com/content_cvpr_2018/html/Liu_FOTS_Fast_Oriented_CVPR_2018_paper.html)
- [7] [CRAFT: Character Region Awareness for Text Detection (CVPR2019)](https://openaccess.thecvf.com/content_CVPR_2019/html/Baek_Character_Region_Awareness_for_Text_Detection_CVPR_2019_paper.html)


[^1]: [エンジニアの言う「完全に理解した」・「チョットデキル」の意味は？](https://ksk-agent.com/%E3%83%AA%E3%82%A2%E3%83%AB%E3%83%A9%E3%82%A4%E3%83%95/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E8%A8%80%E3%81%86%E5%AE%8C%E5%85%A8%E3%81%AB%E7%90%86%E8%A7%A3%E3%81%97%E3%81%9F/)
[^2]: [CVPR](https://cvpr2022.thecvf.com/)は画像処理・画像認識におけるトップカンファレンスで、その界隈では一目置かれる国際学会です。