Group Study (2020-2021)/Machine Learning

[Machine Learning] 8주차 스터디 - 이미지 내 문자 인식(OCR) + 마스크 착용 여부 분류 프로그램

parang99 2020. 12. 2. 18:48

1. 이미지 내 문자 인식(OCR) 맛보기

1) tesserocr 라이브러리 설치

Anaconda 터미널에서 가상환경(ex. MLStudy)을 activate 하고 tesserocr를 설치합니다. 

(base) >conda activate MLStudy
(MLStudy) >conda install -c conda-forge tesserocr

tesserocr 라이브러리 관련 추가 설명이나 다른 설치 방법은 링크를 참고하세요 : tesserocr · PyPI

 

가상환경에서 Jupyter Notebook를 실행해 tessorocr의 버전과 언어를 확인합니다. 

import tesserocr
from PIL import Image

print(tesserocr.tesseract_version())  # print tesseract-ocr version
print(tesserocr.get_languages())  # prints tessdata path and list of available languages

# Output
# tesseract 4.1.1
#  leptonica-1.78.0 (Sep 28 2020, 16:25:11) [MSC v.1916 LIB Release x64]
#   libjpeg 9d : libpng 1.6.37 : libtiff 4.1.0 : zlib 1.2.11 : libopenjp2 2.3.1
# ('C:\\Users\\User\\anaconda3\\envs\\MLStudy/tessdata/', ['eng', 'osd'])

tesserocr.get_languages()는 tessdata 경로와 지원되는 언어 목록을 알려줍니다. 

지원 언어 목록에 한글이 없으니 한글 데이터를 추가해봅시다. 

 

한글 데이터 다운로드 링크 / 다른 언어 데이터 다운로드 링크

위 링크에서 다운로드한 파일을 tessdata 폴더에 넣고 'Hangul' 언어가 추가되었는지 확인합니다. 

 

# 디렉터리 위치 확인
print(tesserocr.get_languages()[0])
# Output
# C:\Users\User\anaconda3\envs\MLStudy/tessdata/

# 지원되는 언어 다시 확인
print(tesserocr.get_languages()[1])
# Output
# ['Hangul', 'eng', 'osd']

 

2) 문자 인식 실습

먼저 영어 버전 실습부터 해보겠습니다.

현재 python 파일이 있는 곳에 Image 폴더를 만들어 english.png라는 이미지를 저장해주세요. 

# 영어 버전
path = './Image/english.png'
image = Image.open(path)
display(image)
print(tesserocr.image_to_text(image, lang='eng'))  # print ocr text from image

image를 불러와 tesserocr.image_to_text()의 language를 'eng'(영어)로 하면 아래와 같은 결과가 나옵니다. 

english.png

# Output
_ Tesseract Will
Fail With Noisy
_ Backgrounds —

 

한글 버전은 korean.png라는 이미지를 Image 폴더 안에 저장하고 코드를 실행하면 됩니다. 

language는 'Hangul'(한글)로 해주세요. 

# 한글 버전
path = './Image/korean.png'
image = Image.open(path)
display(image)
print(tesserocr.image_to_text(image, lang='Hangul'))  # print ocr text from image

korean.png

# Output
소년

여기저기서 단풍잎 같은 슬픈 가 을 이 똑똑 떨어진다. 단풍잎
펼 어져 나은 자 리 마다 봄 을 마 견해 높고 나 못 가 지 위에 하 늘 이
펼쳐 있다. 가만히 하 늘 을 들 여 다 보려면 눈 썸 에 파란 룰 감 이
든 다 . 두 손 으로 따뜻한 불 을 쓸어 보면 손 바 닥 에도 파란 물감
이 묻 어 난다. 다시 손 바 닥 을 들 여 다 본다. 손 금 에는 맑은 강물
이 츠 르 고 , 맑 은 강 물 이 흐르고, 강 룰 속에는 사 랑 처럼 숄 픈 열
굴 ㅡ 이 름 다운 순 이 의 열 굳이 어 린 다. 소 년 은 황 출 히 눈 을
감 아 본 다. 그래도 맑은 강 물 은 훌러 사 랑 처럼 슬픈 얼 굴 ㅡ -
아름다운 순 이 의 열 굴 은 어 린 다.

 

