How to draw Chinese text on the image using `cv2.putText`correctly? (Python+OpenCV)

前端 未结 3 640
盖世英雄少女心
盖世英雄少女心 2020-12-30 03:08

I use python cv2(window10, python2.7) to write text in image, when the text is English it works, but when I use Chinese text it write messy code in the image.

Below

相关标签:
3条回答
  • 2020-12-30 03:54

    The cv2.putText don't support no-ascii char in my knowledge. 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)
    


    Refer to my another answer:

    Load TrueType Font to OpenCV

    0 讨论(0)
  • 2020-12-30 03:59

    According to this opencv forum, putText is only able to support a small ascii subset of characters and does not support unicode characters which are other symboles like chinese and arabic characters.

    However, you can try to use PIL instead and follow the answer posted here and see if it works out for you.

    0 讨论(0)
  • 2020-12-30 04:08

    Quick Start

    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)
    

    what is init_parameters() and cv2_img_add_text()?

    see as below:

    EXAMPLE

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

    0 讨论(0)
提交回复
热议问题