一、yolov5_obb
1. 数据集(DOTA数据集)
- 数据集结构
DOTA:
|____val:
…|_images:
… …|P0001.png
… …|…
…|_labelTxt-v1.5:
… …|_DOTA-v1.5_val_OBB:
… … …|P0001.txt
… … …|…
… …|_DOTA-v1.5_val_hbb:
… … …|P0001.txt
… … …|…
|____train
|____test - 其中images文件夹中为图像数据,labelTxt文件夹中为gt_labels文本文件,DOTA-v1.5_val_OBB为有向目标边界框标注,DOTA-v1.5_val_hbb为水平目标边界框标注
- 共15类目标
classnames_v1_0 = ['plane', 'baseball-diamond', 'bridge', 'ground-track-field', 'small-vehicle',
'large-vehicle', 'ship', 'tennis-court','basketball-court', 'storage-tank',
'soccer-ball-field', 'roundabout', 'harbor', 'swimming-pool', 'helicopter']
2. 旋转框定义方式
- 使用五参数定义旋转框
[x_c, y_c, longside, shortside, Θ]
longside: 旋转矩形框的最长边
shortside: 与最长边对应的另一边
Θ: x轴顺时针旋转遇到最长边所经过的角度,Θ∈[0, 180)
3. detact类
- 参考[Circular Smooth Label (CSL)],由于基于回归的旋转框预测方法会产生边界问题,即理想的预测结果超出了我们所定义的范围,导致产生一个较大的损失值,因此将角度的回归问题转换为分类问题。
- 每个anchor负责预测的参数数量为200=4+1+15+180
[x_c, y_c, longside, shortside]+objness+claffications+angels
- yolov5_OBB输出为tensor(25200 * 200)
4. 损失函数
损失函数分为四类:置信度损失、class分类损失、θ角度分类损失、bbox边框回归损失
- 置信度损失:由正样本匹配得到的样本对计算,一是预测框中的目标置信度分数p_0;二是预测框和与之对应的目标框的 iou 值,其作为 ground-truth,两者计算二进制交叉熵BCEWithLogitsLoss得到最终的目标置信度损失。
- 类别损失:通过预测框的类别分数和目标框类别的 one-hot 表现来计算类别损失,BCEWithLogitsLoss。
- θ角度分类损失:类比类别损失。
- bbox边框回归损失:如果θ为回归任务,要通过旋转IOU损失函数进行反向传播从而调整自身参数,目前旋转检测器的处理办法为将不可导的旋转IOU损失函数进行近似,使得网络可以正常进行训练。如果将θ转换为分类问题,相当于将角度信息与边框参数信息解耦,旋转框的损失计算部分也分为角度损失和水平边框损失两个部分。
二、tensorrt部署
- 与yolov5部署不同在于旋转框iou的计算参考了Meta Research的box_iou_rotated实现
其整体实现过程:
- 结构体定义:
- RotatedBox:表示一个旋转框,包含旋转框的中心坐标 (x_ctr, y_ctr)、宽度 w、高度 h 和旋转角度 a。
- Point:表示一个点的坐标 (x, y)。
- 函数 get_rotated_vertices:
- 输入:一个旋转框 box,以及一个数组 pts 用于存储旋转框的四个顶点。
- 功能:根据旋转框的中心坐标、宽度、高度和旋转角度,计算旋转框的四个顶点坐标,并存储在数组 pts 中。
- 函数 dot_2d:
-
输入:两个二维点 A 和 B。 输出:点 A 和点 B 的内积。
-
功能:计算点 A 和点 B 的二维内积。
- 函数 cross_2d:
- 输入:两个二维点 A 和 B。
- 输出:点 A 和点 B 的二维叉积。
- 功能:计算点 A 和点 B 的二维叉积,结果可以指定为不同的类型
R。
- 函数 get_intersection_points:
-
输入:两个旋转框的顶点数组 pts1 和 pts2,以及一个数组 intersections 用于存储交点。
-
输出:交点的数量。
-
功能:计算两个旋转框之间的交点,将交点存储在数组 intersections
中,并返回交点的数量。该函数首先计算两个旋转框的边的向量,然后进行线段相交的检测,将相交的点存储在数组 intersections 中。
- 函数 convex_hull_graham:
-
输入:一个点数组 p、点的数量 num_in、一个用于存储凸包点的数组 q,以及一个标志 shift_to_zero。
-
输出:凸包点的数量。
-
功能:使用 Graham 扫描算法计算点集的凸包,并将凸包点存储在数组 q中。该函数首先找到点集中的最低点作为起始点,然后将点集中的点减去起始点,进行按角度排序,接着通过栈的方式依次加入点并检查是否形成凹形状,如果是凹形状则将前一个点从栈中弹出,直到得到凸包。最后根据标志shift_to_zero 决定是否将凸包点坐标平移回原点。
- 函数 polygon_area:
- 输入:一个凸包点的数组 p 和凸包点的数量 n。
- 输出:凸包的面积。 功能:根据凸包的顶点数组 p 计算凸包的面积。该函数使用 Shoelace 公式(又称为 Gauss 公式)来计算凸包的面积。
- 函数 rotated_boxes_intersection:
-
输入:两个旋转框 box1 和 box2。
-
输出:旋转框的交并比。
-
功能:计算两个旋转框之间的交并比(IoU)。该函数首先调用 get_rotated_vertices函数获取两个旋转框的顶点数组,然后调用 get_intersection_points函数计算两个旋转框的交点。接着,根据交点数组计算凸包的面积,并分别计算两个旋转框的面积。最后,通过计算两个旋转框面积之和减去交集面积得到并集面积,从而计算交并比。