示例#1
0
                        offset_px1 = 0  #(px1 - x1_) / side_len
                        offset_py1 = 0  #(py1 - y1_) / side_len
                        offset_px2 = 0  #(px2 - x1_) / side_len
                        offset_py2 = 0  #(py2 - y1_) / side_len
                        offset_px3 = 0  #(px3 - x1_) / side_len
                        offset_py3 = 0  #(py3 - y1_) / side_len
                        offset_px4 = 0  #(px4 - x1_) / side_len
                        offset_py4 = 0  #(py4 - y1_) / side_len
                        offset_px5 = 0  #(px5 - x1_) / side_len
                        offset_py5 = 0  #(py5 - y1_) / side_len

                        # 剪切下图片,并进行大小缩放
                        face_crop = img.crop(crop_box)
                        face_resize = face_crop.resize((face_size, face_size))

                        iou = utils.iou(crop_box, np.array(boxes))[0]
                        if iou > 0.65:  # 正样本
                            positive_anno_file.write(
                                "positive/{0}.jpg {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14} {15}\n"
                                .format(positive_count, 1, offset_x1,
                                        offset_y1, offset_x2, offset_y2,
                                        offset_px1, offset_py1, offset_px2,
                                        offset_py2, offset_px3, offset_py3,
                                        offset_px4, offset_py4, offset_px5,
                                        offset_py5))
                            positive_anno_file.flush()
                            face_resize.save(
                                os.path.join(positive_image_dir,
                                             "{0}.jpg".format(positive_count)))
                            positive_count += 1
                        elif iou > 0.4:  # 部分样本
示例#2
0
                    y1_ = np.maximum(0, cy_ - side_len / 2)
                    x2_ = x1_ + side_len
                    y2_ = y1_ + side_len

                    crop_box = np.array([x1_, y1_, x2_, y2_])

                    # 计算坐标的偏移值
                    offset_x1 = (x1 - x1_) / side_len
                    offset_y1 = (y1 - y1_) / side_len
                    offset_x2 = (x2 - x2_) / side_len
                    offset_y2 = (y2 - y2_) / side_len

                    # 剪切下图片,并进行大小缩放
                    face_crop = img.crop(crop_box)
                    face_resize = face_crop.resize((face_size, face_size),
                                                   Image.ANTIALIAS)

                    iou = utils.iou(crop_box, _boxes, False)[0]

                    if iou > 0.5:  # positive and part
                        face_resize.save(
                            os.path.join(person_dir, "{0}.jpg".format(count)))
                        count += 1

                    elif iou < 0.3:  # negative
                        print("Negative simples, dropout")

        except Exception as e:
            print("List empty now!")
            # traceback.print_exc()
