目标检测之YoloV5+旋转目标

目标检测之YoloV5+旋转目标

写在前面

2023年的某一天,记录过一个有关于活虾检测的数据预处理文章:利用虾检测模型检测图像生成的txt转成roLabelImg需要的xml,有兴趣的可以去看看那些密密麻麻的虾子。当时拿到这些图片的第一想法是这视角不就是无人机视角吗,那么该用什么样的方法去实现这种视角下的虾子的检测?刚好看了这个系列的文章:自己改建YOLOv5旋转目标的踩坑记录,才知道可以用旋转目标的方法来解决这样的问题,对此对大佬感激不尽,因此也借用了大佬的开源代码:Yolov5_obb,做了一个虾子检测。
用yolov5_obb的初步虾子检测
当然,效果并没有很好,原因有很多,不一一描述,在这篇文章里面,主要是简单介绍一下我在实现过程中的一些理解,如有问题,请多多指教。

1. YoloV5

YoloV5作为单阶段目标检测算法的代表,以其高效和精度著称。其核心思想是将目标检测视为回归问题,通过单个神经网络直接从完整图像预测边界框和类别概率。现在的yolo版本已经到了11了,在这个系列里面,v5并不是最好的,但是业内很多人都觉得这个版本是比较经典的一个版本,后续的很多个版本迭代都是在这个基础上进行修改,因此选择用V5来描述。原理就不说了,可以研读一下yolo论文和其他详解。

1.1 主要亮点

(1)输入端:Mosaic数据增强:提升小目标检测能力(通过密集目标场景模拟),增强模型对目标遮挡的鲁棒性,减少GPU显存消耗(4图合1训练)、自适应锚框计算:自动适配不同数据集的物体尺度分布,相比手动设定提升3-5% mAP,支持动态调整(训练中可二次优化)、自适应图片缩放:减少无效像素计算(相比直接拉伸),保持目标几何特征不变形,推理速度提升约15%。
(2)Backbone:Focus结构:下采样无信息丢失(传统卷积有信息损失),计算量减少约30%,保持高分辨率特征。CSP结构: 梯度分流解决梯度重复问题,内存占用降低20%,增强特征融合能力。
(3)Neck:FPN+PAN结构:多尺度特征融合(3-5个不同尺度),小目标检测精度提升8-12%,双向特征传播路径。
(4)Prediction network:GIOU Loss:解决非重叠框梯度消失问题, 收敛速度提升约2倍, 框回归精度提高5-8%。
看到这些亮点,从密集小目标,尺度,显存内存上的优化,推理性能的优化,似乎很符合做虾子检测的需求。

2. 旋转目标检测改进点

2.1 主要区别

特性原始YoloV5YoloV5-OBB
框表示水平矩形(x,y,w,h)旋转矩形(x,y,w,h,θ)
标签格式类别+4点坐标类别+8点坐标或5参数
数据增强水平翻转为主支持旋转增强
损失函数GIoU/CIoU旋转IoU
输出维度4+1+nc5+1+nc+角度分类数

2.2 关键代码改动

数据加载部分

标注格式 :

  • 支持多边形标注(8个点)或旋转框标注(5个参数)
  • 标签文件格式: class_id x1 y1 x2 y2 x3 y3 x4 y4(事实上我提供的是 x1 y1 x2 y2 x3 y3 x4 y4 class_id )
    详细代码还是见开源的源码中yolov5_obb/utils/datasets.py和yolov5_obb\utils\rboxs_utils.py
# 多边形转旋转框的核心函数
def poly2rbox(polys, num_cls_thata=180, radius=6.0, use_pi=True, use_gaussian=True):
    # 将多边形转换为旋转框[cx, cy, w, h, angle]
    # 并生成角度的高斯分布标签
    ...
角度损失计算部分

YOLOv5-OBB旋转目标检测代码中,损失函数主要在ComputeLoss类中实现,在这里,只关注角度损失函数。具体来说:

  1. 角度损失初始化
# 在__init__中初始化角度损失函数
BCEtheta = nn.BCEWithLogitsLoss(pos_weight=torch.tensor([h['theta_pw']], device=device))
if g > 0:  # 如果启用了Focal Loss
    BCEtheta = FocalLoss(BCEtheta, g)  # 使用Focal Loss包装
self.BCEtheta = BCEtheta  # 保存为成员变量
  1. 角度损失计算
# 在__call__方法中计算角度损失
class_index = 5 + self.nc  # 分类分支结束位置
t_theta = tgaussian_theta[i].type(ps.dtype)  # 获取目标角度的高斯分布标签
ltheta += self.BCEtheta(ps[:, class_index:], t_theta)  # 计算角度损失
  1. 角度损失特点
  • 使用**Circular Smooth Label (CSL)**方法将角度预测转化为分类问题
  • 采用BCEWithLogitsLoss作为基础损失函数
  • 支持Focal Loss处理类别不平衡
  • 角度值通过高斯分布编码,预测的是角度分布而非直接回归角度值
  1. 损失整合
# 最终将角度损失与其他损失加权求和
ltheta *= self.hyp['theta']  # 应用角度损失权重
total_loss = (lbox + lobj + lcls + ltheta) * bs  # 总损失

