【PyTorch】图像目标检测

news2024/9/30 11:37:55

图像目标检测是什么

Object Detection
判断图像中目标位置

目标检测两要素

  1. 分类:分类向量 [p0, …, pn]
  2. 回归:回归边界框 [x1, y1, x2, y2]

模型如何完成目标检测

将3D张量映射到两个张量

  1. 分类张量:shape为 [N, c+1]
  2. 边界框张量:shape为 [N, 4]

Recent Advances in Deep Learning for Object Detection
在这里插入图片描述

边界框数量N如何确定?

传统方法——滑动窗策略

缺点:

  1. 重复计算量大
  2. 窗口大小难确定

利用卷积减少重复计算
重要概念:特征图一个像素对应原图一块区域

目标检测模型简介

按流程分为:one-stage和two-stage
在这里插入图片描述
在这里插入图片描述

Faster RCNN

经典two stage检测网络

Faster RCNN 数据流

  1. Feature map:[256, h_f, w_f]
  2. 2 Softmax:[num_anchors, h_f, w_f]
  3. Regressors:[num_anchors*4, h_f, w_f]
  4. NMS OUT:[n_proposals=2000, 4]
  5. ROI Layer:[512, 256, 7, 7]
  6. FC1 FC2:[512, 1024]
  7. c+1 Softmax: [512, c+1]
  8. Regressors:[512, (c+1)*4]

Faster RCNN 主要组件

  1. backbone
  2. rpn
  3. filter_proposals(NMS)
  4. roi_heads
    在这里插入图片描述

Faster RCNN 行人检测

数据: PennFudanPed数据集, 70张行人照片共345行人标签
官方地址: http://www.cis.upenn.edu/~jshi/ped_html/
模型: fasterrcnn_resnet50_fpn 进行finetune
目标检测推荐github:https://github.com/amusi/awesome-object-detection

代码如下:

import os
import time
import torch.nn as nn
import torch
import random
import numpy as np
import torchvision.transforms as transforms
import torchvision
from PIL import Image
import torch.nn.functional as F
from my_dataset import PennFudanDataset
from common_tools import set_seed
from torch.utils.data import DataLoader
from matplotlib import pyplot as plt
from torchvision.models.detection.faster_rcnn import FastRCNNPredictor
from torchvision.transforms import functional as F
import enviroments

set_seed(1)  # 设置随机种子

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# classes_coco
COCO_INSTANCE_CATEGORY_NAMES = [
    '__background__', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus',
    'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'N/A', 'stop sign',
    'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
    'elephant', 'bear', 'zebra', 'giraffe', 'N/A', 'backpack', 'umbrella', 'N/A', 'N/A',
    'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',
    'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket',
    'bottle', 'N/A', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl',
    'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',
    'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'N/A', 'dining table',
    'N/A', 'N/A', 'toilet', 'N/A', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
    'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'N/A', 'book',
    'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'
]


def vis_bbox(img, output, classes, max_vis=40, prob_thres=0.4):
    fig, ax = plt.subplots(figsize=(12, 12))
    ax.imshow(img, aspect='equal')

    out_boxes = output_dict["boxes"].cpu()
    out_scores = output_dict["scores"].cpu()
    out_labels = output_dict["labels"].cpu()

    num_boxes = out_boxes.shape[0]
    for idx in range(0, min(num_boxes, max_vis)):

        score = out_scores[idx].numpy()
        bbox = out_boxes[idx].numpy()
        class_name = classes[out_labels[idx]]

        if score < prob_thres:
            continue

        ax.add_patch(plt.Rectangle((bbox[0], bbox[1]), bbox[2] - bbox[0], bbox[3] - bbox[1], fill=False,
                                   edgecolor='red', linewidth=3.5))
        ax.text(bbox[0], bbox[1] - 2, '{:s} {:.3f}'.format(class_name, score), bbox=dict(facecolor='blue', alpha=0.5),
                fontsize=14, color='white')
    plt.show()
    plt.close()


