对 u 版 yolo-v5 中的 load_mosaic 代码的理解。
前言
【个人学习笔记记录,如有错误,欢迎指正】
YOLO-V4 论文地址:https://arxiv.org/pdf/2004.10934.pdf
YOLO-V5 代码仓库地址:https://github.com/ultralytics/yolov5
在 YOLO-V4 论文中提到:Mosaic 数据增强是一种新的混合4幅图像的数据增强方法,该方法参考了 CutMix 只混合了 2 个输入图像的方法。
优点:网络模型上,由于硬件资源的原因,不能够将 batch_size 设置过大,通过 Mosaic 方法就类似间接的增大了 batch_size。
labels4, segments4 = [], [] s = self.img_size yc, xc = (int(random.uniform(-x, 2 * s + x)) for x in self.mosaic_border)
在上图中灰色区域内随机生成中心点的(x, y)坐标。
中心点的坐标分别对应:
第一张图像:右下角坐标
第二张图像:左下角坐标
第三张图像:右上角坐标
第四张图像:左上角坐标
indices = [index] + random.choices(self.indices, k=3) random.shuffle(indices) for i, index in enumerate(indices): img, _, (h, w) = load_image(self, index)3.摆放第一张图像
将第一张图像的右下角坐标放置在生成的中心点上。因为图像的大小和中心点的位置会出现多种放置情况。
if i == 0: # 使用数值 114 对 img4 三个维度全部进行填充 img4 = np.full((s * 2, s * 2, img.shape[2]), 114, dtype=np.uint8) x1a, y1a, x2a, y2a = max(xc - w, 0), max(yc - h, 0), xc, yc x1b, y1b, x2b, y2b = w - (x2a - x1a), h - (y2a - y1a), w, h1. 情况一
图像一的宽度和高度都超过了填充区域给定的大小。
这样对图像一裁剪掉蓝色区域,保留正好填充的红色区域。
图像一的高度、宽度小于填充区域给定的大小,
这样对图像一就直接进行填充。
不管是哪一种情况,只需要计算出填充的图像在填充区域内的最合理的区域坐标,即图像一的左上角坐标值即可。
只要保证被填充图像在填充区域不越界即可!
elif i == 1: # top right x1a, y1a, x2a, y2a = xc, max(yc - h, 0), min(xc + w, s * 2), yc x1b, y1b, x2b, y2b = 0, h - (y2a - y1a), min(w, x2a - x1a), h elif i == 2: # bottom left x1a, y1a, x2a, y2a = max(xc - w, 0), yc, xc, min(s * 2, yc + h) x1b, y1b, x2b, y2b = w - (x2a - x1a), 0, w, min(y2a - y1a, h) elif i == 3: # bottom right x1a, y1a, x2a, y2a = xc, yc, min(xc + w, s * 2), min(s * 2, yc + h) x1b, y1b, x2b, y2b = 0, 0, min(w, x2a - x1a), min(y2a - y1a, h)
根据上面的方法:
将第二张图像的左下角放到生成的中心点上,然后计算出图像二在填充区域中的右上角坐标;
将第三张图像的右上角放到生成的中心点上,然后计算出图像三在填充区域中的左下角坐标;
将第四张图像的左上角放到生成的中心点上,然后计算出图像四在填充区域中的右下角坐标;
img4[y1a:y2a, x1a:x2a] = img[y1b:y2b, x1b:x2b] padw = x1a - x1b padh = y1a - y1b
取出上面找到的红色区域部分,复制到拼接后的图像中。
6.标签的相应转换在进行标签的转换前,需要对 YOLO 的标签格式进行理解。
1.YOLO标签格式对于 YOLO 的标签数据格式为:n * 5,其中 n 为标注框的个数,5 分别为如下:
< box_classifier > < box_x > < box_y > < box_width > < box_height >
<类别索引> <标注框中心点 x 坐标> <标注框中心点 x 坐标> <标注框宽度> <标注框高度>
类别索引:整数,0 ~ (n-1),n个类别。注:这里的 0 还不是背景。
box_x 和 box_width ,是除以了图像本身的宽度。
box_y 和 box_height ,是除以了图像本身的高度。
box_x 、box_y、box_width 、box_height 四个值都使用原图信息进行了归一化 *** 作。
labels, segments = self.labels[index].copy(), self.segments[index].copy() if labels.size: labels[:, 1:] = xywhn2xyxy(labels[:, 1:], w, h, padw, padh) segments = [xyn2xy(x, w, h, padw, padh) for x in segments] labels4.append(labels) segments4.extend(segments)
这里的标签格式的转换由两部分组成:(1)先将YOLO格式还原为(没有归一化之前的值):(x, y, w, h);(2)将值转换为拼接后的坐标系中。
7.这就完了?当图像数据和标签数据都进行了相应的 Mosaic 增强 *** 作之后,这就完了吗?并没用,源码中,还进行了其他的数据增强 *** 作,重点是【拼接后的图像又被缩放到了输入图像的大小(不是原图像尺寸)】,然后将 Mosaic 后的图像加入到数据中,进行训练。
到这里,Mosaic 数据增强就简单理解完了。通过 Mosaic 数据增强就丰富了图像数据,而且间接增大了 batch_size。这样就减少了对 batch_size 的依赖。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)