Machine Learning/CV

EAST & CRAFT (EasyOCR)

elevne 2022. 11. 13. 15:09

저번에는 CRNN을 이용해서 OCR을 진행하는 법에 대해 알아보았다. 이번에는 단순 OCR이 아닌 Scene Text Detection을 진행하기 위해 사용되는 EAST, CRAFT 모델에 대해 알아보고 이를 EasyOCR을 활용하여 코드로 실습해보았다.

 

 

 

Scene Text Detection / Recognition은 일상적인 풍경 이미지에서 글자가 있는 영역을 탐지하고 이를 컴퓨터 문자로 변환하는 문제를 뜻한다. Traditional OCR은 배경이 단순, 글씨체는 규칙적, 글자배열은 수평적, 색은 단조롭다. 하지만 Scene Text 문제는 이보다 훨씬 복잡하다. 이미지의 배경은 복잡하며 글씨체도 다양하고, 글자배열의 각도 및 구도가 다양하며 색도 다채롭게 사용되어 있다.

 

 

 

Scene Text Detection은 다음과 같은 다음과 같은 문제들을 해결하고자 한다.

 

1. 수평으로 되어있지 않고 비스듬하거나 회전된 단어를 탐지 (Arbitrary-Oriented / Multi-Oriented)

2. 서로 겹쳐져 있는 문자 판별 (Occlusion)

3. 곡선형으로 나열된 단어 판별 (Curved Text)

 

 

 

기본적으로 Scene Text Detection 문제는 글자가 위치한 Bounding Box의 좌표를 정확하게 맞추는 것이 목표이기 때문에 Regression 문제로 접근한다. 여기서 글자가 위치한 영역을 Region Proposal 혹은 Region of Interest(ROI)라고 부른다.

 

 

 

 

 

 

이는 주로 CNN으로 이미지의 Feature Extraction을 진행한 뒤, Decoder을 통해 단어 영역을 생성해내는 방식으로 이루어진다. 단어 영역이 될 만한 여러 후보(Anchor Box)를 만든 뒤 ROI를 추려내는 고전적인 Object Detection 방식도 사용된다고 한다. 또, 단어 정합성을 높이기 위해 글자와 글자 사이 여백을 각각 탐지해 하나의 단어 영역으로 합치는 방식의 알고리즘도 다수 제안되었다고 한다.

 

 

 

Scene Text Detection의 대표적인 모델로 EAST (An Efficient and Accurate Scene Text Detector)을 알아보았다. 이는 2017년 중국에서 발표된 논문에서 처음 소개되었다고 한다. 

 

 

기존 Text Detection 모델들이 Convolution 블록을 여러 번 거치게 한 것과 달리 하나의 Convolution 블록으로 줄여서 연산 시간을 대폭 단축했다고 한다. 또 이미지 분할을 위해 고안된 Fully Convolutional Network를 활용하여 단어가 포함된 Rotated Rectangle 또는 Quadrilateral Box를 예측한다.

 

 

 

Fully Convolutional Network는 U-Net의 기본개념이기도 한데, 이는 Semantic Segmentation을 위해 기존 이미지 분류에서 쓰인 CNN 기반의 모델을 목적에 맞춰 변형시킨 것이다. 기존 CNN 기반의 Image Classification 모델들은 출력에서 이미지를 분류하기 위해 출력층이 Fully Connected Layer로 구성되어 있었는데 이 방식은 Semantic Segmentation에서 몇 가지 단점이 생겼다.

 

 

1. Convolution 연산에서는 위치정보가 유지되지만 Fully Connected Layer을 실행하면 위치정보가 사라진다.

 

2. 마지막 Dense Layer이 고정되어 있기 때문에 가중치 유지를 위해서는 결국에 Input Size도 동일해야 한다.

 

 

이러한 문제점을 해결하고자 Fully Connected Layer에서 Dense Layer을 Convolutional Layer로 대체하는 방식을 고안해낸다. 이 방식을 통해 Output은 이미지의 위치정보를 내포하게 된다.

 

 

 

