LoginSignup
10
10

More than 3 years have passed since last update.

PythonのOpenCVで、画像に対して綺麗に文字を表示させる

Posted at

はじめに

以下のような画像を作りたかったのですが、OpenCVで実装しようとすると少しハマりどころがあったので書いています。
スクリーンショット 2019-09-16 17.39.14.png

実装

画像にテキストを載せる

OpenCVのputTextは、そのままでは\nを認識できないようです。
そのため、このようにfor文を回して処理を分ける必要があります。
この関数では、textsとして文字列を受け取った場合にも処理が可能なようにしています。

def draw_texts(img, texts, font_scale=0.7, thickness=2):
    h, w, c = img.shape
    offset_x = 10  # 左下の座標
    initial_y = 0
    dy = int(img.shape[1] / 15)
    color = (0, 0, 0)  # black

    texts = [texts] if type(texts) == str else texts

    for i, text in enumerate(texts):
        offset_y = initial_y + (i+1)*dy
        cv2.putText(img, text, (offset_x, offset_y), cv2.FONT_HERSHEY_SIMPLEX,
                    font_scale, color, thickness, cv2.LINE_AA)

cv2.rectangleでalpha(透過)とfill(塗りつぶし)を考慮する

それらしくするためにfill=True, alpha=0.4などとはcv2.rectangleは認識することができません。
そのため、塗りつぶしのためにはfill=-1, 透過のためにはcv2.addWeightedを使用します。

def draw_result_on_img(img, texts, w_ratio=0.35, h_ratio=0.2, alpha=0.4):
    # 文字をのせるためのマットを作成する
    overlay = img.copy()
    pt1 = (0, 0)
    pt2 = (int(img.shape[1] * w_ratio), int(img.shape[0] * h_ratio))

    mat_color = (200, 200, 200)
    fill = -1  # -1にすると塗りつぶし
    cv2.rectangle(overlay, pt1, pt2, mat_color, fill)

    mat_img = cv2.addWeighted(overlay, alpha, img, 1 - alpha, 0)

    draw_texts(mat_img, texts)

    return mat_img

ここで、文字とマットを含めて全て同じ数値のものを指定するのが望ましいと思われるのですが、その理由はcv2で処理している場合、BGRでの処理がデフォルトになるため、RGBの要領で書いているとcv2.imwrite時に想定通りの色にならないことが考えられるからです。

実行例

jupyter notebook内にてlennaさんの画像を同ディレクトリに配置し、実行します。

import cv2
import matplotlib.pyplot as plt
%matplotlib inline

img = cv2.imread("lenna.png")
mat_img = draw_result_on_img(img, texts=["name: lenna", "gender: female"])

plt.figure(figsize=(8, 8))
plt.imshow(cv2.cvtColor(mat_img, cv2.COLOR_BGR2RGB))

すると、はじめにで書いたような画像を出力することができます。

参考

10
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10