FCOS难点记录

news2024/11/29 4:41:31

在这里插入图片描述
FCOS 中有计算 特征图(Feature map中的每个特征点到gt_box的左、上、右、下的距离)

1、特征点到gt_box框的 左、上、右、下距离计算

		x = coords[:, 0] # h*w,2   即 第一列
        y = coords[:, 1] 
        l_off = x[None, :, None] - gt_boxes[..., 0][:, None, :]  # [1,h*w,1]-[batch_size,1,m]-->[batch_size,h*w,m]
        t_off = y[None, :, None] - gt_boxes[..., 1][:, None, :]
        r_off = gt_boxes[..., 2][:, None, :] - x[None, :, None]
        b_off = gt_boxes[..., 3][:, None, :] - y[None, :, None]
        ltrb_off = torch.stack([l_off, t_off, r_off, b_off], dim=-1)  # [batch_size,h*w,m,4]
        areas = (ltrb_off[..., 0] + ltrb_off[..., 2]) * (ltrb_off[..., 1] + ltrb_off[..., 3])  # [batch_size,h*w,m]
        off_min = torch.min(ltrb_off, dim=-1)[0]  # [batch_size,h*w,m]
        off_max = torch.max(ltrb_off, dim=-1)[0]  # [batch_size,h*w,m]

根据上边的画的图可以看出,假设对应的 feature map 大小为 2x2,stride=4,原始图片为8x8。将特征图中的每个特征点映射回去,可以得到相应的 4个(h*w个)坐标。对应图中的 红色a,绿色b,黄色c和蓝色d的点。

print(x,"\n",y,x.shape)
'''
tensor([2., 6., 2., 6.]) 
tensor([2., 2., 6., 6.]) torch.Size([4])
'''

print(x[None,:,None]) # [1,4,1]
'''
tensor([[[2.],
         [6.],
         [2.],
         [6.]]]) 
'''
 
print(gt_boxes) # [1,2,4]  batch=1, 两个框,每个框左上角和右下角坐标
'''
tensor([[[5, 4, 7, 6],
         [1, 1, 4, 6]]])
'''

print(gt_boxes[...,0],gt_boxes[...,0][:,None,:])
''' 
tensor([[5, 1]]) tensor([[[5, 1]]])
'''
l_off = [2,2]-[5,1]=[-3,1]  以此类推


print(l_off,"\n", l_off.shape)

'''
**第一列代表,所有的点abcd横坐标与第一个框的左边偏移量。第二列代表到第二个框的偏移量**
tensor([[[-3.,  1.],
         [ 1.,  5.],
         [-3.,  1.],
         [ 1.,  5.]]]) 
 torch.Size([1, 4, 2])
 '''

print(ltrb_off)
'''
第一列代表,所有的投影点abcd,到两个框的左边偏移量。第一行第二行分别代表两个框。
tensor([[[[-3., -2.,  5.,  4.], # a 点到第一个框的左边、上边、右边、下边的偏移
          [ 1.,  1.,  2.,  4.]], # a 点到第二框的左边、上边、右边、下边的偏移

         [[ 1., -2.,  1.,  4.], # b 点到第一个框的左边、上边、右边、下边的偏移
          [ 5.,  1., -2.,  4.]],

         [[-3.,  2.,  5.,  0.],
          [ 1.,  5.,  2.,  0.]],

         [[ 1.,  2.,  1.,  0.],
          [ 5.,  5., -2.,  0.]]]]) torch.Size([1, 4, 2, 4]) #[batch_size,h*w,m,4]
'''

print(ltrb_off[...,0])
'''

tensor([[[-3.,  1.],
         [ 1.,  5.],
         [-3.,  1.],
         [ 1.,  5.]]]) torch.Size([1, 4, 2])
'''

print(areas)
'''
areas: tensor([[[ 4., 15.],
         [ 4., 15.],
         [ 4., 15.],
         [ 4., 15.]]])
'''

torch.return_types.min(
values=tensor([[[-3.,  1.],
         [-2., -2.],
         [-3.,  0.],
         [ 0., -2.]]]),
indices=tensor([[[0, 0],
         [1, 2],
         [0, 3],
         [3, 2]]])) 
 torch.return_types.max(
values=tensor([[[5., 4.],
         [4., 5.],
         [5., 5.],
         [2., 5.]]]),
indices=tensor([[[2, 3],
         [3, 0],
         [2, 1],
         [1, 0]]]))



