如何使用`cv2.putText`正确地在图像上绘制中文文本? (Python的+ OpenCV的)

时间:2018-06-14 09:35:08

标签: python opencv cv2

我使用python cv2(window10,python2.7)在图像中写入文本,当文本是英文时它可以工作,但是当我使用中文文本时,它会在图像中写出乱码。

以下是我的代码:

# coding=utf-8
import cv2
import numpy as np

text = "Hello world"   # just work
# text = "内容理解团队"  # messy text in the image

cv2.putText(img, text,
            cord,
            font,
            fontScale,
            fontColor,
            lineType)

# Display the image
cv2.imshow("img", img)

cv2.waitKey(0)
cv2.destroyAllWindows()

text = "Hello world" # just work时,下面是输出图像:

enter image description here

text = "内容理解团队" # Chinese text, draw messy text in the image时,下面是输出图像:

enter image description here

怎么了? opencv putText不支持其他语言文字吗?

3 个答案:

答案 0 :(得分:8)

据我所知,cv2.putText不支持no-ascii char。 Try to use PIL to draw NO-ASCII(such Chinese) on the image.

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, 80),  "端午节就要到了。。。", font = font, fill = (b, g, r, a))
img = np.array(img_pil)

cv2.putText(img,  "--- by Silencer", (200,150), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (b,g,r), 1, cv2.LINE_AA)


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

enter image description here

请参阅我的另一个答案:

Load TrueType Font to OpenCV

答案 1 :(得分:3)

根据这个opencv forum,putText只能支持一个小的ascii字符子集,并且不支持unicode字符,这些字符是其他符号,如中文和阿拉伯字符。

但是,您可以尝试使用PIL,然后按照here发布的答案,看看它是否适合您。

答案 2 :(得分:0)

快速入门

np_img = np.ones((64, 32, 3), dtype=np.uint8) * 255  # background with white color
draw_text = init_parameters(cv2_img_add_text, text_size=32, text_rgb_color=(0, 0, 255), font='kaiu.ttf', replace=True)
draw_text(np_img, '您', (0, 0))
draw_text(np_img, '好', (0, 32))
cv2.imshow('demo', np_img), cv2.waitKey(0)

enter image description here

  

init_parameters()cv2_img_add_text()是什么?

如下所示:

示例

from typing import Tuple
import numpy as np
import cv2
from PIL import Image, ImageDraw, ImageFont


# define decorator
def init_parameters(fun, **init_dict):
    """
    help you to set the parameters in one's habits
    """
    def job(*args, **option):
        option.update(init_dict)
        return fun(*args, **option)
    return job


def cv2_img_add_text(img, text, left_corner: Tuple[int, int],
                     text_rgb_color=(255, 0, 0), text_size=24, font='mingliu.ttc', **option):
    """
    USAGE:
        cv2_img_add_text(img, '中文', (0, 0), text_rgb_color=(0, 255, 0), text_size=12, font='mingliu.ttc')
    """
    pil_img = img
    if isinstance(pil_img, np.ndarray):
        pil_img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    draw = ImageDraw.Draw(pil_img)
    font_text = ImageFont.truetype(font=font, size=text_size, encoding=option.get('encoding', 'utf-8'))
    draw.text(left_corner, text, text_rgb_color, font=font_text)
    cv2_img = cv2.cvtColor(np.asarray(pil_img), cv2.COLOR_RGB2BGR)
    if option.get('replace'):
        img[:] = cv2_img[:]
        return None
    return cv2_img


def main():
    np_img = np.ones(IMG_SHAPE, dtype=np.uint8) * 255  # background with white color

    np_img = cv2_img_add_text(np_img, 'Hello\nWorld', (0, 0), text_rgb_color=(255, 0, 0), text_size=TEXT_SIZE)
    np_img = cv2_img_add_text(np_img, '中文', (0, LINE_HEIGHT * 2), text_rgb_color=(0, 255, 0), text_size=TEXT_SIZE)

    cur_y = LINE_HEIGHT * 3
    draw_text = init_parameters(cv2_img_add_text, text_size=TEXT_SIZE, text_rgb_color=(0, 128, 255), font='kaiu.ttf', replace=True)
    for msg in ('笑傲江湖', '滄海一聲笑'):
        draw_text(np_img, msg, (0, cur_y))
        cur_y += LINE_HEIGHT + 1
    draw_text(np_img,
              """123
456
789
""", (0, cur_y))
    cv2.imshow('demo', np_img), cv2.waitKey(0)


if __name__ == '__main__':
    IMG_HEIGHT, IMG_WIDTH, CHANNEL = IMG_SHAPE = (250, 160, 3)
    TEXT_SIZE = LINE_HEIGHT = 32
    main()

enter image description here