示例#3
0
def gen_sample(face_size, stop_value):
    print("gen size:{} image".format(face_size))

    positive_image_dir = os.path.join(save_path, str(face_size), "positive")
    negative_image_dir = os.path.join(save_path, str(face_size), "negative")
    part_image_dir = os.path.join(save_path, str(face_size), "part")

    for dir_path in [positive_image_dir, negative_image_dir, part_image_dir]:
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)

    positive_anno_filename = os.path.join(save_path, str(face_size),
                                          "positive.txt")
    negative_anno_filename = os.path.join(save_path, str(face_size),
                                          "negative.txt")
    part_anno_filename = os.path.join(save_path, str(face_size), "part.txt")

    positive_count = 0
    negative_count = 0
    part_count = 0
    #这里readlines会有/n readline没有
    # test = open(positive_anno_filename, "r")
    # print(test.readline())
    # exit()

    try:
        positive_anno_file = open(positive_anno_filename, "w")
        negative_anno_file = open(negative_anno_filename, "w")
        part_anno_file = open(part_anno_filename, "w")

        for i, line in enumerate(open(anno_src)):
            if i < 2:
                continue

            strs = line.split()
            #strs = ['000001.jpg', '95', '71', '226', '313']

            image_filename = strs[0].strip()
            print(image_filename)
            image_file = os.path.join(img_dir, image_filename)

            with Image.open(image_file) as img:
                img_w, img_h = img.size
                x1 = float(strs[1].strip())
                y1 = float(strs[2].strip())
                w = float(strs[3].strip())
                h = float(strs[4].strip())
                x2 = float(x1 + w)
                y2 = float(y1 + h)

                px1 = 0  #float(strs[5].strip())
                py1 = 0  #float(strs[6].strip())
                px2 = 0  #float(strs[7].strip())
                py2 = 0  #float(strs[8].strip())
                px3 = 0  #float(strs[9].strip())
                py3 = 0  #float(strs[10].strip())
                px4 = 0  #float(strs[11].strip())
                py4 = 0  #float(strs[12].strip())
                px5 = 0  #float(strs[13].strip())
                py5 = 0  #float(strs[14].strip())

                if x1 < 0 or y1 < 0 or w < 0 or h < 0:
                    continue
                #原图的框框
                boxes = [[x1, y1, x2, y2]]

                cx = x1 + w / 2
                cy = y1 + h / 2
                side_len = max(w, h)

                count = 0
                for _ in range(5):
                    # 边长放缩比例
                    side_len_scale = np.random.uniform(0.8, 1.2)
                    _side_len = int(side_len * side_len_scale)
                    if _side_len == 0:
                        continue
                    # print(_side_len)

                    if np.random.randint(0, 10) < 1:
                        #生成同一范围内两个随机数
                        #给xy不同比例的偏移量
                        positive_scale = np.random.uniform(0, 0.08, 2)

                        # part_scale = np.random.uniform(0.15, 0.25)

                        part_scale = np.random.uniform(0.2, 0.6, 2)
                        part_scale = part_scale if np.random.randint(
                            0, 2) else -part_scale
                        offset_scale = [positive_scale, part_scale]
                        seed = offset_scale[np.random.randint(0, 2)]
                        _cx = cx + int(-_side_len * seed[0])
                        _cy = cy + int(-_side_len * seed[1])

                        _x1 = _cx - _side_len / 2
                        _y1 = _cy - _side_len / 2
                        _x2 = _x1 + _side_len
                        _y2 = _y1 + _side_len
                    else:
                        if img_w - _side_len <= 0 or img_h - _side_len <= 0:
                            continue
                        else:
                            _x1 = np.random.randint(0, img_w - _side_len)
                            _y1 = np.random.randint(0, img_h - _side_len)
                            _x2 = _x1 + _side_len
                            _y2 = _y1 + _side_len

                    if _x1 < 0 or _y1 < 0 or _x2 > img_w or _y2 > img_h:
                        continue

                    offset_x1 = (x1 - _x1) / _side_len
                    offset_y1 = (y1 - _y1) / _side_len
                    offset_x2 = (x2 - _x2) / _side_len
                    offset_y2 = (y2 - _y2) / _side_len

                    offset_px1 = 0  #(px1 - x1_) / side_len
                    offset_py1 = 0  #(py1 - y1_) / side_len
                    offset_px2 = 0  #(px2 - x1_) / side_len
                    offset_py2 = 0  #(py2 - y1_) / side_len
                    offset_px3 = 0  #(px3 - x1_) / side_len
                    offset_py3 = 0  #(py3 - y1_) / side_len
                    offset_px4 = 0  #(px4 - x1_) / side_len
                    offset_py4 = 0  #(py4 - y1_) / side_len
                    offset_px5 = 0  #(px5 - x1_) / side_len
                    offset_py5 = 0  #(py5 - y1_) / side_len

                    crop_box = [_x1, _y1, _x2, _y2]
                    face_crop = img.crop(crop_box)
                    face_resize = face_crop.resize((face_size, face_size))

                    iou = utils.iou(crop_box, np.array(boxes))[0]
                    if iou > 0.65:
                        if positive_count >= stop_value * 0.2:
                            continue
                        positive_anno_file.write(
                            "positive\{0}.jpg {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14} {15}\n"
                            .format(positive_count, 1, offset_x1, offset_y1,
                                    offset_x2, offset_y2, offset_px1,
                                    offset_py1, offset_px2, offset_py2,
                                    offset_px3, offset_py3, offset_px4,
                                    offset_py4, offset_px5, offset_py5))
                        #flush 写入一次保存一次
                        positive_anno_file.flush()
                        face_resize.save(
                            os.path.join(positive_image_dir,
                                         "{0}.jpg".format(positive_count)))
                        positive_count += 1
                    elif 0.5 > iou > 0.25:
                        if part_count >= stop_value * 0.2:
                            continue
                        part_anno_file.write(
                            "part\{0}.jpg {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14} {15}\n"
                            .format(part_count, 2, offset_x1, offset_y1,
                                    offset_x2, offset_y2, offset_px1,
                                    offset_py1, offset_px2, offset_py2,
                                    offset_px3, offset_py3, offset_px4,
                                    offset_py4, offset_px5, offset_py5))
                        part_anno_file.flush()
                        face_resize.save(
                            os.path.join(part_image_dir,
                                         "{0}.jpg".format(part_count)))
                        part_count += 1
                    elif iou < 0.1:
                        if negative_count >= stop_value * 0.6:
                            continue
                        negative_anno_file.write(
                            "negative\{0}.jpg {1} 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
                            .format(negative_count, 0))
                        negative_anno_file.flush()
                        face_resize.save(
                            os.path.join(negative_image_dir,
                                         "{0}.jpg".format(negative_count)))
                        negative_count += 1

                    count = positive_count + part_count + negative_count
                    print(positive_count, part_count, negative_count)
                if count >= stop_value:
                    break

    finally:
        positive_anno_file.close()
        negative_anno_file.close()
        part_anno_file.close()