2、确定该特征点在哪一个框内,是否在该FPN特征层进行尺寸判断并进行后续预测

off_min = torch.min(ltrb_off, dim=-1)[0]  # [batch_size,h*w,m] # off_min 找出所有 特征点  到 每个框的 四条边 最小的距离
off_max = torch.max(ltrb_off, dim=-1)[0]  # [batch_size,h*w,m]  #off_max 找出所有 特征点  到 每个框的 四条边 最大的距离

mask_in_gtboxes = off_min > 0
mask_in_level = (off_max > limit_range[0]) & (off_max <= limit_range[1]) # 锁定在这个limit range上的所有的特征的点	
print("ltrf_off",ltrb_off)
print("off_min",off_min,"\n","off_max",off_max)
print("mask_in_gtboxes-->",mask_in_gtboxes)
print("mask_in_level-->",mask_in_level)

'''
ltrf_off tensor([[[[-3., -2.,  5.,  4.], # a 点到第一个框的左边、上边、右边、下边的偏移
          [ 1.,  1.,  2.,  4.]],  # a 点到第二个框的左边、上边、右边、下边的偏移

         [[ 1., -2.,  1.,  4.], # b 点到第一个框的左边、上边、右边、下边的偏移
          [ 5.,  1., -2.,  4.]],

         [[-3.,  2.,  5.,  0.],
          [ 1.,  5.,  2.,  0.]],

         [[ 1.,  2.,  1.,  0.],
          [ 5.,  5., -2.,  0.]]]])
          
off_min 
tensor([[[-3.,  1.], # a点到第一个框最小距离-3,  a点到第二个框的最小偏移距离 1
         [-2., -2.], #b点到第一个框最小距离-2,  b点到第二个框的最小偏移距离 -2
         [-3.,  0.], # c点到第一个框最小距离-3,  a点到第二个框的最小偏移距离 0
         [ 0., -2.]]]) # d点到第一个框最小距离0,  a点到第二个框的最小偏移距离 -2
         
 off_max 
 tensor([[[5., 4.],
         [4., 5.],
         [5., 5.],
         [2., 5.]]])
         
mask_in_gtboxes-->  # 判断了 特征点是否在框内
tensor([[[False,  True],  # a点到第一个框四边最小偏移距离小于0,所以,a点不属于第一个框,为false;以此类推。
         [False, False],
         [False, False],
         [False, False]]]) # [batch,h*w,m]
         
mask_in_level-->  # 锁定在这个limit range上的所有的特征的点	
tensor([[[True, True],  # 锁定了a 在这个level中
         [True, True],  # 锁定了b
         [True, True],  # 锁定了c
         [True, True]]])# 锁定了d  都在这个FPN级别上  [batch,h*w,m]
'''

3、特征点是否在框中心的范围内,用来判断是否为正样本

	radiu = stride * sample_radiu_ratio # 4*1.15 = 4.6
    gt_center_x = (gt_boxes[..., 0] + gt_boxes[..., 2]) / 2
    gt_center_y = (gt_boxes[..., 1] + gt_boxes[..., 3]) / 2
    c_l_off = x[None, :, None] - gt_center_x[:, None, :]  # [1,h*w,1]-[batch_size,1,m]-->[batch_size,h*w,m]
    c_t_off = y[None, :, None] - gt_center_y[:, None, :]
    c_r_off = gt_center_x[:, None, :] - x[None, :, None]
    c_b_off = gt_center_y[:, None, :] - y[None, :, None]
    c_ltrb_off = torch.stack([c_l_off, c_t_off, c_r_off, c_b_off], dim=-1)  # [batch_size,h*w,m,4]
    c_off_max = torch.max(c_ltrb_off, dim=-1)[0]
    mask_center = c_off_max < radiu
print("c_ltrb_off",c_ltrb_off)
print("c_off_max",c_off_max)
print("mask_center",mask_center)

