본문 바로가기
개발 관련 지식/잡동사니

[Pillow] 영상에 한자 텍스트 입력하기

by rahites 2024. 6. 28.

일본 박람회를 준비하던 중 박람회에서 발표하는 영상이 일본어로 이루어져 있다면 지나다니는 행인들의 관심을 쉽게 끌고 좋은 이미지로 어필할 수 있을 것이라 생각했다.

 

그러기 위해 기존에 제작해둔 샘플 영상 속 영어를 일본어로 만들 필요가 있었고, 이러한 문제를 잘 해결하기 위해 내가 직접 진행한 방법을 정리해 보려 한다.

 

활용 OS : Ubuntu 22.04


기존 Visualize 코드의 문제점은 OpenCV를 활용하면 일본어 폰트를 영상속에 합성할 수 없다는 것이었다. 따라서 이 문제를 해결하기 위해 내가 진행한 전체적인 방법을 정리해보면 아래와 같다.

1. Ubuntu에 일본어 폰트를 설치
2. Opencv로 PutText를 진행해주었던 것 → Pillow 패키지를 이용하여 draw
3. Opencv로 텍스트 크기를 구했던 것 -> Pillow 패키지를 활용해 텍스트 크기를 구한 후 영상 속에 텍스트를 삽입

 

1. Ubuntu에 일본어 폰트 설치하기

일본어 폰트는 기본적으로 설치되어 있지 않기 때문에 OS에 먼저 일본어 폰트를 설치해 주어야 한다.

 

참고한 블로그는 아래와 같다.

https://bill1224.tistory.com/384

 

[ ubuntu ] 일본어 폰트 패키지 설치 && matplotlib에 적용

takao 폰트 설치 sudo apt install fonts-takao 폰트 확인 ls -al /usr/share/fonts/truetype ubuntu의 공용 font 경로를 확인해보면 takao 폰트가 설치된 것을 확인할 수 있습니다. 폰트 캐시 삭제 fc-cache -fv 폰트 배포 mat

bill1224.tistory.com

원하는 일본어 폰트를 설치하였고 Ubuntu의 Font 저장 경로에서 내가 사용하고 싶은 ttf 파일을 선택하여 사용하였다.

# 사용가능한 폰트 확인
ls -al /usr/share/fonts/truetype

 

 

2. Pillow 패키지 활용하기

기본적으로 OpenCV 패키지를 사용하면 영상 속에 일본어를 넣어줄 수가 없다. 따라서 OpenCV 패키지 대신 Pillow를 사용해 주어야 하는데, 내가 사용하고자 하는 폰트 경로만 잘 넣어주면 큰 문제 없이 일본어를 인식시킬 수 있다.

 

from PIL import Image, ImageFont, ImageDraw

# 이전에 f_cnt(현재 frame number), 카메라 fps 변수 설정
current_time = f_cnt / fps
time_text = str(f"時間: {current_time:.2f}秒")

# 이전에 frame 변수 설정
frame = Image.fromarray(frame)
fontpath = "/usr/share/fonts/truetype/fonts-japanese-mincho.ttf"
font = ImageFont.truetype(fontpath, 20)
draw = ImageDraw.Draw(frame, 'RGBA')

text_width_time, text_height_time = get_text_dimensions(time_text, font)
b,g,r,a = 255,255,255,255

text_x_time, text_y_time = frame.width - text_width_time - 10, 10
draw.text((text_x_time, text_y_time), time_text, font=font, fill=(b,g,r,a))

frame = np.array(frame)
  • f_cnt : 현재 frame number
  • fps : 영상 fps
  • frame : 처리할 영상

 

이 때 get_text_dimensions라는 함수를 사용하여 텍스트의 크기를 파악하였는데 그 코드는 아래와 같다.Pillow 패키지를 이용하여 텍스트의 사이즈를 측정하는 코드로 Stackoverflow를 참고하여 코드를 작성하였다.

def get_text_dimensions(text_string, font):
    """텍스트의 크기 파악"""
    ascent, descent = font.getmetrics()

    text_width = font.getmask(text_string).getbbox()[2]
    text_height = font.getmask(text_string).getbbox()[3] + descent

    return (text_width, text_height)

https://stackoverflow.com/a/46220683/9263761

 

How to get the font pixel height using PIL's ImageFont class?

I am using PIL' ImageFont module to load fonts to generate text images. I want the text to tightly bound to the edge, however, when using the ImageFont to get the font height, It seems that it incl...

stackoverflow.com

 

 

결과 예시

 

일본어(한자)가 영상 속에 잘 합성된 것을 확인할 수 있다.


참고자료

https://levelup.gitconnected.com/how-to-properly-calculate-text-size-in-pil-images-17a2cc6f51fd

 

How to properly calculate text size in PIL images

Finding the text size in PIL is confusing, so today I’m showing a possible way of doing it.

levelup.gitconnected.com

 

댓글