示例#4
0
                        offset_px2 = 0  #(px2 - x1_) / side_len
                        offset_py2 = 0  #(py2 - y1_) / side_len
                        offset_px3 = 0  #(px3 - x1_) / side_len
                        offset_py3 = 0  #(py3 - y1_) / side_len
                        offset_px4 = 0  #(px4 - x1_) / side_len
                        offset_py4 = 0  #(py4 - y1_) / side_len
                        offset_px5 = 0  #(px5 - x1_) / side_len
                        offset_py5 = 0  #(py5 - y1_) / side_len

                        # 剪切下图片,并进行大小缩放
                        face_crop = img.crop(crop_box)  # 抠图
                        face_resize = face_crop.resize(
                            (face_size, face_size),
                            Image.ANTIALIAS)  #按照人脸尺寸进行缩放:12/24/48

                        iou = utils.iou(crop_box,
                                        np.array(boxes))[0]  # 抠出来的框和原来的框计算IOU
                        if iou > 0.6:  # 正样本;原为0.65
                            positive_anno_file.write(
                                "positive/{0}.jpg {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14} {15}\n"
                                .format(positive_count, 1, offset_x1,
                                        offset_y1, offset_x2, offset_y2,
                                        offset_px1, offset_py1, offset_px2,
                                        offset_py2, offset_px3, offset_py3,
                                        offset_px4, offset_py4, offset_px5,
                                        offset_py5))
                            positive_anno_file.flush()  # flush:将缓存区的数据写入文件
                            face_resize.save(
                                os.path.join(
                                    positive_image_dir,
                                    "{0}.jpg".format(positive_count)))  # 保存
                            positive_count += 1
