目标检测 - 绘制bounding box

news2024/10/2 6:41:37

工具类

from PIL.Image import Image, fromarray
import PIL.ImageDraw as ImageDraw
import PIL.ImageFont as ImageFont
from PIL import ImageColor
import numpy as np

STANDARD_COLORS = [
    'AliceBlue', 'Chartreuse', 'Aqua', 'Aquamarine', 'Azure', 'Beige', 'Bisque',
    'BlanchedAlmond', 'BlueViolet', 'BurlyWood', 'CadetBlue', 'AntiqueWhite',
    'Chocolate', 'Coral', 'CornflowerBlue', 'Cornsilk', 'Crimson', 'Cyan',
    'DarkCyan', 'DarkGoldenRod', 'DarkGrey', 'DarkKhaki', 'DarkOrange',
    'DarkOrchid', 'DarkSalmon', 'DarkSeaGreen', 'DarkTurquoise', 'DarkViolet',
    'DeepPink', 'DeepSkyBlue', 'DodgerBlue', 'FireBrick', 'FloralWhite',
    'ForestGreen', 'Fuchsia', 'Gainsboro', 'GhostWhite', 'Gold', 'GoldenRod',
    'Salmon', 'Tan', 'HoneyDew', 'HotPink', 'IndianRed', 'Ivory', 'Khaki',
    'Lavender', 'LavenderBlush', 'LawnGreen', 'LemonChiffon', 'LightBlue',
    'LightCoral', 'LightCyan', 'LightGoldenRodYellow', 'LightGray', 'LightGrey',
    'LightGreen', 'LightPink', 'LightSalmon', 'LightSeaGreen', 'LightSkyBlue',
    'LightSlateGray', 'LightSlateGrey', 'LightSteelBlue', 'LightYellow', 'Lime',
    'LimeGreen', 'Linen', 'Magenta', 'MediumAquaMarine', 'MediumOrchid',
    'MediumPurple', 'MediumSeaGreen', 'MediumSlateBlue', 'MediumSpringGreen',
    'MediumTurquoise', 'MediumVioletRed', 'MintCream', 'MistyRose', 'Moccasin',
    'NavajoWhite', 'OldLace', 'Olive', 'OliveDrab', 'Orange', 'OrangeRed',
    'Orchid', 'PaleGoldenRod', 'PaleGreen', 'PaleTurquoise', 'PaleVioletRed',
    'PapayaWhip', 'PeachPuff', 'Peru', 'Pink', 'Plum', 'PowderBlue', 'Purple',
    'Red', 'RosyBrown', 'RoyalBlue', 'SaddleBrown', 'Green', 'SandyBrown',
    'SeaGreen', 'SeaShell', 'Sienna', 'Silver', 'SkyBlue', 'SlateBlue',
    'SlateGray', 'SlateGrey', 'Snow', 'SpringGreen', 'SteelBlue', 'GreenYellow',
    'Teal', 'Thistle', 'Tomato', 'Turquoise', 'Violet', 'Wheat', 'White',
    'WhiteSmoke', 'Yellow', 'YellowGreen'
]

"""
将目标边界框和类别信息绘制到图片上
"""
def draw_text(draw,
              box: list,
              cls: int,
              score: float,
              category_index: dict,
              color: str,
              font: str = 'arial.ttf',
              font_size: int = 24):

    try:
        font = ImageFont.truetype(font, font_size)
    except IOError:
        font = ImageFont.load_default()

    left, top, right, bottom = box
    display_str = f"{category_index[str(cls)]}: {int(100 * score)}%"
    display_str_heights = [font.getsize(ds)[1] for ds in display_str]
    display_str_height = (1 + 2 * 0.05) * max(display_str_heights)

    if top > display_str_height:
        text_top = top - display_str_height
        text_bottom = top
    else:
        text_top = bottom
        text_bottom = bottom + display_str_height

    for ds in display_str:
        text_width, text_height = font.getsize(ds)
        margin = np.ceil(0.05 * text_width)
        draw.rectangle([(left, text_top),
                        (left + text_width + 2 * margin, text_bottom)], fill=color)
        draw.text((left + margin, text_top),
                  ds,
                  fill='black',
                  font=font)
        left += text_width


def draw_masks(image, masks, colors, thresh: float = 0.7, alpha: float = 0.5):
    np_image = np.array(image)
    masks = np.where(masks > thresh, True, False)

    # colors = np.array(colors)
    img_to_draw = np.copy(np_image)
    # TODO: There might be a way to vectorize this
    for mask, color in zip(masks, colors):
        img_to_draw[mask] = color

    out = np_image * (1 - alpha) + img_to_draw * alpha
    return fromarray(out.astype(np.uint8))