이 과정에서 Feature Map을 원본 이미지의 픽셀과 가까운 Dense Map으로 변환해주기 위해 아래와 같은 방법이 사용된다.

 

 

 

FCN

 

 

1. Bilinear Interpolation: Interpolation(보간)이란 알려진 값 사이에 위치한 값을 추정하는 것을 뜻한다. Linear Interpolation(선형보간법)은 두 점의 값이 주어졌을 때 그 사이에 위치한 값을 추정하기 위하여 직선 거리에 따라 선형적으로 계산하는 방법이다. Bilinear Interpolation은 선형 보간법을 2차원으로 확장한 것으로, 선형보간을 바탕으로 수행되는데 화소당 선형 보간을 세번 수행하고 새롭게 생성된 화소는 가장 가까운 화소 4개 가중치를 곱한값을 합해서 얻게 된다.

 

 

2. Backwards Convolution: Convolution 연산을 반대로 실행하여 Up-sampling의 효과를 본다.

 

 

3. Skip Architecture: 깊은 층의 정보를 얕은 층의 정보와 결합하여 사용한다. (Upsampling)

 

 

 

다시 EAST로 돌아와서 EAST는 기본적으로 512*512 RGB 이미지를 Input으로 받고, Output으로는 Rotated Rectangle Bounding Box의 5개 정보(x1, y1, w, h, angle)를 반환한다. 이 과정에서 FCN 구조를 사용하여 더욱 정확한 Localization을 하고자하는 것이다. 

 

 

 

이 FCN을 지나고 나면 처음 이미지와 유사한 사이즈의 Score Map이 생성되게 된다. 이 Score Map은 각 픽셀이 단어 영역 내에 있을 확률(0~1)을 나태나고 있는 것이다. 단어 Box를 추정한 후에, 각 픽셀과 Box의 4개 변 사이의 거리 정보를 구하여 단어 영역의 중심에 대한 정보를 구하고, 단어 Box가 회전된 각도를 구해낸다.

 

 

 

이후에 Scene Text Recognition(각 단어 영역이 어떤 문자인지를 찾는 Classification 문제)을 진행하게 된다. 단어 영역에 해당하는 이미지로부터 특징을 추출해낸 후 Sequential 하게 만들어 각 글자의 조합(단어)를 찾아가는 방식을 사용하는데 이 때는 RNN이 사용된다. RNN을 거치며 Character 단위로 출력이 나오게 되고 예측을 한 후에 글자의 조합을 알아보는 것이다. 여기서 RNN을 사용하는 이유는 이미지마다 글자의 크기, 배치가 다르기 때문에 글자 단위로 정확하게 나누는 것은 어렵기 때문이다. 또, Feature Map의 부분적 정보만을 이용해서 글자를 예측하려면 앞뒤의 다른 정보를 종합적으로 고려해야 한다.

 

 

 

EAST는 이렇게 알아보았고 그 다음으로 이와 유사한 CRAFT(Character Region Awareness for Text Detection)에 대해 알아보았다. CRAFT 이전의 모델들은 Rigid Word-level Bounding Boxes(Bounding Box를 네모 형태로만 예측하게 되는 것) Model 이었다. CRAFT는 완전 곡선 형태로 되어있는 글자들도 인식할 수 있는 모델이다.

 

 

 

CRAFT

 

 

 

CRAFT는 단어 단위로 예측하지 않고 Character 단위로 예측을 진행한다. 이를 의미구조 단위로 묶어주기 위해 Affinity Score라는 것을 예측하여 이를 기반으로 Character를 합치는 과정을 거치게 된다.

 

 

EAST와 Architecture가 유사하지만 EAST를 포함한 이전 모델들보다 더 좋은 성능을 보여준다고 한다. 완전 곡선 형태의 글자들도 인식한다. Loss Function은 Score Map, Affinity error 값을 넣어주어 MSE를 계산한다.

 

 

 