class Compose(object):
    def __init__(self, transforms):
        self.transforms = transforms

    def __call__(self, image, target):
        for t in self.transforms:
            image, target = t(image, target)
        return image, target


class RandomHorizontalFlip(object):
    def __init__(self, prob):
        self.prob = prob

    def __call__(self, image, target):
        if random.random() < self.prob:
            height, width = image.shape[-2:]
            image = image.flip(-1)
            bbox = target["boxes"]
            bbox[:, [0, 2]] = width - bbox[:, [2, 0]]
            target["boxes"] = bbox
        return image, target


class ToTensor(object):
    def __call__(self, image, target):
        image = F.to_tensor(image)
        return image, target


if __name__ == "__main__":

    # config
    LR = 0.001
    num_classes = 2
    batch_size = 1
    start_epoch, max_epoch = 0, 5
    train_dir = enviroments.pennFudanPed_data_dir
    train_transform = Compose([ToTensor(), RandomHorizontalFlip(0.5)])

    # step 1: data
    train_set = PennFudanDataset(data_dir=train_dir, transforms=train_transform)

    # 收集batch data的函数
    def collate_fn(batch):
        return tuple(zip(*batch))

    train_loader = DataLoader(train_set, batch_size=batch_size, collate_fn=collate_fn)

    # step 2: model
    model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
    in_features = model.roi_heads.box_predictor.cls_score.in_features
    model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes) # replace the pre-trained head with a new one

    model.to(device)

    # step 3: loss
    # in lib/python3.6/site-packages/torchvision/models/detection/roi_heads.py
    # def fastrcnn_loss(class_logits, box_regression, labels, regression_targets)

    # step 4: optimizer scheduler
    params = [p for p in model.parameters() if p.requires_grad]
    optimizer = torch.optim.SGD(params, lr=LR, momentum=0.9, weight_decay=0.0005)
    lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)

    # step 5: Iteration

    for epoch in range(start_epoch, max_epoch):

        model.train()
        for iter, (images, targets) in enumerate(train_loader):

            images = list(image.to(device) for image in images)
            targets = [{k: v.to(device) for k, v in t.items()} for t in targets]

            # if torch.cuda.is_available():
            #     images, targets = images.to(device), targets.to(device)

            loss_dict = model(images, targets)  # images is list; targets is [ dict["boxes":**, "labels":**], dict[] ]

            losses = sum(loss for loss in loss_dict.values())

            print("Training:Epoch[{:0>3}/{:0>3}] Iteration[{:0>3}/{:0>3}] Loss: {:.4f} ".format(
                epoch, max_epoch, iter + 1, len(train_loader), losses.item()))

            optimizer.zero_grad()
            losses.backward()
            optimizer.step()

        lr_scheduler.step()

    # test
    model.eval()

    # config
    vis_num = 5
    vis_dir = os.path.join(BASE_DIR, "..", "..", "data", "PennFudanPed", "PNGImages")
    img_names = list(filter(lambda x: x.endswith(".png"), os.listdir(vis_dir)))
    random.shuffle(img_names)
    preprocess = transforms.Compose([transforms.ToTensor(), ])

    for i in range(0, vis_num):

        path_img = os.path.join(vis_dir, img_names[i])
        # preprocess
        input_image = Image.open(path_img).convert("RGB")
        img_chw = preprocess(input_image)

        # to device
        if torch.cuda.is_available():
            img_chw = img_chw.to('cuda')
            model.to('cuda')

        # forward
        input_list = [img_chw]
        with torch.no_grad():
            tic = time.time()
            print("input img tensor shape:{}".format(input_list[0].shape))
            output_list = model(input_list)
            output_dict = output_list[0]
            print("pass: {:.3f}s".format(time.time() - tic))

        # visualization
        vis_bbox(input_image, output_dict, COCO_INSTANCE_CATEGORY_NAMES, max_vis=20, prob_thres=0.5)  # for 2 epoch for nms

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

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

