- 网络结构
假设输入数据的大小为416×416,经过Darknet-53特征提取网络后得到尺度为13×13,26×26,52×52的特征图。其中每一个尺寸的特征图都有18(3×6,其中3是指每个grid-cell有3个anchor,每个anchor预测一个边界框的4个坐标值,1个置信度,还有一个类别概率值)个通道,将13×13×18的特征图和对应尺寸的anchor作为Decode-Unit模块的输入,根据anchor的尺寸来生成相应的预测框。这个预测框的dx,dy,dw,dh是对应在416×416输入图片上的坐标和宽高。将输入图片和图片中的真实标框经过等比缩放变成图片的尺寸为416×416,图片中的标框也相应的进行变化,求预测框和真实框的giou,然后计算边界框的损失,其网络结构图如下图所示。
2. 输入数据的预处理
首先对读取的图片数据和图片中标准的真实框的数据做数据增强(平移、翻转、裁剪)处理,从而来增加数据量。将图片和真实框按照一定比例缩放,比如真实图片数据的尺度是(767,512,3),神经网络的输入数据需要的尺寸是(416,416,3),其缩放比例为416/767.Tensorflow的实现代码如下所示。
def image_preporcess(image, target_size, gt_boxes=None): #image:输入的图片 target_size:416×416 image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32) ih, iw = target_size #ih: 416 iw: 416 h, w, _ = image.shape #h: 512 w: 767 _:3 scale = min(iw/w, ih/h) # 0.54237 nw, nh = int(scale * w), int(scale * h) #nw: 416 nh:277 image_resized = cv2.resize(image, (nw, nh)) #将图片resize成新的尺寸 image_paded = np.full(shape=[ih, iw, 3], fill_value=128.0) #生成一块画布,画布中的像素 #值为128 dw, dh = (iw - nw) // 2, (ih-nh) // 2 #计算目标尺寸的宽和高和真实尺寸的宽和高的差距 image_paded[dh:nh+dh, dw:nw+dw, :] = image_resized image_paded = image_paded / 255. #输入数据进行归一化处理 if gt_boxes is None: return image_paded else: gt_boxes[:, [0, 2]] = gt_boxes[:, [0, 2]] * scale + dw #将图片上的真实框按照比例进 #行缩放 gt_boxes[:, [1, 3]] = gt_boxes[:, [1, 3]] * scale + dh return image_paded, gt_boxes # 返回的图片的尺寸是416×416,此时的真实框的尺寸是在 #416×416上的框的尺寸