将TrueType字体加载到OpenCV

32

我们可以加载自定义的TrueType字体,并将其与cv2.putText函数一起使用吗?

font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv2.LINE_AA)
4个回答

38
在OpenCV中,仅支持Hershey字体的子集。
opencv2/core.hpp中,您可以找到此枚举HersheyFonts。
//! Only a subset of Hershey fonts
enum HersheyFonts {
    FONT_HERSHEY_SIMPLEX        = 0, //!< normal size sans-serif font
    FONT_HERSHEY_PLAIN          = 1, //!< small size sans-serif font
    FONT_HERSHEY_DUPLEX         = 2, //!< normal size sans-serif font (more complex than FONT_HERSHEY_SIMPLEX)
    FONT_HERSHEY_COMPLEX        = 3, //!< normal size serif font
    FONT_HERSHEY_TRIPLEX        = 4, //!< normal size serif font (more complex than FONT_HERSHEY_COMPLEX)
    FONT_HERSHEY_COMPLEX_SMALL  = 5, //!< smaller version of FONT_HERSHEY_COMPLEX
    FONT_HERSHEY_SCRIPT_SIMPLEX = 6, //!< hand-writing style font
    FONT_HERSHEY_SCRIPT_COMPLEX = 7, //!< more complex variant of FONT_HERSHEY_SCRIPT_SIMPLEX
    FONT_ITALIC                 = 16 //!< flag for italic font
};

如果您想使用自定义字体,可以尝试PIL.ImageFont。

下面是一个基本示例:

import numpy as np
from PIL import ImageFont, ImageDraw, Image
import cv2
import time

## Make canvas and set the color
img = np.zeros((200,400,3),np.uint8)
b,g,r,a = 0,255,0,0

## Use cv2.FONT_HERSHEY_XXX to write English.
text = time.strftime("%Y/%m/%d %H:%M:%S %Z", time.localtime()) 
cv2.putText(img,  text, (50,50), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (b,g,r), 1, cv2.LINE_AA)

## Use simsum.ttc to write Chinese.
fontpath = "./simsun.ttc"     
font = ImageFont.truetype(fontpath, 32)
img_pil = Image.fromarray(img)
draw = ImageDraw.Draw(img_pil)
draw.text((50, 100),  "国庆节/中秋节 快乐!", font = font, fill = (b, g, r, a))
img = np.array(img_pil)

## Display 
cv2.imshow("res", img);cv2.waitKey();cv2.destroyAllWindows()
cv2.imwrite("res.png", img)

在这里输入图片描述


非常好的答案,它在Python 3.9环境下也能正常工作。 - yw173

23

3
有人有这个的 Python 代码片段吗?我无法让它工作。 - Jonas
6
对于Python,您需要安装opencv-contrib-python模块。请参考此答案获取代码示例。 - rgov
请注意:opencv的预构建轮子并不总是包含这些freetype类。在我的Mac上,它们有,但在Linux上没有。 - Alexander Pacha

11

图片描述

您还可以使用PILasOPENCV库,该库可在https://github.com/bunkahle/PILasOPENCV找到,以便与Python OpenCV一起使用TrueType字体。不需要使用PIL或Pillow。该模块依赖于freetype-py库。以下是导入字体的方法:

from __future__ import print_function
import PILasOPENCV as Image
import PILasOPENCV as ImageDraw
import PILasOPENCV as ImageFont
import cv2
# was: from PIL import Image, ImageDraw, ImageFont

font = ImageFont.truetype("arial.ttf", 18)
print(font)
im = Image.open("lena.jpg")
draw = ImageDraw.Draw(im)
text = "Lena's image"
draw.text((249,455), text, font=font, fill=(0, 0, 0))
# in PIL:
# print(font.getsize(text))
# mask = font.getmask(text)
print(ImageFont.getsize(text, font))
mask = ImageFont.getmask(text, font)
print(type(mask))
cv2.imshow("mask", mask)
im.show()

这个库是对常用的 PIL 函数的封装,但它在内部使用 OpenCV 进行操作。


0
补充一下@Pavlos Fragkiadoulakis的回答:这里是使用OpenCV 4.8.0在Python中创建一个带有文本和自定义字体的空二进制图像的示例。
import cv2 as cv
import numpy as np

text = str(-1.234)
font_height = 400
thickness = 1

# load font and check text size
ft = cv.freetype.createFreeType2()
ft.loadFontData("Seven Segment.ttf", 0)
width, height = ft.getTextSize(text, font_height, thickness)[0]


# create empty white image (slightly bigger than text size)
binary_image = np.ones((int(1.05*height), int(1.05*width)), dtype=np.uint8) * 255

# adjust text positioning
text_origin = (0, height+5)

# add text to image
ft.putText(binary_image, text, text_origin, font_height, (0, 0, 0), thickness, cv.LINE_8, True)

# display image
cv.imshow("", binary_image)
cv.waitKey()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接