"""
调用该函数进行绘制,传入图像,边界框信息,类别信息,置信度,类别索引,字体等信息。
将目标边界框信息,类别信息,mask信息绘制在图片上
Args:
    image: 需要绘制的图片
    boxes: 目标边界框信息
    classes: 目标类别信息
    scores: 目标概率信息
    masks: 目标mask信息
    category_index: 类别与名称字典
    box_thresh: 过滤的概率阈值
    mask_thresh:
    line_thickness: 边界框宽度
    font: 字体类型
    font_size: 字体大小
    draw_boxes_on_image:
    draw_masks_on_image:

Returns:
"""
def draw_objs(image: Image,
              boxes: np.ndarray = None,
              classes: np.ndarray = None,
              scores: np.ndarray = None,
              masks: np.ndarray = None,
              category_index: dict = None,
              box_thresh: float = 0.1,
              mask_thresh: float = 0.5,
              line_thickness: int = 8,
              font: str = 'arial.ttf',
              font_size: int = 24,
              draw_boxes_on_image: bool = True,
              draw_masks_on_image: bool = False):


    # 过滤掉低概率的目标
    idxs = np.greater(scores, box_thresh)
    boxes = boxes[idxs]
    classes = classes[idxs]
    scores = scores[idxs]
    if masks is not None:
        masks = masks[idxs]
    if len(boxes) == 0:
        return image

    colors = [ImageColor.getrgb(STANDARD_COLORS[cls % len(STANDARD_COLORS)]) for cls in classes]

    if draw_boxes_on_image:
        draw = ImageDraw.Draw(image)
        for box, cls, score, color in zip(boxes, classes, scores, colors):
            left, top, right, bottom = box
            # 绘制目标边界框
            draw.line([(left, top), (left, bottom), (right, bottom),
                       (right, top), (left, top)], width=line_thickness, fill=color)
            # 绘制类别和概率信息
            draw_text(draw, box.tolist(), int(cls), float(score), category_index, color, font, font_size)

    if draw_masks_on_image and (masks is not None):
        image = draw_masks(image, masks, colors, mask_thresh)

    return image

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1402390.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++提高编程---模板---类模板

目录 一、类模板 1.模板 2.类模板的作用 3.语法 4.声明 二、类模板和函数模板的区别 三、类模板中成员函数的创建时机 四、类模板对象做函数参数 五、类模板与继承 六、类模板成员函数类外实现 七、类模板分文件编写 八、类模板与友元 九、类模板案例 一、类模板 …

SpringBoot - SpringBoot手写模拟SpringBoot启动过程

依赖 建一个工程,两个Module: 1. springboot模块,表示springboot框架的源码实现 2. user包,表示用户业务系统,用来写业务代码来测试我们所模拟出来的SpringBoot 首先,SpringBoot是基于的Spring,所以我…

3DMAX初级小白班第一课:菜单栏介绍

基本介绍 这里不可能一个一个选项全部教给大家(毕竟之后靠实操慢慢就记住了),只说一些相对需要注意的设置。 自定义-热键编辑器-热键设置 这里有你所需要的全部快捷键 自定义-自定义UI启动布局 将UI布局还原到启动的位置 自定义-通用单…

使用Go发送HTTP GET请求