相关文章

【选择”丹摩“深入探索智谱AI的CogVideoX:视频生成的新前沿】

文章目录 一、CogVideoX模型概述二、变革性的3D变分自编码器三、先进的3D旋转位置编码四、端到端的视频理解模型五、丹摩平台的环境配置简单介绍六、开发者的展望示例代码&#xff1a;与CogVideoX的交互 2024年8月6日&#xff0c;智谱AI宣布其开源视频生成模型CogVideoX&#x…

16、斑马设备的ppocer-4进行文字识别和opencv-mobile中文显示

基本思想:手上有个斑马设备,是客户的,简单记录一下开发过程和工程项目,同时记录跟着android小哥学习了很多anroid的知识,转ppocr-4参考之前的ppocr-3转换即可,整个框架仍然使用c++ ncnn jni框架推理和现实,图像库使用opencv-mobile 一、首先转paddle-cor-4 到ncnn的框架…

E34.【C语言】位段练习题

1.题目 分析下列代码中位段在内存中的排布(已知测试平台为VS2022) struct S {int a : 2;int b : 5;int c : 10;int d : 30; };int main() {struct S s { 0 };return 0; } 有关位段的知识点见64.【C语言】再议结构体(下)文 2.提示 VS满足:由低地址向高地址存储,按浪费空间…

新书推荐——《深度学习精粹与PyTorch实践》

深度学习绝非不可窥探的黑箱!深入理解其模型和算法的实际运作机制&#xff0c;是驾驭并优化结果的关键。你无需成为数学专家或资深数据科学家,同样能够掌握深度学习系统内部的工作原理。 本书旨在通过深入浅出的方式&#xff0c;为你揭示这些原理&#xff0c;让你在理解和解释…

C++系列-继承

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 继承的概念和定义 继承是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特性的基础上进行拓展&#xff0c;增加功能&#xff0c;这样可以…

SSL VPN | Easyconnect下载安装使用 (详尽)

EasyConnect是一款远程连接工具&#xff0c;为用户提供简便、快捷的远程访问和控制解决方案。 目录 下载 安装 使用 卸载 下载 通过链接进入官网技术支持板块 深信服技术支持-简单、高效、自助化服务 (sangfor.com.cn)https://support.sangfor.com.cn/ 选择软件下载 在安…

获取本函数所在代码域内的所有局部变量和值以字典形式返回locals()

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 获取本函数所在代码域内的 所有局部变量和值 以字典形式返回 locals() 选择题 关于以下代码输出的结果说法正确的是&#xff1f; a 10 def x(): b 20 print(locals()) print("【执行…

二值图像的面积求取的两种方法及MATLAB实现

一、引言 面积在数字图像处理中经常用到&#xff0c;在MATLAB中&#xff0c;计算二值图像的面积通常可以通过两种主要方法实现&#xff1a;遍历法和直接利用bwarea函数。下面将分别介绍这两种方法的原理和相应的MATLAB代码示例。 二、遍历法计算二值图像面积的原理和MATLAB代码…

护眼落地台灯品牌前十名:十大全网超高热度品牌汇总

十大护眼路灯台灯有哪些&#xff1f;在众多照明灯具产品中&#xff0c;护眼落地台灯能够提供适合多场景、大氛围的舒适照明&#xff0c;对于学生、工作群体来说能够有效的提高光线质量&#xff0c;减少不良光线带来的近视风险。可是市场品牌繁多&#xff0c;很容易选购到劣质的…

golang web笔记-2.请求request

什么是request http消息分为request&#xff08;请求&#xff09; 和 response&#xff08;响应&#xff09; request&#xff1a;在go中是一个struct&#xff0c;代表了客户段发送的http请求&#xff0c;已可以通过request 的方法访问请求中的cookie、URL、User Agent&#xf…

【论文阅读笔记】TOOD: Task-aligned One-stage Object Detection