def generatedataset(pass_used=False, treat_img=True, gen_label=True):
    pic_used_dict = {12: "12.txt", 24: "24.txt", 48: "48.txt"}

    # 新旧标签列表
    datalist_read = []
    # datalist_write = []

    with open(labelfile, 'r') as f:
        for i, line in enumerate(f.readlines()):
            # 第一行为标量行,不读
            if (i > 0):
                datalist_read.append(line.strip())

    ioulist = []
    # 定义三个样本的计数
    positive_num_ = 0
    negative_num_ = 0
    part_num_ = 0

    positive_num = 0
    negative_num = 0
    part_num = 0
    for face_size in face_sizes:
        datalist_write = []  # 注意datalist清空位置,注意计数
        '''
           将已生成的图片存起来,下次不再生成'''
        pic_used_txt = pic_used_dict.get(face_size)
        if pass_used:

            pic_used_list = []

            if os.path.exists(pic_used_txt):
                with open(pic_used_txt) as f:
                    for line in f.readlines():

                        if line[0].isdigit():
                            pic_used_list.append(line.strip().split()[0])
        elif os.path.exists(pic_used_txt):
            os.remove(pic_used_txt)

        "定义三个尺寸的文件保存路径"
        # positive_savepath = os.path.join(pic_savepath, str(face_size), "positive")
        # negative_savepath = os.path.join(pic_savepath, str(face_size), "negative")
        # part_savepath = os.path.join(pic_savepath, str(face_size), "part")
        # pic_savepathlist = [negative_savepath,positive_savepath,part_savepath]
        # 定义图片保存文件夹
        # pic_savedict = {
        #     0: os.path.join(pic_savepath, str(face_size), "negative"),
        #     1: os.path.join(pic_savepath, str(face_size), "positive"),
        #     2: os.path.join(pic_savepath, str(face_size), "part")
        # }
        '''
        定义每个尺寸图片保存文件夹和标签保存文件的dict
        图片要按照置信分类,标签不用'''
        save_dict = {
            "pic": {
                0: os.path.join(pic_savepath, str(face_size), "negative"),
                1: os.path.join(pic_savepath, str(face_size), "positive"),
                2: os.path.join(pic_savepath, str(face_size), "part")
            },
            "label":
            os.path.join(label_savepath,
                         "label_{0}.txt".format(str(face_size)))
        }
        # positive part negative集中放置,这几个文件夹不用生成
        # for i in [0, 1, 2]:
        #     utils.makedir(save_dict['pic'][i])

        "遍历标签数据"
        for i, strdata in enumerate(datalist_read):
            "分隔每行数据"
            data = strdata.strip().split()
            if pass_used:
                if data[0] in pic_used_list:
                    continue

            # x,y,w,h = map(int,data[1],data[2],data[3],data[4])#这个写法不行
            # x1, y1, w, h, width, height = map(int, data[1:7])#本身可以实现数据的strip()
            # x1, y1, w, h, width, height = map(int, map(str.strip,data[1:7]))#不以逗号分隔了,改为空格
            x1, y1, x2, y2, w, h, width, height = map(int, data[1:9])
            "图片过滤"
            # if (x1 < 0 or y1 < 0 or w < 0 or h < 0 or max(w, h) < 40):
            #     continue
            "判断是否有小于0的元素,框的大小是否比40小,框是否在图片内"
            if any([d < 0 for d in map(int, data[1:9])
                    ]) or min(w, h) < 40 or max(w, h) > min(width, height):
                # print("false data: ", data)
                # 输出错误数据
                continue
            '''
            补方框'''
            # "判断框是否为近方框"
            # if w / (w + h) > 0.6 or w / (w + h) < 0.3:
            #     pass
            # else:
            #     continue

            # x1, y1, x2, y2, w, h, width, height = map(int, data[1:9])

            "计算右下角坐标x1,y1和中心点x0,y0"
            # x2, y2 = x1 + w, y1 + h
            # x0, y0 = x1 + w // 2, y1 + h // 2
            for j in range(len(wh_scales)):
                k = 0
                while k < each_pic_num:
                    '''
                    name是加载图片的名称
                    pic_name 是新生成图片的名称'''

                    name, offset, box, box_ = utils.getoffset(
                        data, wh_scale=wh_scales[j], size_scale=size_scale)

                    iou_value = utils.iou(box, box_)

                    # 生成图片文件名
                    pic_name = "%s_%d_0%1d%02d.jpg" % (
                        name.split('.')[0], face_size, j, k
                    )  # 文件名中第二个"_"后的第一个0代表正或部分样本,另外生成的负样本此处为1

                    # 生成图片路径
                    "置信"
                    confidence = getconfidence(iou_value)

                    "图片保存路径"
                    if confidence == -1:
                        continue
                    else:
                        ioulist.append(iou_value)
                        k += 1

                    pic_savedir = os.path.join(pic_savepath, str(face_size))
                    utils.makedir(pic_savedir)
                    pic_savefile = os.path.join(pic_savedir, pic_name)

                    "标签保存路径"
                    label_savefile = os.path.join(save_dict['label'])

                    "原图片路径"
                    pic_file = os.path.join(picpath, name)

                    if treat_img:
                        utils.imgTreat(pic_file, pic_savefile, box_, face_size)

                    datalist_write.append(
                        utils.generateLabeldata(pic_name, confidence, offset))
                    # 三个样本计数

                    if positive_range[0] < iou_value < positive_range[1]:
                        positive_num_ += 1
                    elif part_range[0] < iou_value < part_range[1]:
                        part_num_ += 1
                    elif negative_range[0] < iou_value < negative_range[1]:
                        negative_num_ += 1
                if i % 100 == 0:
                    total_num_ = positive_num_ + part_num_ + negative_num_
                    print("epoch", i, positive_num_, part_num_, negative_num_,
                          total_num_)
                    if all([
                            positive_num_ > 0, part_num_ > 0,
                            negative_num_ > 0, total_num_ > 0
                    ]):
                        print("positive: %.3f, %.3f" %
                              (positive_num_ / part_num_,
                               positive_num_ / negative_num_))
                        print("ratio: %.3f, %.3f, %.3f" %
                              (positive_num_ / total_num_,
                               part_num_ / total_num_,
                               negative_num_ / total_num_))  # 临时查看一下数量
                    print("********************")

            if pass_used:
                with open(pic_used_txt, 'a') as pic_used_file:
                    print(data[0], file=pic_used_file)

        if len(datalist_write) != 0 and gen_label:
            utils.generateLabel(datalist_write, label_savefile, face_size)

    # 三个样本计数
    for i in ioulist:
        if positive_range[0] < i < positive_range[1]:
            positive_num += 1
        elif part_range[0] < i < part_range[1]:
            part_num += 1
        elif negative_range[0] < i < negative_range[1]:
            negative_num += 1
    total_num = positive_num + part_num + negative_num
    print(positive_num, part_num, negative_num, total_num)
