OpenCV+Pillow로 동영상에 초 단위로 변경되는 일본어 텍스트 표시

12364 단어 파이썬pillowOpenCV

소개



업무로 초단위의 센서 정보 텍스트 데이터를 동영상에 직접 연결하기 위해 동영상에 초단위로 일본어 텍스트를 표시하는 작업을 실시했다.
그 때 조금 힘들었기 때문에, 텍스트 표시용의 Python 실행 코드 샘플을 비망록도 겸해 소개합니다.

했던 것 (프로그램 입출력 내용)



입력 동영상보다 아래 출력 동영상처럼 초단위로 변화하는 일본어 텍스트를 표시할 수 있도록 했다.

・입력 동영상 (※ htps //w w. 호메도 ゔ아. 비·f레에_도ごぃ에. HTML 로부터 취득)


・출력 동영상


실행 코드



동영상의 프레임 입출력에 OpenCV(v4.5.1), 일본어 텍스트 기입에 Pillow(v7.0.0)를 이용하고 있다.
※ OpenCV에서도 putText 메소드에 의해 텍스트 기입은 가능하지만, 일본어·개행에 비대응

폰트는 프로그램내의 정수 「FONT_PATH」로 기호로 변경해 실행해 주세요.

write_text_on_video.py
"""動画へのテキスト書き込みプログラムサンプル"""
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont

# Windows
FONT_PATH = "C:\Windows\Fonts\meiryo.ttc"
# Linux(Ubuntu)
# FONT_PATH = "/usr/share/fonts/truetype/takao-gothic/TakaoGothic.ttf"


def main():
    # 入出力動画ファイルパス
    video_infile = "./mov_hts-samp003.mp4"
    video_outfile = "./outvideo.mp4"

    # 動画読み込み
    cap = cv2.VideoCapture(video_infile)

    # 動画の各プロパティ取得
    print("# Video Property List")
    frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    fps = round(cap.get(cv2.CAP_PROP_FPS), 2)
    bitrate = int(cap.get(cv2.CAP_PROP_BITRATE))
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    print(f"FrameCount:{frame_count}, FPS:{fps}, BitRate:{bitrate}")
    print(f"Width:{width}, Height:{height}")

    # 出力用の動画(MP4)オブジェクト設定
    fourcc = cv2.VideoWriter_fourcc("m", "p", "4", "v")
    outvideo = cv2.VideoWriter(video_outfile, fourcc, fps, (width, height))

    while True:
        # フレーム読み込み
        ret, frame = cap.read()
        if ret is False:
            break

        # フレーム読み込み時点の再生時間[秒]を取得
        frame_pos = int(cap.get(cv2.CAP_PROP_POS_FRAMES))
        video_sec = int(frame_pos / fps)

        # フレームへテキスト書き込み
        text = f"動画ファイル:{video_infile}\n再生時間:{video_sec}秒"
        frame = write_text_on_frame(frame, text, width, height)

        # 編集フレーム出力
        outvideo.write(frame)


def write_text_on_frame(
    frame: np.ndarray, text: str, width: int, height: int
) -> np.ndarray:
    """入力フレームに指定テキスト書き込み

    Args:
        frame (np.ndarray): フレーム
        text (str): 書き込みテキスト
        width (int): フレーム幅
        height (int): フレーム高

    Returns:
        np.ndarray: テキスト書き込みフレーム
    """
    image = Image.fromarray(frame)
    draw = ImageDraw.Draw(image)

    # テキスト書き込み
    font = ImageFont.truetype(font=FONT_PATH, size=72)
    draw.rectangle(xy=(0, 0, width, int(height / 5)), fill=(255, 255, 255))
    draw.text(xy=(10, 10), text=text, fill=(0, 0, 255), font=font)

    return np.array(image)


if __name__ == "__main__":
    main()


참고


  • 파이썬 동영상 편집! 동영상에 위치 제어 텔롭을 넣는 방법
  • 【Python】Pillow ↔ OpenCV 변환
  • 좋은 웹페이지 즐겨찾기