python 绘制对象检测框及中文信息标注

# 坐标顺序: 上-》左-》下-》右
def draw_bounding_box_on_image(image,
                               ymin,
                               xmin,
                               ymax,
                               xmax,
                               color='red',
                               thickness=4,
                               display_str_list=(),
                               use_normalized_coordinates=True):
    """
    Args:
      image: a cv2 object.
      ymin: ymin of bounding box.
      xmin: xmin of bounding box.
      ymax: ymax of bounding box.
      xmax: xmax of bounding box.
      color: color to draw bounding box. Default is red.
      thickness: line thickness. Default value is 4.
      display_str_list: list of strings to display in box
                        (each to be shown on its own line).
      use_normalized_coordinates: If True (default), treat coordinates
        ymin, xmin, ymax, xmax as relative to the image.  Otherwise treat
        coordinates as absolute.
    """
    image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))  
    draw = ImageDraw.Draw(image)
    # 获取图像的宽度与高度
    im_width, im_height = image.size
    if use_normalized_coordinates:
        (left, right, top, bottom) = (xmin * im_width, xmax * im_width,
                                    ymin * im_height, ymax * im_height)
    else:
        (left, right, top, bottom) = (xmin, xmax, ymin, ymax)
    
    # 绘制Box框
    draw.line([(left, top), (left, bottom), (right, bottom),
               (right, top), (left, top)], width=thickness, fill=color)
    
    # 加载字体
    try:
        font = ImageFont.truetype("font/simsun.ttc", 24, encoding="utf-8")
    except IOError:
        font = ImageFont.load_default()
    
    # 计算显示文字的宽度集合 、高度集合   
    display_str_width = [font.getsize(ds)[0] for ds in display_str_list]
    display_str_height = [font.getsize(ds)[1] for ds in display_str_list]
    # 计算显示文字的总宽度
    total_display_str_width = sum(display_str_width) + max(display_str_width) * 1.1
    # 计算显示文字的最大高度
    total_display_str_height = max(display_str_height)
    
    if top > total_display_str_height:
        text_bottom = top
    else:
        text_bottom = bottom + total_display_str_height
    
    # 计算文字背景框最右侧可到达的像素位置    
    if right < (left + total_display_str_width):
        text_right = right
    else:
        text_right = left + total_display_str_width
    
    # 绘制文字背景框
    draw.rectangle(
            [(left, text_bottom), (text_right, text_bottom - total_display_str_height)],
            fill=color)    
    
    # 计算文字背景框可容纳的文字,若超出部分不显示,改为补充“..”
    for index in range(len(display_str_list[::1])):
        current_right = (left + (max(display_str_width)) + sum(display_str_width[0:index + 1]))
        
        if current_right < text_right:
            print(current_right)
            display_str = display_str_list[:index + 1]
        else:
            display_str = display_str_list[0:index - 1] + '...'
            break  
    
    # 绘制文字
    draw.text(
            (left + max(display_str_width) / 2, text_bottom - total_display_str_height),
            display_str,
            fill='black',
            font=font)
    
    return cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR) 

效果

在这里插入图片描述

posted on 2019-07-17 11:16  疯狂的小萝卜头  阅读(616)  评论(0编辑  收藏  举报