YOLOv3之标签生成

标签就是网络要学习的东西。
怎么生成标签呢?
首先,需要有数据。
数据包括:图片数据,目标框数据
YOLOv3之标签生成_第1张图片
这个图有两个人一只狗,对应两类三个目标框:

images/87.jpg 0 304 245 140 133 1 97 235 124 153 1 199 156 354 311

怎么把目标框生成YOLOV3的标签呢?
3层循环,第一层循环遍历每种特征图尺寸(13, 26, 52),第二层循环遍历原图的每个目标框(n个),第三层循环遍历对应特征图尺寸的建议框(3个)。每个目标框都和建议框计算iou、中心点偏移率以及宽高偏移率,并把类别的标签做成one_hot形式,全部存入对应特征图上对应点的通道内。
看代码比较简单:

import numpy as np
import math

CLASS_NUM = 2  # 类别数目
IMG_WIDTH = 416  # 图片边长
BOXES = "images/87.jpg 0 304 245 140 133 1 97 235 124 153 1 199 156 354 311"  # 目标框数据
#  建议框
ANCHORS_GROUP_KMEANS = {
    52: [[10, 13],  [16, 30],  [33, 23]],
    26: [[30, 61],  [62, 45],  [59, 119]],
    13: [[116, 90],  [156, 198],  [373, 326]]}
#  建议框面积
ANCHORS_GROUP_KMEANS_AREA = {
    13: [x * y for x, y in ANCHORS_GROUP_KMEANS[13]],
    26: [x * y for x, y in ANCHORS_GROUP_KMEANS[26]],
    52: [x * y for x, y in ANCHORS_GROUP_KMEANS[52]],
}


#  定义one_hot函数
def one_hot(cls_num, i):
    b = np.zeros(cls_num)
    b[i] = 1.
    return b


#  定义生成标签函数
def gen_label():
    labels = {}
    strs = BOXES.split()
    _boxes = np.array(list(map(float, strs[1:])))  # 转变数据类型
    boxes = np.split(_boxes, len(_boxes) // 5)  # 切分成n组,得到n个目标框

    for feature_size, anchors in ANCHORS_GROUP_KMEANS.items():  # 遍历3种特征图尺寸
        # 对每种特征图尺寸,建一个对应形状的张量用以存放标签
        labels[feature_size] = np.zeros(shape=(feature_size, feature_size, 3, 5 + CLASS_NUM))
        for box in boxes:  # 遍历目标框
            cls, cx, cy, w, h = box  # 目标类别,中心点坐标x&y, 宽,高
            # cx_index:索引,与网格一一对应。cx_offset:中心点相对于网格左上角的偏移率
            cx_offset, cx_index = math.modf(cx * feature_size / IMG_WIDTH)
            # cfg.IMG_WIDTH / feature_size实际上就是步长
            cy_offset, cy_index = math.modf(cy * feature_size / IMG_WIDTH)
            for i, anchor in enumerate(anchors):  # 遍历3种建议框
                anchor_area = ANCHORS_GROUP_KMEANS_AREA[feature_size][i]  # 每种特征图对应的3种建议框的面积
                p_w, p_h = w / anchor[0], h / anchor[1]  # 目标框相对于建议框的偏移率
                p_area = w * h  # 目标框的面积
                iou = min(p_area, anchor_area) / max(p_area, anchor_area)  # 小框比大框
                # 标签存入对应尺寸特征图对应点的通道内
                labels[feature_size][int(cy_index), int(cx_index), i] = np.array(
                    [iou, cx_offset, cy_offset, np.log(p_w), np.log(p_h), *one_hot(CLASS_NUM, int(cls))]) 
    return labels[13], labels[26], labels[52]


if __name__ == '__main__':
    label_13, label_26, label_52 = gen_label()
    print(label_13.shape)  # (13, 13, 3, 7)

你可能感兴趣的:(YOLOv3之标签生成)