그럼 이제 위 CRAFT 기반의 OCR 모델을 직접 코드로 사용해보겠다. 이전에 사용했던 Keras-OCR 라이브러리를 사용할 수 있지만 이번에는 더 쉽게, 한국어 OCR을 진행할 수 있는 방법을 사용해보았다. 바로 Easy OCR 라이브러리이다. 이는 Github에 OpenSource로 공개되어있고, Tesseract보다 더욱 높은 정확도를 보이며 다양한 언어를 제공한다고 한다. Easy OCR은 CRAFT 기반의 Detection  Model, CRNN 기반의 Recognition을 수행한다(Resnet LSTM CTC). 또한, 오타 보정을 위한 Greedy, Beamsearch, WordbeamSearch 또한 옵션으로 제공된다고 한다. 사용법이 매우 간단하고 추후 지속적인 업데이트도 예고되어 있어서 OCR을 심플하게 비즈니스에 적용하기에 좋은 오픈소스라고 한다. 우선 pip install 을 진행해준다.

 

 

 

pip install easyocr

 

 

 

그 후에 우선 필요한 라이브러리들을 아래와 같이 import 해준다.

 

 

 

import easyocr
import numpy as np
import cv2
import random
import matplotlib.pyplot as plt
from PIL import ImageFont, ImageDraw, Image

 

 

 

사용방법은 간단하다. 우선 easyocr의 Reader 객체를 만들어준다. 만들어줄 때, 어떠한 언어 OCR 모델을 사용할 것인지 지정해주어야 한다. 아래에서는 한국어와 영어를 인식하는 모델을 선택하였다. Reader를 만들어주었다면 Reader.readtext() 함수를 사용하는데, 이 안에 분석하려는 이미지가 위치한 경로를 넣어주기만 하면 된다. 코드는 아래와 같이 작성하였다.

 

 

 

reader = easyocr.Reader(['ko','en'], gpu=True) # this needs to run only once to load the model into memory
result = reader.readtext('/content/drive/MyDrive/Colab Notebooks/test.png')

 

 

result

 

 

 

아주 손쉽게 OCR을, 꽤나 높은 정확도로 진행할 수 있는 것을 확인할 수 있다. 이제 이 결과를 이미지 상에서 확인하기 위해 코드를 작성해주어야 했다.

 

 

 

reader = easyocr.Reader(['ko', 'en'], gpu = True)
result = reader.readtext('/content/drive/MyDrive/Colab Notebooks/test.png')
img    = cv2.imread('/content/drive/MyDrive/Colab Notebooks/test.png')
img = Image.fromarray(img)
font = ImageFont.truetype('/content/drive/MyDrive/Colab Notebooks/BMEULJIROTTF.ttf', 20)
draw = ImageDraw.Draw(img)
np.random.seed(42)
COLORS = np.random.randint(0, 255, size=(255, 3),dtype="uint8")
for i in result :
    x = i[0][0][0] 
    y = i[0][0][1] 
    w = i[0][1][0] - i[0][0][0] 
    h = i[0][2][1] - i[0][1][1]

    color_idx = random.randint(0,255) 
    color = [int(c) for c in COLORS[color_idx]]

    draw.rectangle(((x, y), (x+w, y+h)), outline=tuple(color), width=2)
    draw.text((int((x + x + w) / 2) , y-2),str(i[1]), font=font, fill=tuple(color),)

plt.figure(figsize=(50,50))
plt.imshow(img)
plt.show()

 

 

 

 

 

결과는 위와 같이 나온다. 다음 시간에는 이를 더 활용해보는 법에 대해 알아보도록 하겠다!

 

 

 

출처:

https://yunwoong.tistory.com/76

https://github.com/JaidedAI/EasyOCR/tree/master/unit_test

https://medium.com/@msmapark2/character-region-awareness-for-text-detection-craft-paper-%EB%B6%84%EC%84%9D-da987b32609c

https://www.youtube.com/watch?v=_4CFxre4b1s