论文代码&#xff1a;https://github.com/fcjian/TOOD 文章目录 论文小结论文简介论文方法Task-aligned Head&#xff08;T-Head&#xff09;T-Head伪代码解释 Task Alignment Learning&#xff08;TAL&#xff09;Task-aligned Sample AssignmentTask-aligned Loss 论文实验消…

STM32F1+HAL库+FreeTOTS学习15——互斥信号量

STM32F1HAL库FreeTOTS学习15——互斥信号量 1. 优先级翻转2. 互斥信号量3. 相关API函数&#xff1b;3.1 互斥信号量创建3.2 获取信号量3.3 释放信号量3.4 删除信号量 4. 操作实验1. 实验内容2. 代码实现3. 运行结果 上期我们介绍了数值信号量。这一期我们来介绍互斥信号量 1. 优…

Hadoop FileSystem Shell 常用操作命令

提示&#xff1a;本文章只总结一下常用的哈&#xff0c;详细的命令大家可以移步官方的文档&#xff08;链接贴在下面了哈&#x1f923;&#xff09;— HDFS官方命令手册链接。 目录 1. cat 命令&#xff1a;查看 HDFS 文件内容2. put 命令&#xff1a;将本地文件上传到 HDFS3.…

基于VirtualBox和Ubuntu的虚拟环境搭建

VirtualBox简介 VirtualBox 是一款开源虚拟机软件。 是由德国 Innotek 公司开发&#xff0c;由Sun Microsystems公司出品的软件&#xff0c;使用Qt编写&#xff0c;在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。简单易用&#xff0c;可虚拟的系统包括Windows&…

浅谈汽车智能座舱如何实现多通道音频

一、引言 随着汽车智能座舱的功能迭代发展&#xff0c;传统的 4 通道、6 通道、8 通道等音响系统难以在满足驾驶场景的需求&#xff0c;未来对于智能座舱音频质量和通道数会越来越高。接下来本文将浅析目前智能座舱如何实现音频功放&#xff0c;以及如何实现多路音频功放方案。…

Library介绍(三)

环境描述 工作条件 一般lib文件里面包含了芯片的工作条件即operation conditions&#xff0c;其指定了工艺&#xff08;process&#xff09;、温度&#xff08;temperature&#xff09;和电压&#xff08;voltage&#xff09;&#xff0c;见图1。 其中&#xff0c;process代表了…

10款超好用的图纸加密软件推荐!2024企业图纸加密最佳选择!

在现代企业中&#xff0c;保护知识产权和敏感数据显得尤为重要。尤其是工程设计、建筑图纸等专业文件&#xff0c;若遭到泄露&#xff0c;可能导致巨大的经济损失和竞争优势的丧失。为了帮助企业有效保护图纸&#xff0c;本文将推荐10款超好用的图纸加密软件。 1.安秉图纸加密软…

【CSS in Depth 2 精译_043】6.5 CSS 中的粘性定位技术 + 本章小结

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09;第二章 相对单位&#xff08;已完结&#xff09;第三章 文档流与盒模型&#xff08;已完结&#xff09;第四章 Flexbox 布局&#xff08;已…

在起草行业标准时,如何确保格式统一?

一、遵循相关规范 1. 严格按照国家有关标准编写规范以及行业特定的标准编写指南进行起草。熟悉并掌握规范中对于标准结构、条款编号、字体字号、图表格式等方面的具体要求。 2. 参考已发布的同行业成熟标准的格式&#xff0c;学习其成功的格式布局和表达形式。 二、建立模板 1…

9.24-k8s服务发布

Ingress 使用域名发布 K8S 服务 部署项目 一、先部署mariadb [rootk8s-master ~]# mkdir aaa [rootk8s-master ~]# cd aaa/ [rootk8s-master aaa]# # 先部署mariadb [rootk8s-master aaa]# # configmap [rootk8s-master aaa]# vim mariadb-configmap.yaml apiVersion: v1 ki…