3) 문자 인식을 활용한 프로젝트 아이디어

     - 신분증, 카드에서 정보 추출

     - 스캔한 pdf 문서 ocr 변환

     - 사진 속 외국어 번역해주는 앱

     - 시각장애인을 위한 상품 상세 설명 문자 인식 안내 서비스 등

 

2. 마스크 착용 여부 분류 프로그램 작성하기

1) 캐글에서 모델 만들기

마스크 분류(mask classification)에 사용하는 모델은 직접 작성하지 않고 Kaggle(캐글)을 참고합니다. 

캐글 데이터세트 : Kaggle Dataset : Face Mask Detection

참고할 캐글 노트북 : Kaggle Notebook : Fastai- mask classification

     (1) 위 노트북을 [Copy and Edit]하여 모든 코드를 실행합니다. 

     (2) 제일 아래 코드의 주석을 풀고 model.pkl을 생성합니다. 

# model.export("/kaggle/working/model.pkl")

     (3) /kaggle/working/model.pkl을 다운로드합니다. 

     (4) Model 폴더를 만들어 다운받은 모델 파일을 옮깁니다. 

 

2) fastai 라이브러리 설치

!pip install fastai==1.0.60

여기서 fastai 버전은 1로 설치해주세요. 

참고 : 저는 이 과정에서 에러가 발생했고 pytorch와 visual studio c++ build tool을 설치 후 에러가 해결됐습니다. 

fastai 라이브러리 관련 추가 설명이나 다른 설치 방법은 링크를 참고하세요 : fastai · PyPI

 

프로그램을 작성하기 전 필요한 라이브러리를 가져옵니다. 

import warnings
warnings.filterwarnings('ignore')

import fastai
fastai.__version__
# Output
# '1.0.60'

import cvlib as cv
import cv2
import torch
import time
import imutils
from PIL import Image as PImage
from matplotlib import pyplot as plt
from fastai.vision import *
from torchvision.transforms import Compose, Resize, ToPILImage, ToTensor

7주차에서 사용한 cvlib의 얼굴 인식(Face Detection) 함수를 이용합니다. 

 

3) 마스크 착용 여부 분류 프로그램 작성

웹캠으로 실시간 영상을 가져와 마스크 착용 여부를 알려주는 프로그램 코드입니다. 

# 캐글에서 만든 모델 가져오기
learn = load_learner("./Model", 'model.pkl')

# Transform image
transformations = Compose([
        ToPILImage(),
        Resize((224, 224)),
        ToTensor(),
    ])
    
webcam = cv2.VideoCapture(0)

if not webcam.isOpened():
    print("Could not open webcam")
    exit()

while webcam.isOpened():
    status, frame = webcam.read()

    if not status:
        print("Could not read frame")
        exit()

    im = cv2.flip(frame, 1)
    
    # cvlib 의 얼굴 인식 함수를 사용
    faces, confidences = cv.detect_face(im)
    
    # face 의 좌표 가져오기
    for face in faces:
        (startX,startY) = face[0],face[1]
        (endX,endY) = face[2],face[3]
        
        # 사진에서 얼굴 부분만 크롭
        face_crop = im[startY:endY, startX:endX]
        
        # face_crop 이미지를 BGR 에서 RGB 로 변환
        face_RGB = cv2.cvtColor(face_crop, cv2.COLOR_BGR2RGB)
        
        outImg = Image(transformations(face_RGB))
        
        # learn.predict() 을 이용하여, outImg 의 결과를 받아옴
        pred_class, pred_idx, class_scores = learn.predict(outImg)
        
        text = f'{pred_class}, {int(class_scores[pred_idx]*100)} accurate'
        cv2.putText(im, text, (startX,startY), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
    
    cv2.imshow("Real-time video", im)

    # 키보드의 'q'를 누르면 프로그램이 종료됨
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

webcam.release()
cv2.destroyAllWindows()

위 코드는 mask-detection-on-webcam을 참고했습니다.