角度损失的特点:

  1. 使用BCEWithLogitsLoss作为基础损失函数
  2. 支持Focal Loss处理类别不平衡
  3. 角度值通过高斯分布编码,预测的是角度分布而非直接回归角度值
  4. 最终损失是各损失项的加权和:total_loss = (lbox + lobj + lcls + ltheta) * bs

3. 旋转目标

3.1 旋转框表示方法

采用五参数表示法:[cx, cy, w, h, θ],其中:

  • cx, cy:旋转框中心坐标
  • w, h:框的宽度和高度
  • θ:旋转角度(弧度制),范围[-π/2, π/2)
# 五参数表示法 [cx, cy, w, h, θ]
def poly2rbox(polys, num_cls_thata=180, radius=6.0, use_pi=False, use_gaussian=False):
    # θ∈[-pi/2, pi/2) 或 [0,180) 两种模式
    (x,y), (w,h), angle = cv2.minAreaRect(poly)
    theta = angle / 180 * pi  # 弧度制转换
    return [x, y, w, h, theta] if use_pi else [x, y, w, h, angle]

3.2 角度编码方式

  1. CSL编码(Circular Smooth Label)
    • 将连续角度离散化为分类问题
    • 使用圆形平滑标签缓解类别不平衡
    • 每个角度类别用高斯分布表示相邻角度关系
def gaussian_label_cpu(label, num_class, u=0, sig=4.0):
    """
    转换成CSL Labels:
        用高斯窗口函数根据角度θ的周期性赋予gt labels同样的周期性,使得损失函数在计算边界处时可以做到“差值很大但loss很小”;
        并且使得其labels具有环形特征,能够反映各个θ之间的角度距离
    Args:
        label (float32):[1], theta class
        num_theta_class (int): [1], theta class num
        u (float32):[1], μ in gaussian function
        sig (float32):[1], σ in gaussian function, which is window radius for Circular Smooth Label
    Returns:
        csl_label (array): [num_theta_class], gaussian function smooth label
    """
    x = np.arange(-num_class/2, num_class/2)
    y_sig = np.exp(-(x - u) ** 2 / (2 * sig ** 2))
    index = int(num_class/2 - label)
    return np.concatenate([y_sig[index:], 
                           y_sig[:index]], axis=0)
  1. 高斯编码
    • 使用高斯分布表示角度不确定性
    • 更精细的角度表示能力

4. 旋转目标检测的优点

  1. 更精确的定位

    • 旋转框能更紧密地贴合倾斜目标
    • 减少背景区域的误检
    • 对于长宽比较大的目标(如车辆、船舶)效果尤为明显
  2. 更高的IoU

    • 对于密集排列的倾斜目标(如遥感图像中的车辆)
    • 旋转框IoU比水平框平均提高15-30%
    • 减少同一目标被多次检测的情况
  3. 更广的应用场景

    • 遥感图像分析:飞机、船舶检测、无人机
    • 文档分析:文字检测与识别
    • 自动驾驶:道路标志检测
    • 工业检测:零件定位与缺陷检测

5. 总结

YoloV5-OBB通过引入旋转框检测能力,显著提升了模型在倾斜目标场景下的检测性能。其核心改进包括旋转框表示、角度编码策略和旋转IoU计算等。虽然带来了一定的计算开销,但在需要精确检测旋转目标的场景下,这种改进是非常有价值的。未来,随着硬件加速和算法优化的进步,旋转目标检测技术将在更多领域得到广泛应用。

### 关于旋转目标检测 #### 算法原理 对于常规的目标检测算法而言,其设计初衷通常假设物体处于正交视角或者特定角度范围内。然而,在实际场景中,尤其是航空图像、卫星图片以及一些工业视觉应用里,待测物体会存在任意方向上的摆放情况。为了应对这种情况,研究人员提出了专门针对旋转矩形框标注下的目标检测方案。 这类方法的核心在于调整特征提取网络以适应不同朝向的对象,并且重新定义边界框回归机制来拟合倾斜的角度参数。具体来说,可以采用RPN(Region Proposal Network)变体生成候选区域时就考虑方位角因素;也可以直接在网络输出端增加额外维度用于表示宽高之外的方向信息[^3]。 #### 实现方法 一种常见的做法是在传统Faster R-CNN框架基础上做适当修改: 1. 修改Anchor的设计使其能够覆盖多种尺度和比例的同时也考虑到不同的旋转角度; 2. 对应地更改RoI Pooling操作使之适用于带有角度坐标的提议框; 3. 设计新的损失函数项惩罚预测结果中的角度偏差部分; 4. 数据预处理阶段加入随机仿射变换模拟更多样化的姿态分布。 以下是Python代码片段展示如何创建带旋转变换的数据增强管道: ```python import cv2 import numpy as np def rotate_image(image, angle): (h, w) = image.shape[:2] center = (w // 2, h // 2) M = cv2.getRotationMatrix2D(center, angle, scale=1.0) rotated = cv2.warpAffine(image, M, (w, h)) return rotated ``` #### 应用场景 旋转目标检测技术特别适合应用于那些对象可能呈现多角度状态的任务环境中,比如无人机拍摄地面车辆监控、遥感影像分析识别建筑物轮廓等。此外,在医疗成像领域也有潜在用途,例如CT扫描断层图中器官位置不固定的情况下进行病变部位定位[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值