32

Can we load a custom TrueType font and use it with cv2.putText function ?

font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv2.LINE_AA)
Ghilas BELHADJ
  • 13,412
  • 10
  • 59
  • 99

3 Answers3

35

In OpenCV, only a subset of Hershey fonts are supported.

In opencv2/core.hpp, you can find this enum 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
};

You can try PIL.ImageFont if you want to use custom font.

A basic example is presented here:

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)

enter image description here

Kinght 金
  • 17,681
  • 4
  • 60
  • 74
22

For new viewers, OpenCV supports custom fonts since OpenCV 3.0.0 via the FreeType2 class. See here some nice sample code: https://docs.opencv.org/4.1.1/d9/dfa/classcv_1_1freetype_1_1FreeType2.html

Dharman
  • 30,962
  • 25
  • 85
  • 135
  • 2
    Anyone got a python code snippet for this? I can't get it working – Jonas Dec 20 '19 at 21:41
  • 6
    For Python, you would need to install the `opencv-contrib-python` module. See [this answer](https://stackoverflow.com/a/50921014/145504) for a code sample. – rgov Jan 04 '20 at 18:22
  • Be warned: The pre-built wheels for opencv not always contain these freetype classes. On my Mac they do, but on Linux they don't. – Alexander Pacha Dec 09 '20 at 09:12
10

enter image description here

You can also use the library PILasOPENCV to be found at https://github.com/bunkahle/PILasOPENCV to use truetype fonts in combination with Python OpenCV. PIL or Pillow are not needed. The module depends on the library freetype-py. Fonts would be imported like this:

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()

This library is a wrapper around the common used PIL functions but works internally with OpenCV.

bunkus
  • 975
  • 11
  • 19