ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • opencv / pytesseract를 활용한 image2text
    ML, DL & Python/python opencv , pytesseract 2019. 5. 6. 19:03

    안녕하세요 오늘은 opencv 와 pytesseract를 활용한 이미지에 있는 글귀를 text로 인식하는 image2text를 할 예정입니다.

     

    업무를 하면서 크롤링한 이미지를 텍스트로 전환해야 하는 일이 생겼습니다. 제가 말하는 image2text란 무엇이냐?

     

    단순히 그림만이 있는 이미지가 아니라 text를 가지고 있는 이미지의 글자를 실제 text형식으로 뽑아내는 작업을 뜻합니다. 아래의 그림을 보시죠!

    image captioning

     

    이 예시는 image captioning으로 text가 없는 그림에서 그림을 묘사하는 기술을 뜻합니다. 하지만 제가 오늘 하려고 하는 image2text는 예시를 보시죠!

    이미지의 텍스트를 변환한 것

    즉, image2text는 ocr기술이며 그에 따라 지원하는 모듈로는 opencv, pytesseract가 있습니다.

     

    먼저 python에서 해당 기술을 사용하기 전에 선행되어야 하는 작업이 있습니다. 저도 밑의 블로그를 참고하여 진행했는데 굉장히 이해하기 쉽고 간편하게 정리해 주셔서 보시기 편하실겁니다!

     

     

    Python에서 Tesseract 사용하기 for OCR

    Tesseract 이미지로부터 텍스트를 인식하고, 추출하는 소프트웨어를 일반적으로 OCR이라고 한다. Tesseract는 1984~1994년에 HP 연구소에서 개발된 오픈 소스 OCR 엔진이며, 현재까지도 LSTM과 같은 딥러닝 방식을 통해 텍스트 인식률을 지속적으로 개선하고 있다. 지금부터 Python 환경에서 Tesseract를 이용하여 이미지로부터 텍스트 추출하는 방법을 소개한다.

    junyoung-jamong.github.io

     

    자! 그럼 이제 준비가 다 되었다는 가정하에 본격적으로 시작해보도록 하겠습니다.

     

    먼저 이미지를 준비해주세요(제가 준비한 파일이 아니더라도 다른 이미지 파일로 해보시길 바랍니다.)

    ocr테스트이미지.jpg
    0.50MB

     

    1. 그럼 이제 파이썬에서 모듈을 import합니다. 제가 올려드린 블로그의 순서대로 꼭 다운 받길 바랍니다

    from PIL import Image
    from pytesseract import *
    import re
    import cv2

    error가 나오지 않았다면 설치에 성공하신겁니다.

     

    2. 그다음으로 제가 올려드린 이미지 파일을 불러옵니다.

    img = Image.open('ocr테스트이미지.jpg')

     

    3. 불러들인 이미지 파일을 pytesseract를 이용하여 text로 변환시킵니다.

    text = pytesseract.image_to_string(img,lang='kor')#영어면 'euc'

     

    3-1. 해당 이미지를 출력해봅니다.

    print(text)

    text를 print한 것

     

    보시는 것 처럼 이미지를 텍스트화 시킨 것을 볼 수 있습니다. 그렇다면 이미지를 텍스트화 시키기 성공?

     

    물론, 성공이라고 할 수 있습니다. 하지만 이렇게 정제되지 않은 데이터를 어떻게 가만히 있을 수가 있겠나요. 당연히 해당 데이터를 정제된 상태로 옮겨보고자 합니다. 제가 하려는 것은 해당 사진의 사이즈 정보만 출력해서 dataframe화 시키는 작업까지 진행하겠습니다.

     

    4. 먼저 너무 공백이 많기 때문에 단넘기기(\n)를 기준으로 text를 구분해줍니다.

    size_table = re.split('\n',text)

    size_table를 확인해 보시면 리스트 형식으로 단넘기기를 기준으로 text가 구분되어 있는 것을 확인할 수 있습니다.

     

    4-1. 다음으로 사이즈정보를 뽑으려 하는 것이므로 사이즈 정보가 담긴 text를 확인한 뒤 매칭시켜 사이즈 정보만 담긴 text를 추출합니다

    matchers = ['사이즈(','어깨너비','가슴둘레','소매길이','총장']
    size = [s for s in size_table if any(xs in s for xs in matchers)]

    size추출

     

    size를 확인해보면 리스트 형식으로 사이즈 정보만 추출된 것을 확인할 수 있습니다.

     

    5. 제가 말씀드린 dataframe형식으로 만들기 위해 "정규표현식"을 사용하여 데이터를 정제했습니다. 여기서 "정규표현식'은 한번쯤은 공부하시길 추천드립니다. 시간이 난다면 정규표현식에 대해서 정리해 보는 시간도 가져 보겠습니다!

    import pandas as pd
    size2 = []
    for i in range(len(size)):
        size2.append(size[i].split())
        
    if '총장' and '소매길이' and '어깨너비' and '가슴둘레' not in size2[1][0] + size2[2][0]+size2[3][0]+size2[4][0]:
        pass
    else:
        match = re.match(r"([가-힣]+)([(0-9].+)", size2[0][0], re.I)
        if match:
            items = match.groups()
        size2[0][0] = items[0]
    
        size3 = list(map(list, zip(*size2))) #리스트를 transpose하는 법
        #import numpy as np
        #np.array(a).T.tolist() - 똑같은 방법  -> array 변환 -> 전치 -> tolist
        df_size = pd.DataFrame(size3[1:], columns = size3[0])

    사이즈별로 쉽게 정리하기 위해서 추출한 size를 split()를 사용하여 반복문을 통해 리스트로 붙여줍니다.

    size2

    위의 리스트를 보면 필요없는 단어가 섞여있는 것을 확인할 수 있습니다.저희가 필요한 것은 사이즈와 사이즈별로 수치 이므로 "1는몰라", "흥" 등의 단어를 없애야 합니다. 따라서 그 작업을 진행해 보겠습니다.

    size3=[]
    for i in range(len(size2)):
        if len(size2[i]) == len(size2[0]):
            size3.append(size2[i])
        else:
            diff = len(size2[i]) - len(size2[0])
            size3.append(size2[i][diff:])

    size3

     

    6. 이제 마지막 작업으로 dataframe을 만들어 볼텐데요. 위의 형식 그대로 만들기 보다는 카테고리가 column으로 있는 것이 낫다고 생각했습니다. 따라서 list를 행렬로 생각하고 전치(transpose)할 수 있도록 코드를 짰습니다.

    size4 = list(map(list, zip(*size3))) #리스트를 transpose하는 법

    size4

     

    7. list to dataframe

    df_size = pd.DataFrame(size4[1:], columns = size4[0])

    df_size

     

    데이터 정제까지 완료했습니다!

     

    위의 작업을 통해서 알 수 있듯이 pytesseract는 비교적 한글을 잘 인식하는 것 같으면서도 출력상의 오류가 잦습니다. 하지만 만약 인코딩이 한글이 아닌 영어인 경우는 굉장히 잘 인식하는데요. 이것과 더불어서 cctv같이 약간 흐린 화면 상에서의 이미지는 어떻게 잘 인식시킬 수 있을까요?

     

    정답은 opencv를 통해서 흑백처리를 하여 컴퓨터가 더 잘 인식할 수 있도록 만드는 방법에 있습니다. 따라서 기존에 text를 인식시키고자 하는 이미지를 흑백 전처리를 통해서 주변 환경에 구애받지 않고 오로지 text만 잘 인식할 수 있도록 정확성을 개선시키는 것입니다.

     

     

    시간이 있다면 opencv도 같이 활용하여 다른 이미지를 이용해서 인식시키는 작업을 진행해보도록 하겠습니다. 감사합니다.

    https://github.com/minyong-shin/Bloging/tree/master/


    댓글 3

    • 안재범 2020.05.19 15:41

      이미지에 텍스트를 저장하는 방법은 없는지요 ?
      wand 를 사용해서 해 보고 있는데,
      한글이 깨어져서 사용을 못하고 있습니다.

      • 사용자 me뇽 2020.05.21 09:55 신고

        그 부분에 대해서는 아는바가 없어서... 한번 공부해봐야겠네요!

      • 과객 2020.10.19 14:54

        오래된 글인데, 이미 해결하셨는지 모르겠네요.
        PIL 라이브러리 활용하시면 손쉽게 원하는 위치에 글자를 넣을 수 있습니다. 텍스트가 깨지는건 서체 때문이므로 적절하게 서체를 가져와서 작업하시면 됩니다.

Designed by Tistory.