画像に日本語を描画したいけど
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,'OpenCV(オープンシーブイ)',(10,500), font, 4,(255,255,255),2,cv2.LINE_AA)
とか記載しても画像に文字を表示させようとするとOpenCV(???????)となって日本語部分が??????と文字化けして表示されます。
そこで、 PIL.ImageFont を使って日本語を表示する方法を記載しておきます。
入力画像
背景が真っ黒の画像を作ってこの画像の上に『OpenCV(オープンシーブイ)』と表示させてみましょう。
サンプルコード
import numpy as np
from PIL import ImageFont, ImageDraw, Image
import cv2
# 背景が黒になるように、すべての要素を0とし、200*500でRGB値3つを格納でき、
# 要素のデータ型は8bit(1byte)の符号なし整数とする配列(背景画像)を作る。
img = np.zeros((200,500,3),np.uint8)
# 表示
cv2.imshow('img',img)
cv2.imwrite("img.png", img)
# 表示する色
b,g,r,a = 0,255,0,0 #B(青)・G(緑)・R(赤)・A(透明度)
# 表示させる文字
message = 'OpenCV(オープンシーブイ)'
## Use cv2.FONT_HERSHEY_XXX to write Japanese.(失敗パターン)
position = (50,50) # テキスト表示位置
cv2.putText(img, message, position, cv2.FONT_HERSHEY_SIMPLEX, 0.7, (b,g,r), 1, cv2.LINE_AA)
## Use HGS創英角ゴシックポップ体標準 to write Japanese.
fontpath ='C:\Windows\Fonts\HGRPP1.TTC' # Windows10 だと C:\Windows\Fonts\ 以下にフォントがあります。
font = ImageFont.truetype(fontpath, 32) # フォントサイズが32
img_pil = Image.fromarray(img) # 配列の各値を8bit(1byte)整数型(0~255)をPIL Imageに変換。
draw = ImageDraw.Draw(img_pil) # drawインスタンスを生成
position = (50, 100) # テキスト表示位置
draw.text(position, message, font = font , fill = (b, g, r, a) ) # drawにテキストを記載 fill:色 BGRA (RGB)
img = np.array(img_pil) # PIL を配列に変換
## 表示
cv2.imshow("res", img)
cv2.imwrite("res.png", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
出力結果
上が HERSHEY_SIMPLEX という日本語対応していないフォント。
下が Windows の HGS創英角ゴシックポップ体標準 というフォント。
おまけ
コロンビア大学の研究者たちによって FontCode なんていう目には見えない「秘密のメッセージ」を送る新手法が開発されていますので、OpenCV + PIL で作った画像をインスタのストーリーに乗せて、簡単に秘密の指令が送れるかもね。
参考情報
https://stackoverflow.com/questions/37191008/load-truetype-font-to-opencv
https://wired.jp/2018/06/04/invisible-messages-steganography/