'''
c_ltrb_off 
tensor([[[[-4.0000, -3.0000,  4.0000,  3.0000],  # 同上边一样,a到 第一个框 小的中心框四边 的距离
          [-0.5000, -1.5000,  0.5000,  1.5000]], # a到 第二个框 小的中心框四边 的距离

         [[ 0.0000, -3.0000,  0.0000,  3.0000], # b到 第一个框 小的中心框四边 的距离
          [ 3.5000, -1.5000, -3.5000,  1.5000]], # # b到 第二个框 小的中心框四边 的距离

         [[-4.0000,  1.0000,  4.0000, -1.0000],
          [-0.5000,  2.5000,  0.5000, -2.5000]],

         [[ 0.0000,  1.0000,  0.0000, -1.0000],
          [ 3.5000,  2.5000, -3.5000, -2.5000]]]])
          
c_off_max tensor([[[4.0000, 1.5000], # 找到a特征点到第一个框中心框和第二个框的中心框的 最大距离
         [3.0000, 3.5000],
         [4.0000, 2.5000],
         [1.0000, 3.5000]]]) # [batch,h*w,m] 4个特征点(a,b,c,d) x 框的个数2个(第一个框,第二个框)
         
mask_center tensor([[[True, True], # 判断是否在这个框里中心点里边 正样本
         [True, True],
         [True, True],
         [True, True]]]) ## [batch,h*w,m]
'''

3、制定mask,根据上边的 gt_box、fpn_level、mask_center

‘’’
mask_pos 是三个约束条件的交集,分别是特征点在gt中,特征点在level中,以及特征点距离Gt中的center小于指定的范围
‘’’

mask_pos = mask_in_gtboxes & mask_in_level & mask_center  # [batch_size,h*w,m]

areas[~mask_pos] = 99999999
areas_min_ind = torch.min(areas, dim=-1)[1]  # [batch_size,h*w]
mask_pos = mask_in_gtboxes & mask_in_level & mask_center  # [batch_size,h*w,m]
print("pre_areas:",areas)
areas[~mask_pos] = 99999999
areas_min_ind = torch.min(areas, dim=-1)[1]  # [batch_size,h*w] # 返回索引,注意和上边的区别,上边返回值,比大小
# torch.max()  or  torch.min() dim=0 找列,dim=1  找行
print("mask_pos-->",mask_pos)
print("post_ares",areas)
print("areas_min_ind",areas_min_ind)

'''
mask_in_gtboxes--> 
tensor([[[False,  True],
         [False, False],
         [False, False],
         [False, False]]])
mask_in_level--> 
tensor([[[True, True],
         [True, True],
         [True, True],
         [True, True]]])
mask_center 
tensor([[[True, True],
         [True, True],
         [True, True],
         [True, True]]])

mask_pos--> 
tensor([[[False,  True],  # 只有a点在第二个框在这个fpn这个level, 同时满足这三个条件
         [False, False],
         [False, False],
         [False, False]]])
         
post_ares 
tensor([[[1.0000e+08, 1.5000e+01],
         [1.0000e+08, 1.0000e+08],
         [1.0000e+08, 1.0000e+08],
         [1.0000e+08, 1.0000e+08]]]) # #[batch_size,h*w,m] 将 满足要求的 保持面积不面,其他设置为很大的值
         
areas_min_ind tensor([[1, 0, 0, 0]]) # [batch_size,h*w] min[1]返回的是对应的indices  找到最小的面积,返回索引。

'''



4、