在Go语言中,我们可以使用net/http包来发送HTTP GET请求。以下是一个简单的示例,展示了如何使用Go发送HTTP GET请求并获取响应。 go复制代码 package main import ( "fmt" "io/ioutil" "net/http" …

HCIP网络的类型

一.网络类型: 点到点 BMA:广播型多路访问 -- 在一个MA网络中同时存在广播(泛洪)机制 NBMA:非广播型多路访问 -- 在一个MA网络中,没有泛洪机制-----不怎么使用了 MA:多路访问 -- 在一个…

03-常用编程概念

上一篇:02-编程猜谜游戏 本章介绍几乎所有编程语言中都会出现的概念,以及它们在 Rust 中的工作原理。许多编程语言的核心都有许多共同点。本章介绍的概念都不是 Rust 独有的,但我们会在 Rust 的上下文中讨论这些概念,并解释使用这…

课堂教学内容分为哪几类

作为一名老师,每天都要面对各种类型的学生,而学生们最关心的问题之一就是:老师,你到底要教我们什么?这个问题看似简单,实则深奥。那么,课堂教学内容究竟分为哪几类呢?今天&#xff0…

【webrtc】GCC 7: call模块创建的ReceiveSideCongestionController

webrtc 代码学习&#xff08;三十二&#xff09; video RTT 作用笔记 从call模块说起 call模块创建的时候&#xff0c;会创建 src\call\call.h 线程&#xff1a; 统计 const std::unique_ptr<CallStats> call_stats_;SendDelayStats &#xff1a; 发送延迟统计 const…

【书生·浦语大模型实战营05】《(5)LMDeploy 大模型量化部署实践》学习笔记

《(5)LMDeploy 大模型量化部署实践》 课程文档&#xff1a;《LMDeploy 的量化和部署》 1、大模型部署背景 1.1 模型部署 定义 将训练好的模型在特定软硬件环境中启动的过程&#xff0c;使模型能够接收输入并返回预测结果为了满足性能和效率的需求&#xff0c;常常需要对模型…

CLion调试Nodejs源码

【环境】 macOS node-v20.11.0源码 CLion 2023.3.2 【1】下载源码 https://nodejs.org/en/download/ 【2】编译源码 解压后的目录如下 进入解压后的目录进行编译 ./configure --debug make -C out BUILDTYPEDebug -j 4需要好久… 编译成功之后在node-v20.11.0目录下会有一个…

DNS是什么?为什么需要DNS?常用的DNS记录类型有哪些?

在互联网时代&#xff0c;基本上人人都要上网&#xff0c;网络已与人们日常生活息息相关。而DNS就在我们上网的过程中扮演着重要的角色—“将网址/域名解析成 IP 地址”。那么DNS是什么&#xff1f;为什么需要DNS&#xff1f;常用的DNS类型有哪些呢&#xff1f;别着急&#xff…

[数据结构 - C++] 红黑树RBTree

文章目录 1、前言2、红黑树的概念3、红黑树的性质4、红黑树节点的定义5、红黑树的插入Insert6、红黑树的验证7、红黑树与AVL树的比较附录&#xff1a; 1、前言 我们在学习了二叉搜索树后&#xff0c;在它的基础上又学习了AVL树&#xff0c;知道了AVL树是靠平衡因子来调节左右高…

springboot+mysql马拉松赛事志愿者管理系统-计算机毕业设计源码93439

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对马拉松赛事志愿者管理等问题&#xff0c;对…

司铭宇老师: 房地产中介销售顾问培训:房产中介经纪人提升销售业绩的法宝

房地产中介销售顾问培训&#xff1a;房产中介经纪人提升销售业绩的法宝 一、了解客户需求 成功的沟通始于深入了解客户的需求和期望。房地产经纪人应该通过提问和倾听来收集信息&#xff0c;比如客户对房产的地理位置、价格范围、户型设计等的偏好。此外&#xff0c;了解客户的…

【算法专栏学习】成贤学院,程序员的福利站到了,判断子序列,经典算法实战。

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

优思学院|怎样制作优秀的标准作业流程(SOP)?

我相信你一定去过众所周知的麦当劳。它在世界各地都有许多分店。不知道你是否曾在不同地方的麦当劳尝试过他们的美食&#xff0c;但你可能会好奇&#xff0c;为什么无论在世界哪个角落&#xff0c;麦当劳的食物口味都如此一致&#xff1f;它们是如何确保全球各地分店都能提供同…

中断——外部中断EXIT

终端可以分成外部中断和内部中断吗 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 野火中断章节有这样一句话 【F103在内核水平上搭载了一个异常响应系统&#xff0c; 支持为数众多的系统异常和外部中断。 其中系统异常有8个&#xff…

「 网络安全常用术语解读 」网络攻击者的战术、技术和常识知识库ATTCK详解

引言&#xff1a;随着网络攻击手段的不断升级和多样化&#xff0c;网络安全领域面临着越来越严峻的挑战。为了帮助网络安全专业人员更好地识别和防御网络攻击&#xff0c;MITRE公司创建了ATT&CK框架&#xff0c;以提供一个统一且结构化的方法来描述网络攻击者的行为和技巧。…

Git与GitHub零基础教学

大家好&#xff0c;我是星恒&#xff0c;这个帖子给大家分享的是git和github的全套教程&#xff0c;包含github初始&#xff0c;git常用命令以及基本使用&#xff0c;git的ssh链接github&#xff0c;github使用token登录&#xff0c;github和idea的配合&#xff0c;一些平时常用…

SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务)

文章目录 前言1.痛点2.解决方案3.具体实现3.1搭建热配置服务3.2编写配置文件3.3搭建版本控制仓库3.4Eureka-Client引入以下依赖3.5Eureka-Client微服务编写以下配置bootstrap.yml提前加载3.6分别编写测试Controller3.7测试效果3.8下线场景压测 4.SpringCloudBus优化 前言 在上…