示例#6
0
                        y2_ = y1_ + side_len

                        crop_box = np.array([x1_, y1_, x2_, y2_])

                        # 计算坐标的偏移值
                        offset_x1 = (x1 - x1_) / side_len
                        offset_y1 = (y1 - y1_) / side_len
                        offset_x2 = (x2 - x2_) / side_len
                        offset_y2 = (y2 - y2_) / side_len

                        # 剪切下图片,并进行大小缩放
                        face_crop = img.crop(crop_box)
                        face_resize = face_crop.resize((face_size, face_size),
                                                       Image.ANTIALIAS)

                        iou = utils.iou(crop_box, _boxes, False)[0]
                        iou_min = utils.iou(crop_box, _boxes, True)[0]

                        if iou > 0.65 and iou_min > 0.65:  # 正样本
                            positive_file.write(
                                "positive/{0}.jpg {1} {2} {3} {4} {5}\n".
                                format(positive_count, 1, offset_x1, offset_y1,
                                       offset_x2, offset_y2))
                            positive_file.flush()
                            face_resize.save(
                                os.path.join(positive_image_dir,
                                             "{0}.jpg".format(positive_count)))
                            positive_count += 1

                        elif iou > 0.4 and iou_min > 0.4:  # 部分样本
                            part_file.write(
                        offset_px1 = 0#(px1 - x1_) / side_len   # 人的五官特征的偏移值
                        offset_py1 = 0#(py1 - y1_) / side_len
                        offset_px2 = 0#(px2 - x1_) / side_len
                        offset_py2 = 0#(py2 - y1_) / side_len
                        offset_px3 = 0#(px3 - x1_) / side_len
                        offset_py3 = 0#(py3 - y1_) / side_len
                        offset_px4 = 0#(px4 - x1_) / side_len
                        offset_py4 = 0#(py4 - y1_) / side_len
                        offset_px5 = 0#(px5 - x1_) / side_len
                        offset_py5 = 0#(py5 - y1_) / side_len

                        # 剪切下图片,并进行大小缩放
                        face_crop = img.crop(crop_box)          # 抠图
                        face_resize = face_crop.resize((face_size, face_size),Image.ANTIALIAS) #按照人脸尺寸进行缩放:12/24/48

                        iou = utils.iou(crop_box, np.array(boxes))[0]   # 抠出来的框和原来的框计算IOU
                        if iou > 0.6:  # 正样本;原为0.65
                            positive_anno_file.write(
                                "positive/{0}.jpg {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14} {15}\n".format(
                                    positive_count, 1, offset_x1, offset_y1,
                                    offset_x2, offset_y2, offset_px1, offset_py1, offset_px2, offset_py2, offset_px3,
                                    offset_py3, offset_px4, offset_py4, offset_px5, offset_py5))
                            positive_anno_file.flush() # flush:将缓存区的数据写入文件
                            face_resize.save(os.path.join(positive_image_dir, "{0}.jpg".format(positive_count))) # 保存
                            positive_count += 1
                        elif iou > 0.4:  # 部分样本;原为0.4
                            part_anno_file.write(
                                "part/{0}.jpg {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14} {15}\n".format(
                                    part_count, 2, offset_x1, offset_y1,offset_x2,
                                    offset_y2, offset_px1, offset_py1, offset_px2, offset_py2, offset_px3,
                                    offset_py3, offset_px4, offset_py4, offset_px5, offset_py5)) # 写入txt文件
示例#8
0
def gen_sample(save_path, face_size, stop_value):
    print("gen size:{} image".format(face_size))
    # 样本图片存储路径
    positive_image_dir = os.path.join(save_path, str(face_size), "positive")
    negative_image_dir = os.path.join(save_path, str(face_size), "negative")
    part_image_dir = os.path.join(save_path, str(face_size), "part")

    # 造出三种路径下的9个文件夹,// 12,24,48
    for dir_path in [positive_image_dir, negative_image_dir, part_image_dir]:
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)

    # 样本标签存储路径
    positive_anno_filename = os.path.join(save_path, str(face_size), "positive.txt")
    negative_anno_filename = os.path.join(save_path, str(face_size), "negative.txt")
    part_anno_filename = os.path.join(save_path, str(face_size), "part.txt")

    # 样本的统计数
    positive_count = 0
    negative_count = 0
    part_count = 0

    try:
        positive_anno_file = open(positive_anno_filename, "w")
        negative_anno_file = open(negative_anno_filename, "w")
        part_anno_file = open(part_anno_filename, "w")

        for i, line in enumerate(open(anno_src)):
            if i < 2:
                continue
            try:
                # 切割非空值元素
                strs = line.split()
                # print(strs)

                image_filename = strs[0].strip()
                print(image_filename)
                image_file = os.path.join(img_dir, image_filename)

                with Image.open(image_file) as img:
                    img_w, img_h = img.size
                    x1 = float(strs[1].strip())
                    y1 = float(strs[2].strip())
                    w = float(strs[3].strip())
                    h = float(strs[4].strip())

                    # 如果坐标或边长为负数,或者人脸框面积和最大边长正方形面积比(IOU)低于0.7(无法生成正样本),则丢弃
                    if x1 < 0 or y1 < 0 or w < 0 or h < 0 or (w * h) / (max(w, h) * max(w, h)) <= 0.7:
                        # if x1 < 0 or y1 < 0 or w < 0 or h < 0 or (min(w,h)*min(w,h)) / (w*h) <= 0.7:
                        continue

                    x2 = float(x1 + w)
                    y2 = float(y1 + h)

                    px1 = 0  # float(strs[5].strip())
                    py1 = 0  # float(strs[6].strip())
                    px2 = 0  # float(strs[7].strip())
                    py2 = 0  # float(strs[8].strip())
                    px3 = 0  # float(strs[9].strip())
                    py3 = 0  # float(strs[10].strip())
                    px4 = 0  # float(strs[11].strip())
                    py4 = 0  # float(strs[12].strip())
                    px5 = 0  # float(strs[13].strip())
                    py5 = 0  # float(strs[14].strip())

                    boxes = [[x1, y1, x2, y2]]

                    # 计算出人脸中心点位置
                    cx = x1 + w / 2
                    cy = y1 + h / 2

                    side_len = random.choice([w, h])  # 随机选一个边,(正方形)

                    # 一张图片生成的样本统计数
                    single_img_pos = 0
                    single_img_part = 0
                    single_img_neg = 0
                    while True:

                        if single_img_pos < 3:
                            _side_len = side_len + side_len * random.uniform(-0.2, 0.2) + 1
                            _cx = cx + cx * random.uniform(-0.2, 0.2) + 1
                            _cy = cy + cy * random.uniform(-0.2, 0.2) + 1

                        elif single_img_part < 3:
                            _side_len = side_len + side_len * random.uniform(-1, 1) + 1
                            _cx = cx + cx * random.uniform(-1, 1) + 1
                            _cy = cy + cy * random.uniform(-1, 1) + 1

                        elif single_img_neg < 9:
                            _side_len = side_len + side_len * random.uniform(-2, 2) + 1
                            _cx = cx + cx * random.uniform(-2, 2) + 1
                            _cy = cy + cy * random.uniform(-2, 2) + 1

                        _x1 = _cx - _side_len / 2  # 偏移后的中心点换算回偏移后起始点X,Y
                        _y1 = _cy - _side_len / 2
                        _x2 = _x1 + _side_len  # 获得偏移后的X2,Y2
                        _y2 = _y1 + _side_len
                        # 偏移后的的坐标点对应的是正方形
                        # 判断偏移超出整张图片的就跳过,不截图
                        if _x1 < 0 or _y1 < 0 or _x2 > img_w or _y2 > img_h or _side_len < face_size:
                            continue

                        offset_x1 = (x1 - _x1) / _side_len  # 获得换算后的偏移率
                        offset_y1 = (y1 - _y1) / _side_len
                        offset_x2 = (x2 - _x2) / _side_len
                        offset_y2 = (y2 - _y2) / _side_len

                        offset_px1 = 0  # (px1 - x1_) / side_len
                        offset_py1 = 0  # (py1 - y1_) / side_len
                        offset_px2 = 0  # (px2 - x1_) / side_len
                        offset_py2 = 0  # (py2 - y1_) / side_len
                        offset_px3 = 0  # (px3 - x1_) / side_len
                        offset_py3 = 0  # (py3 - y1_) / side_len
                        offset_px4 = 0  # (px4 - x1_) / side_len
                        offset_py4 = 0  # (py4 - y1_) / side_len
                        offset_px5 = 0  # (px5 - x1_) / side_len
                        offset_py5 = 0  # (py5 - y1_) / side_len

                        # 剪切下图片,并进行大小缩放
                        crop_box = [_x1, _y1, _x2, _y2]  # 获得需要截取图片样本的坐标
                        face_crop = img.crop(crop_box)
                        face_resize = face_crop.resize((face_size, face_size))

                        iou = utils.iou(crop_box, np.array(boxes))[0]

                        if iou > 0.7 and single_img_pos < 3:  # 正样本
                            positive_anno_file.write(
                                "positive/{0}.jpg {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14} {15}\n".format(
                                    positive_count, 1, offset_x1, offset_y1,
                                    offset_x2, offset_y2, offset_px1, offset_py1, offset_px2, offset_py2, offset_px3,
                                    offset_py3, offset_px4, offset_py4, offset_px5, offset_py5))
                            positive_anno_file.flush()
                            face_resize.save(os.path.join(positive_image_dir, "{0}.jpg".format(positive_count)))
                            single_img_pos += 1
                            positive_count += 1

                        elif 0.7 > iou > 0.3 and single_img_part < 3:  # 部分样本
                            part_anno_file.write(
                                "part/{0}.jpg {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14} {15}\n".format(
                                    part_count, 2, offset_x1, offset_y1, offset_x2,
                                    offset_y2, offset_px1, offset_py1, offset_px2, offset_py2, offset_px3,
                                    offset_py3, offset_px4, offset_py4, offset_px5, offset_py5))
                            part_anno_file.flush()
                            face_resize.save(os.path.join(part_image_dir, "{0}.jpg".format(part_count)))
                            single_img_part += 1
                            part_count += 1

                        elif iou < 0.1 and single_img_neg < 9:  # 负样本
                            negative_anno_file.write(
                                "negative/{0}.jpg {1} 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n".format(negative_count, 0))
                            negative_anno_file.flush()
                            face_resize.save(os.path.join(negative_image_dir, "{0}.jpg".format(negative_count)))
                            single_img_neg += 1
                            negative_count += 1

                        # 统计每张图片被生成各类样本的次数,当一张原始图像按照3:3:9的比例生成的数量达到15张时,换下一张图像
                        if single_img_pos + single_img_part + single_img_neg >= 15:
                            break

                # 统计总样本数
                count = positive_count + part_count + negative_count
                # 判断总样本数据是否到要求
                if count >= stop_value:
                    break

            except:
                traceback.print_exc()
    except:
        traceback.print_exc()