![在这里插入图片描述](https://img-blog.csdnimg.cn/3e504ea230ff47c097ba9eb6caddca55.png在这里插入图片描述

reg_targets = ltrb_off[torch.zeros_like(areas, dtype=torch.bool)
.scatter_(-1, areas_min_ind.unsqueeze(dim=-1), 1)]  # [batch_size*h*w,4]
reg_targets = torch.reshape(reg_targets, (batch_size, -1, 4))  # [batch_size,h*w,4]
scatter_的用法:参考 https://blog.csdn.net/weixin_43496455/article/details/103870889
scatter(dim, index, src)将src中数据根据index中的索引按照dim的方向进行填充。

dim=0
'''
areas: 
tensor([[[ 4., 15.],
         [ 4., 15.],
         [ 4., 15.],
         [ 4., 15.]]]) [1,4,2]
扩展维度之后  [1,4] --> torch.Size([1, 4, 1]) ===> [[[1,0,0,0]]]
torch.zeros_like(areas, dtype=torch.bool) 
tensor([[[False, False],
         [False, False],
         [False, False],
         [False, False]]])
         
after scatter_--> 
tensor([[[False,  True],
         [ True, False],
         [ True, False],
         [ True, False]]]) # [1,4,2]
         
ltrf_off 
tensor([[[[-3., -2.,  5.,  4.], # a 点到第一个框的左边、上边、右边、下边的偏移
          [ 1.,  1.,  2.,  4.]],  # a 点到第二个框的左边、上边、右边、下边的偏移

         [[ 1., -2.,  1.,  4.], # b 点到第一个框的左边、上边、右边、下边的偏移
          [ 5.,  1., -2.,  4.]],

         [[-3.,  2.,  5.,  0.],
          [ 1.,  5.,  2.,  0.]],

         [[ 1.,  2.,  1.,  0.],
          [ 5.,  5., -2.,  0.]]]])
          
reg_targets1 
tensor([[ 1.,  1.,  2.,  4.], # a 点 第二个框
        [ 1., -2.,  1.,  4.], # b 点 第一个框
        [-3.,  2.,  5.,  0.], # c 点 第一个框
        [ 1.,  2.,  1.,  0.]])# d 点 第一个框
        # torch.Size([4, 4])
        
reg_targets2 tensor([[[ 1.,  1.,  2.,  4.],
         [ 1., -2.,  1.,  4.],
         [-3.,  2.,  5.,  0.],
         [ 1.,  2.,  1.,  0.]]]) # torch.Size([1, 4, 4])
'''

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

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

相关文章

禅道研发项⽬管理系统未授权RCE漏洞复现

1、产品介绍 Zendao禅道是第一款国产的开源项目管理软件&#xff0c;他的核心管理思想基于敏捷方法scrum&#xff0c;内置了产品管理和项目管理&#xff0c;同时又根据国内研发现状补充了测试管理、计划管理、发布管理、文档管理、事务管理等功能。 2、漏洞描述 该系统在202…

opencv创建图片,绘制图片,画框,划线,改变像素点颜色

文章目录 创建空白图片创建一张渐变色彩色绘制多边形绘制多线改变像素点颜色 创建空白图片 bool tool_class::creatEmpty(int width, int height, std::string image_p) {// 创建一个空白图像cv::Mat blankImage(height, width, CV_8UC3, cv::Scalar(255, 255, 255));// 保存图…

html与django实现多级数据联动

html与django实现多级数据联动 1、流程 1、进入页面后先获取年级数据 2、选择年级后获取院级数据 3、选择院级后获取层次数据 4、选择层次数据后获取专业数据 2、html代码 <p style"margin-top: 10px;"><label>年级</label><select id"…

MCU平台使用SPI-DirectC实现FPGA在线升级

本文介绍在MCU平台上使用SPI-DirectC实现FPGA的在线升级功能。 对于使用Microchip FPGA若想使用离线方式对FPGA进行Bitstream的烧写,就不得不使用官方提供的DirectC组件(开源,包含JTAG-DirectC和SPI-DirectC),本文是在MCU(32bit)上实现的,采用的是SPI-DirectC组件。 …

工业自动化与5G技术的融合:开启工业4.0时代的新篇章

工业自动化与5G技术的融合&#xff1a;开启工业4.0时代的新篇章 随着全球数字化进程的加速推进&#xff0c;工业自动化作为现代制造业的核心驱动力&#xff0c;正经历着前所未有的变革。而在这一变革中&#xff0c;5G技术的崛起为工业自动化带来了全新的可能性和机遇。本文将探…

商人宝:网页收银软件有哪些功能

网页收银软件凭借无需安装、无需手工升级以及良好的用户体验等优势迅速发展并替代传统收银软件&#xff0c;今天商人宝为大家分享网页收银软件一般有哪些功能。欢迎大家点赞关注&#xff0c;以及收藏本文章&#xff0c;以便后续多看多了解。 1、快速收银 通过扫码枪快速将商品加…

到蒙古包了,这边天气-9度 很冷

【点我-这里送书】 本人详解 作者&#xff1a;王文峰&#xff0c;参加过 CSDN 2020年度博客之星&#xff0c;《Java王大师王天师》 公众号&#xff1a;JAVA开发王大师&#xff0c;专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生&#xff0c;期待你的…

Android笔记(十二):结合Compose实现Handler机制处理多线程的通信

在Android应用中常常结合多线程处理多个任务。不可避免&#xff0c;多个线程之间需要数据通信。Hanlder消息处理机制是异步处理的方式之一。通过Handler机制可以实现在不同的线程之间的通信。 一、主线程和工作线程 1.主线程 一个Android的移动应用启动时会单独启动一个进程…

虚幻C++基础 day4

虚幻中的UI 虚幻中的比较常用的UI&#xff1a;Widget Blueprint又称UMG虚幻中的两种布局&#xff1a; 网格布局锚布局 创建Widget Blueprint 网格布局 有点类似Qt中的网格布局&#xff0c;将UI面板进行行列切分Horizontal Box&#xff1a;水平分布Vertical Box&#xff1a;…

【C++】——类与对象(二)

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

微信号绑定50个开发者小程序以后超额如何删除不用的

我们在开发微信小程序的时候&#xff0c;当前开发者工具登录的必须是该小程序的开发者才能进行小程序的开发&#xff0c;添加开发者的步骤是&#xff1a; 添加开发者 1、进入微信开放平台&#xff0c;然后扫码进入管理平台 2、找到下图所示位置 3:、输入要添加的微信账号&am…

python调用chrome实现网页自动操作

一. 内容简介 python调用chrome实现网页自动操作。 二. 软件环境 2.1vsCode 2.2Anaconda version: conda 22.9.0 2.3代码 链接&#xff1a; 三.主要流程 3.1 下载驱动和插件 调用谷歌浏览器&#xff0c;需要下载浏览器驱动&#xff08;https://registry.npmmirror.co…

fastadmin 表单页面,根据一个字段的值显示不同字段

表单中有计费方式&#xff0c;选中不同的计费方式显示不同的字段如下图 根据选择不同的计费方式&#xff1a;重量或夹板。展示不同相关字段&#xff1a;每件重量/每夹板件数量 add.html <div class"form-group"><label class"control-label col-xs-12…

redisson中的分布式锁二

公平锁&#xff08;Fair Lock&#xff09; 基于Redis的Redisson分布式可重入公平锁也是实现了java.util.concurrent.locks.Lock接口的一种RLock对象。同时还提供了异步&#xff08;Async&#xff09;、反射式&#xff08;Reactive&#xff09;和RxJava2标准的接口。它保证了当…

C#开发的OpenRA游戏之世界存在的属性CombatDebugOverlay(3)

C#开发的OpenRA游戏之世界存在的属性CombatDebugOverlay(3) 这次来分析CombatDebugOverlay属性,这个属性只有在调试游戏的时候才会使用。当你设置这个属性的时候,就可以看到如下图的结果: 可以看到物品的周边都有一个圆圈,以及有一些十字的点位标志。 那些十字表示的点…

LCD英文字模库(16x8)模拟测试程序

字模 字模&#xff0c;就是把文字符号转换为LCD能识别的像素点阵信息。 电子发烧友可能都熟悉字模的用途。就是调用者通过向LCD模块发送字模数据&#xff0c;LCD根据字模数据在LCD面板上相应的像素描绘出图形或文字。 现在&#xff0c;大部分的LCD都内置了字模库&#xff0c…

【脑源成像】术前癫痫的电源成像 评价:现状与未来展望

Electric source imaging for presurgical epilepsy evaluation: current status and future prospects 术前癫痫的电源成像 评价:现状与未来展望论文下载&#xff1a;算法程序下载&#xff1a;摘要1 项目介绍1.1. 选择要综述的文章2. 电源成像的基本原理4. ESI的实践方面4.1脑…

EPLAN中的电位,编号和报表

一、电位-eplan路由的理论基础 电位&#xff0c;信号和网络是eplan中的隐藏三君子。官网帮助中对电位和信号的解释如下&#xff1a; 在 EPLAN 中区分电位和信号。通过电位使连接属性的默认值和电位信息进入到项目中。 通过电位定义点或电位连接点定义一个电位或信号。此处录入…

Autosar模块介绍:Memory_2(NVM)

上一篇 | 返回主目录 | [下一篇] Autosar模块介绍&#xff1a;Memory_2(NVM 1 基本术语解释2 NVRAM Block组成关系2.1 基础Block类型2.1.1 NV Block2.1.2 RAM Block2.1.3 ROM Block2.2.4 Administrative Block 2.2 NVRAM Block类型 1 基本术语解释 编号缩写原文解释1NVNon Vol…

万字详解Java的三大特性:封装 | 继承 | 多态

前言&#xff1a;面向对象程序设计的三大特征就是&#xff1a;封装&#xff0c;继承&#xff0c;多态。在前文介绍了类和对象后&#xff0c;我们就可以继而学习什么是封装&#xff0c;怎么用类的子类来实现继承和多态 目录 一.面向对象的特性 1.封装性 2.继承性 3.多态性…