Esempio n. 1
0
def gen_PNet_bbox_data(anno_file, im_dir, save_dir, debug=False):
    print('gen PNet bbox data.')
    pos_save_dir = os.path.join(save_dir, 'positive')
    part_save_dir = os.path.join(save_dir, 'part')
    neg_save_dir = os.path.join(save_dir, 'negative')

    if not os.path.exists(save_dir):
        os.mkdir(save_dir)
    if not os.path.exists(pos_save_dir):
        os.mkdir(pos_save_dir)
    if not os.path.exists(part_save_dir):
        os.mkdir(part_save_dir)
    if not os.path.exists(neg_save_dir):
        os.mkdir(neg_save_dir)

    pos_list_file = os.path.join(save_dir, 'pos_12.txt')
    neg_list_file = os.path.join(save_dir, 'neg_12.txt')
    part_list_file = os.path.join(save_dir, 'part_12.txt')
    f1 = open(pos_list_file, 'w')
    f2 = open(neg_list_file, 'w')
    f3 = open(part_list_file, 'w')
    with open(anno_file, 'r') as f:
        annotations = f.readlines()

    if debug:
        annotations = annotations[:500]

    num = len(annotations)
    print "{} pics in total".format(num)
    p_idx = 0  # positive
    n_idx = 0  # negative
    d_idx = 0  # dont care
    idx = 0
    box_idx = 0
    for annotation in annotations:
        annotation = annotation.strip().split(' ')
        im_path = annotation[0]
        bbox = map(float, annotation[1:])
        boxes = np.array(bbox, dtype=np.float32).reshape(-1, 4)
        img = cv2.imread(os.path.join(im_dir, im_path + '.jpg'))
        idx += 1
        if idx % 1000 == 0:
            print '{}/{} images done'.format(idx, num)

        height, width, channel = img.shape

        neg_num = 0
        while neg_num < 50:
            #neg_num's size [40,min(width, height) / 2],min_size:40
            size = np.random.randint(12, min(width, height) / 2)
            nx = np.random.randint(0, width - size)
            ny = np.random.randint(0, height - size)
            crop_box = np.array([nx, ny, nx + size, ny + size])
            Iou = IoU(crop_box, boxes)

            cropped_im = img[ny:ny + size, nx:nx + size, :]
            resized_im = cv2.resize(cropped_im, (12, 12),
                                    interpolation=cv2.INTER_LINEAR)

            if np.max(Iou) < 0.3:
                save_file = os.path.join(neg_save_dir, '{}.jpg'.format(n_idx))
                f2.write('{} 0\n'.format(save_file))
                cv2.imwrite(save_file, resized_im)
                n_idx += 1
                neg_num += 1
        for box in boxes:
            x1, y1, x2, y2 = box
            w = x2 - x1 + 1
            h = y2 - y1 + 1

            if max(w, h) < 40 or x1 < 0 or y1 < 0:
                continue
            for i in range(5):
                size = np.random.randint(12, min(width, height) / 2)
                delta_x = np.random.randint(max(-size, -x1), w)
                delta_y = np.random.randint(max(-size, -y1), h)
                nx1 = int(max(0, x1 + delta_x))
                ny1 = int(max(0, y1 + delta_y))
                if nx1 + size > width or ny1 + size > height:
                    continue
                crop_box = np.array([nx1, ny1, nx1 + size, ny1 + size])
                Iou = IoU(crop_box, boxes)

                cropped_im = img[ny1:ny1 + size, nx1:nx1 + size, :]
                resized_im = cv2.resize(cropped_im, (12, 12),
                                        interpolation=cv2.INTER_LINEAR)

                if np.max(Iou) < 0.3:
                    save_file = os.path.join(neg_save_dir,
                                             '{}.jpg'.format(n_idx))
                    f2.write('{} 0\n'.format(save_file))
                    cv2.imwrite(save_file, resized_im)
                    n_idx += 1
            # generate positive examples and part faces
            for i in range(20):
                size = np.random.randint(int(min(w, h) * 0.8),
                                         np.ceil(1.25 * max(w, h)))
                delta_x = np.random.randint(-w * 0.2, w * 0.2)
                delta_y = np.random.randint(-h * 0.2, h * 0.2)
                nx1 = int(max(x1 + w / 2 + delta_x - size / 2, 0))
                ny1 = int(max(y1 + h / 2 + delta_y - size / 2, 0))
                nx2 = nx1 + size
                ny2 = ny1 + size

                if nx2 > width or ny2 > height:
                    continue
                crop_box = np.array([nx1, ny1, nx2, ny2])
                offset_x1 = (x1 - nx1) / float(size)
                offset_y1 = (y1 - ny1) / float(size)
                offset_x2 = (x2 - nx2) / float(size)
                offset_y2 = (y2 - ny2) / float(size)
                cropped_im = img[ny1:ny2, nx1:nx2, :]
                resized_im = cv2.resize(cropped_im, (12, 12),
                                        interpolation=cv2.INTER_LINEAR)

                box_ = box.reshape(1, -1)
                if IoU(crop_box, box_) >= 0.65:
                    save_file = os.path.join(pos_save_dir,
                                             '{}.jpg'.format(p_idx))
                    f1.write('{} 1 {:.2} {:.2} {:.2} {:.2}\n'.format(
                        save_file, offset_x1, offset_y1, offset_x2, offset_y2))
                    cv2.imwrite(save_file, resized_im)
                    p_idx += 1
                elif IoU(crop_box, box_) >= 0.4:
                    save_file = os.path.join(part_save_dir,
                                             '{}.jpg'.format(d_idx))
                    f3.write('{} -1 {:.2} {:.2} {:.2} {:.2}\n'.format(
                        save_file, offset_x1, offset_y1, offset_x2, offset_y2))
                    cv2.imwrite(save_file, resized_im)
                    d_idx += 1
            box_idx += 1

    print '{} images done, pos: {} part: {} neg: {}'.format(
        idx, p_idx, d_idx, n_idx)
    f1.close()
    f2.close()
    f3.close()
    return pos_list_file, neg_list_file, part_list_file
            print('')
            # break
        # if i > 10: break
        Array = np.load(npz)
        bbox = Array['bbox']
        wh = bbox[2:4] - bbox[0:2] + 1
        wh = wh[None, :]
        animoji = Array['landmark']
        animoji = animoji.reshape(70, 2)
        boxes_pred = Array['boxes_pred']
        landmarks_pred = Array['landmarks_pred']
        animojis_pred = Array['animoji_pred']
        if len(boxes_pred.shape) == 0:
            continue

        iou = IoU(bbox, boxes_pred)
        idx = np.argmax(iou)

        if iou[idx] < 0.4:
            continue

        image = cv2.imread(filepath)
        image2 = image.copy()
        h, w, _ = image2.shape
        line_w = int(max(h, w) / 500 + 1)

        boxes = boxes_pred[idx]
        landmarks = landmarks_pred[idx]

        animoji_pred = animojis_pred[idx]
        animojis_landmark = landmarknet.predict(image.copy(), [boxes],
Esempio n. 3
0
def save_hard_example(images, det_boxes, gt_bboxes, image_size, save_dir):
    print('Save hard example.')
    pos_save_dir = os.path.join(save_dir, 'positive')
    part_save_dir = os.path.join(save_dir, 'part')
    neg_save_dir = os.path.join(save_dir, 'negative')

    if not os.path.exists(save_dir):
        os.mkdir(save_dir)
    if not os.path.exists(pos_save_dir):
        os.mkdir(pos_save_dir)
    if not os.path.exists(part_save_dir):
        os.mkdir(part_save_dir)
    if not os.path.exists(neg_save_dir):
        os.mkdir(neg_save_dir)
    # save files
    neg_label_file = os.path.join(save_dir, 'neg_{}.txt'.format(image_size))
    neg_file = open(neg_label_file, 'w')

    pos_label_file = os.path.join(save_dir, 'pos_{}.txt'.format(image_size))
    pos_file = open(pos_label_file, 'w')

    part_label_file = os.path.join(save_dir, 'part_{}.txt'.format(image_size))
    part_file = open(part_label_file, 'w')
    num_of_images = len(images)
    print('processing {} images in total'.format(num_of_images))
    assert len(det_boxes) == num_of_images, '{}/{}'.format(
        len(det_boxes), num_of_images)
    assert len(gt_bboxes) == num_of_images, '{}/{}'.format(
        len(gt_bboxes), num_of_images)

    n_idx = 0
    p_idx = 0
    d_idx = 0
    image_done = 0
    for img, dets, gts in zip(images, det_boxes, gt_bboxes):
        gts = np.array(gts, dtype=np.float32).reshape(-1, 4)
        if image_done % 100 == 0:
            print('{}/{} images done'.format(image_done, num_of_images))
        image_done += 1

        if dets is None:
            continue
        if dets.shape[0] == 0:
            continue
        dets = convert_to_square(dets)
        dets[:, 0:4] = np.round(dets[:, 0:4])
        neg_num = 0
        for box in dets:
            x_left, y_top, x_right, y_bottom, _ = box.astype(int)
            width = x_right - x_left + 1
            height = y_bottom - y_top + 1

            if width < 20 or x_left < 0 or y_top < 0 or x_right > img.shape[
                    1] - 1 or y_bottom > img.shape[0] - 1:
                continue

            Iou = IoU(box, gts)
            cropped_im = img[y_top:y_bottom + 1, x_left:x_right + 1, :]
            resized_im = cv2.resize(cropped_im, (image_size, image_size),
                                    interpolation=cv2.INTER_LINEAR)

            if np.max(Iou) < 0.3 and neg_num < 60:
                save_file = os.path.join(neg_save_dir, '{}.jpg'.format(n_idx))
                neg_file.write(save_file + ' 0\n')
                cv2.imwrite(save_file, resized_im)
                n_idx += 1
                neg_num += 1
            else:
                idx = np.argmax(Iou)
                assigned_gt = gts[idx]
                x1, y1, x2, y2 = assigned_gt

                offset_x1 = (x1 - x_left) / float(width)
                offset_y1 = (y1 - y_top) / float(height)
                offset_x2 = (x2 - x_right) / float(width)
                offset_y2 = (y2 - y_bottom) / float(height)

                if np.max(Iou) >= 0.65:
                    save_file = os.path.join(pos_save_dir,
                                             '{}.jpg'.format(p_idx))
                    pos_file.write('{} 1 {:.2} {:.2} {:.2} {:.2}\n'.format(save_file,\
                                     offset_x1, offset_y1, offset_x2, offset_y2))
                    cv2.imwrite(save_file, resized_im)
                    p_idx += 1

                elif np.max(Iou) >= 0.4:
                    save_file = os.path.join(part_save_dir,
                                             '{}.jpg'.format(d_idx))
                    part_file.write('{} -1 {:.2} {:.2} {:.2} {:.2}\n'.format(save_file, \
                        offset_x1, offset_y1, offset_x2, offset_y2))
                    cv2.imwrite(save_file, resized_im)
                    d_idx += 1
    neg_file.close()
    part_file.close()
    pos_file.close()

    return [pos_label_file, neg_label_file, part_label_file]
Esempio n. 4
0
def GenLandmarkData(ftxt, net_type, size, output, argument=False, debug=False):
    dstdir = os.path.join(output, 'train_{}_landmark'.format(net_type))
    if not os.path.exists(output): os.makedirs(output)
    if not os.path.exists(dstdir): os.makedirs(dstdir)
    assert (os.path.exists(dstdir) and os.path.exists(output))

    image_id = 0
    landmark_list_file = os.path.join(output,
                                      'landmark_{}.txt'.format(net_type))
    f = open(landmark_list_file, 'w')
    data = getDataFromTxt(ftxt)
    if debug:
        data = data[:10]
    idx = 0
    #image_path bbox landmark(5*2)
    print('landmark')
    for (imgPath, bbox, label, landmarkGt) in data:
        #print imgPath
        F_imgs = []
        F_landmarks = []
        imgPath = imgPath.replace('\\', '/')
        try:
            img = cv2.imread(imgPath)
            assert (img is not None), imgPath
            img_h, img_w, img_c = img.shape
            #litmit bbox
            gt_box = np.array([
                min(max(bbox.left, 0), img_w),
                min(max(bbox.top, 0), img_h),
                min(max(bbox.right, 0), img_w),
                min(max(bbox.bottom, 0), img_h)
            ])
            if min([bbox.left, bbox.top, bbox.right, bbox.bottom]) < 0:
                print([bbox.left, bbox.top, bbox.right, bbox.bottom])
                print(imgPath)
                #print(img.shape)

            f_face = img[gt_box[1]:gt_box[3] + 1, gt_box[0]:gt_box[2] + 1]
            f_face = cv2.resize(f_face, (size, size))
        except Exception as e:
            print(str(e))

        offset = np.array([gt_box[0], gt_box[1]],
                          dtype=np.float32).reshape(-1, 2)
        Length = np.array([gt_box[2] - gt_box[0], gt_box[3] - gt_box[1]],
                          dtype=np.float32).reshape(-1, 2)
        landmark = (landmarkGt - offset) / Length

        F_imgs.append(f_face)
        F_landmarks.append(landmark.reshape(-1))

        if argument:
            idx = idx + 1
            if idx % 1000 == 0:
                print('{}/{} images done'.format(idx, len(data)))
            x1, y1, x2, y2 = gt_box
            #width
            gt_w = x2 - x1 + 1
            #height
            gt_h = y2 - y1 + 1
            if max(gt_w, gt_h) < 40 or x1 < 0 or y1 < 0:
                continue
            #random shift
            for i in range(10):
                bbox_size = np.random.randint(int(min(gt_w, gt_h) * 0.8),
                                              np.ceil(1.25 * max(gt_w, gt_h)))
                delta_x = np.random.randint(-gt_w * 0.2, gt_w * 0.2)
                delta_y = np.random.randint(-gt_h * 0.2, gt_h * 0.2)
                nx1 = max(x1 + gt_w // 2 - bbox_size // 2 + delta_x, 0)
                ny1 = max(y1 + gt_h // 2 - bbox_size // 2 + delta_y, 0)

                nx2 = nx1 + bbox_size
                ny2 = ny1 + bbox_size
                if nx2 > img_w or ny2 > img_h:
                    continue
                crop_box = np.array([nx1, ny1, nx2, ny2])
                cropped_im = img[ny1:ny2 + 1, nx1:nx2 + 1, :]
                resized_im = cv2.resize(cropped_im, (size, size))

                iou = IoU(crop_box, np.expand_dims(gt_box, 0))
                if iou > 0.65:
                    F_imgs.append(resized_im)
                    #normalize

                    offset = np.array([nx1, ny1],
                                      dtype=np.float32).reshape(-1, 2)
                    Length = np.array([bbox_size, bbox_size],
                                      dtype=np.float32).reshape(-1, 2)
                    landmark_ = (landmarkGt - offset) / Length
                    F_landmarks.append(landmark_.reshape(-1))
                    # print(landmarkGt)
                    # print(landmark_)

                    bbox = BBox([nx1, ny1, nx2, ny2])

                    #mirror
                    # print(np.size(landmark_))
                    if np.size(landmark_) == 10:
                        face_flipped, landmark_flipped = flip(
                            resized_im, landmark_)
                        face_flipped = cv2.resize(face_flipped, (size, size))
                        F_imgs.append(face_flipped)
                        F_landmarks.append(landmark_flipped.reshape(-1))
                    #rotate +5
                    if random.choice([0, 1]) > 0:
                        face_rotated_by_alpha, landmark_rotated = rotate(img, bbox, \
                                                                         bbox.reprojectLandmark(landmark_), 5)
                        #landmark_offset
                        landmark_rotated = bbox.projectLandmark(
                            landmark_rotated)
                        face_rotated_by_alpha = cv2.resize(
                            face_rotated_by_alpha, (size, size))
                        F_imgs.append(face_rotated_by_alpha)
                        F_landmarks.append(landmark_rotated.reshape(-1))

                        #flip
                        if np.size(landmark_) == 10:
                            face_flipped, landmark_flipped = flip(
                                face_rotated_by_alpha, landmark_rotated)
                            face_flipped = cv2.resize(face_flipped,
                                                      (size, size))
                            F_imgs.append(face_flipped)
                            F_landmarks.append(landmark_flipped.reshape(-1))

                    #rotate -5
                    if random.choice([0, 1]) > 0:
                        face_rotated_by_alpha, landmark_rotated = rotate(img, bbox, \
                                                                         bbox.reprojectLandmark(landmark_), -5)
                        landmark_rotated = bbox.projectLandmark(
                            landmark_rotated)
                        face_rotated_by_alpha = cv2.resize(
                            face_rotated_by_alpha, (size, size))
                        F_imgs.append(face_rotated_by_alpha)
                        F_landmarks.append(landmark_rotated.reshape(-1))
                        if np.size(landmark_) == 10:
                            face_flipped, landmark_flipped = flip(
                                face_rotated_by_alpha, landmark_rotated)
                            face_flipped = cv2.resize(face_flipped,
                                                      (size, size))
                            F_imgs.append(face_flipped)
                            F_landmarks.append(landmark_flipped.reshape(-1))

            F_imgs, F_landmarks = np.asarray(F_imgs), np.asarray(F_landmarks)

            for i in range(len(F_imgs)):
                if np.sum(np.where(F_landmarks[i] <= 0, 1, 0)) > 0:
                    continue
                if np.sum(np.where(F_landmarks[i] >= 1, 1, 0)) > 0:
                    continue

                cv2.imwrite(os.path.join(dstdir, '{}.jpg'.format(image_id)),
                            F_imgs[i])
                landmarks = ' '.join(map(str, list(F_landmarks[i])))
                f.write(
                    os.path.join(
                        dstdir,
                        '{}.jpg {} {}\n'.format(image_id, label, landmarks)))
                image_id = image_id + 1
                if debug:
                    debug_path = os.path.join(output, 'debug')
                    if not os.path.exists(debug_path):
                        os.mkdir(debug_path)
                    if image_id < 10:
                        image = F_imgs[i].copy()
                        landmark = F_landmarks[i]
                        assert ((len(landmark)) % 2 == 0)
                        for j in range(len(landmark) // 2):
                            cv2.circle(
                                image,
                                (int(landmark[2 * j] * image.shape[1]),
                                 int(int(
                                     landmark[2 * j + 1] * image.shape[0]))),
                                3, (0, 0, 255))
                        cv2.imwrite(
                            os.path.join(debug_path,
                                         '{}.jpg'.format(image_id)), image)

    f.close()
    return F_imgs, F_landmarks, landmark_list_file
        neg_num = 0
        #1---->50
        # keep crop random parts, until have 50 negative examples
        # get 50 negative sample from every image
        while neg_num < 50:
            #neg_num's size [40,min(width, height) / 2],min_size:40
            # size is a random number between 12 and min(width,height)
            size = npr.randint(12, min(width, height) / 2)
            #top_left coordinate
            nx = npr.randint(0, width - size)
            ny = npr.randint(0, height - size)
            #random crop
            crop_box = np.array([nx, ny, nx + size, ny + size])
            #calculate iou
            Iou = IoU(crop_box, boxes)

            #crop a part from inital image
            cropped_im = img[ny:ny + size, nx:nx + size, :]
            #resize the cropped image to size 12*12
            resized_im = cv2.resize(cropped_im, (12, 12),
                                    interpolation=cv2.INTER_LINEAR)

            if np.max(Iou) < 0.3:
                # Iou with all gts must below 0.3
                save_file = os.path.join(neg_save_dir, "%s.jpg" % n_idx)
                f2.write("../XW-Dataset/Training/negative/%s.jpg" % n_idx +
                         ' 0\n')
                cv2.imwrite(save_file, resized_im)
                n_idx += 1
                neg_num += 1
Esempio n. 6
0
def save_hard_example(data, save_path, image_size):
    im_idx_list = data['images']
    gt_boxes_list = data['bboxes']
    num_of_images = len(im_idx_list)

    print("processing %d images in total" % num_of_images)

    neg_label_file = config.ROOT_DIR + "/data/train/neg_{}.txt".format(image_size)
    neg_file = open(neg_label_file, 'w')

    pos_label_file = config.ROOT_DIR + "/data/train/pos_{}.txt".format(image_size)
    pos_file = open(pos_label_file, 'w')

    part_label_file = config.ROOT_DIR + "/data/train/part_{}.txt".format(image_size)
    part_file = open(part_label_file, 'w')

    det_boxes = pickle.load(open(os.path.join(save_path, 'detections.pkl'), 'rb'))
    print(len(det_boxes))
    print(num_of_images)
    assert len(det_boxes) == num_of_images, "incorrect detections or ground truths"

    n_idx = 0
    p_idx = 0
    d_idx = 0
    image_done = 0
    for im_idx, dets, gts in zip(im_idx_list, det_boxes, gt_boxes_list):
        gts = np.array(gts, dtype=np.float32).reshape(-1, 4)
        if image_done % 100 == 0:
            print("%d images done" % image_done)
        image_done += 1

        if dets.shape[0] == 0:
            continue
        img = cv2.imread(im_idx)
        dets = convert_to_square(dets)
        dets[:, 0:4] = np.round(dets[:, 0:4])
        neg_num = 0
        for box in dets:
            x_left, y_top, x_right, y_bottom, _ = box.astype(int)
            width = x_right - x_left + 1
            height = y_bottom - y_top + 1

            # ignore box that is too small or beyond image border
            if width < 20 or x_left < 0 or y_top < 0 or x_right > img.shape[1] - 1 or y_bottom > img.shape[0] - 1:
                continue

            # compute intersection over union(IoU) between current box and all gt boxes
            Iou = IoU(box, gts)
            cropped_im = img[y_top:y_bottom + 1, x_left:x_right + 1, :]
            resized_im = cv2.resize(cropped_im, (image_size, image_size),
                                    interpolation=cv2.INTER_LINEAR)

            if np.max(Iou) < 0.3 and neg_num < 60:
                save_file = os.path.join(neg_dir, "%s.jpg" % n_idx)
                neg_file.write(save_file + ' 0\n')
                cv2.imwrite(save_file, resized_im)
                n_idx += 1
                neg_num += 1
            else:
                # find gt_box with the highest iou
                idx = np.argmax(Iou)
                assigned_gt = gts[idx]
                x1, y1, x2, y2 = assigned_gt

                # compute bbox reg label
                offset_x1 = (x1 - x_left) / float(width)
                offset_y1 = (y1 - y_top) / float(height)
                offset_x2 = (x2 - x_right) / float(width)
                offset_y2 = (y2 - y_bottom) / float(height)

                # save positive and part-face images and write labels
                if np.max(Iou) >= 0.65:
                    save_file = get_path(pos_dir, "%s.jpg" % p_idx)
                    pos_file.write(save_file + ' 1 %.2f %.2f %.2f %.2f\n' % (
                        offset_x1, offset_y1, offset_x2, offset_y2))
                    cv2.imwrite(save_file, resized_im)
                    p_idx += 1

                elif np.max(Iou) >= 0.4:
                    save_file = os.path.join(part_dir, "%s.jpg" % d_idx)
                    part_file.write(save_file + ' -1 %.2f %.2f %.2f %.2f\n' % (
                        offset_x1, offset_y1, offset_x2, offset_y2))
                    cv2.imwrite(save_file, resized_im)
                    d_idx += 1
    neg_file.close()
    part_file.close()
    pos_file.close()
Esempio n. 7
0
def gen_12net_data(anno_file, save_dir):
    pos_save_dir = os.path.join(save_dir, "positive")
    part_save_dir = os.path.join(save_dir, "part")
    neg_save_dir = os.path.join(save_dir, "negative")

    if not os.path.exists(save_dir):
        os.mkdir(save_dir)
    if not os.path.exists(pos_save_dir):
        os.mkdir(pos_save_dir)
    if not os.path.exists(part_save_dir):
        os.mkdir(part_save_dir)
    if not os.path.exists(neg_save_dir):
        os.mkdir(neg_save_dir)

    pos_12_file = os.path.join(save_dir, 'pos_12.txt')
    part_12_file = os.path.join(save_dir, 'part_12.txt')
    neg_12_file = os.path.join(save_dir, 'neg_12.txt')
    if os.path.exists(pos_12_file) and os.path.exists(part_12_file) and os.path.exists(neg_12_file):
        return
    f1 = open(pos_12_file, 'w')
    f2 = open(neg_12_file, 'w')
    f3 = open(part_12_file, 'w')
    with open(anno_file, 'r') as f:
        annotations = f.readlines()
    num = len(annotations)
    print("%d pics in total" % num)
    p_idx = 0  # positive
    n_idx = 0  # negative
    d_idx = 0  # don't care
    idx = 0
    box_idx = 0
    for annotation in annotations:
        annotation = annotation.strip().split(' ')
        im_path = annotation[0]
        bbox = list(map(float, annotation[1:]))
        boxes = np.array(bbox, dtype=np.float32).reshape(-1, 4)
        img = cv2.imread(im_path)
        idx += 1

        height, width, channel = img.shape

        neg_num = 0
        while neg_num < 3:
            size = npr.randint(12, min(width, height) / 2)
            nx = npr.randint(0, width - size)
            ny = npr.randint(0, height - size)
            crop_box = np.array([nx, ny, nx + size, ny + size])
            Iou = IoU(crop_box, boxes)

            cropped_im = img[ny: ny + size, nx: nx + size, :]
            resized_im = cv2.resize(cropped_im, (12, 12), interpolation=cv2.INTER_LINEAR)

            if len(list(Iou)) == 0:
                continue
            if np.max(Iou) < 0.3:
                save_file = os.path.join(neg_save_dir, "%s.jpg" % n_idx)
                f2.write(neg_save_dir + "/%s.jpg" % n_idx + ' 0\n')
                cv2.imwrite(save_file, resized_im)
                n_idx += 1
                neg_num += 1

        # for every bounding boxes
        for box in boxes:
            x1, y1, w, h = box
            x2 = x1 + w
            y2 = y1 + h

            if max(w, h) < 20 or x1 < 0 or y1 < 0:
                continue

            for i in range(2):
                # size of the image to be cropped
                size = npr.randint(12, min(width, height) / 2)
                delta_x = npr.randint(max(-size, -x1), w)
                delta_y = npr.randint(max(-size, -y1), h)
                nx1 = int(max(0, x1 + delta_x))
                ny1 = int(max(0, y1 + delta_y))
                if nx1 + size > width or ny1 + size > height:
                    continue
                crop_box = np.array([nx1, ny1, nx1 + size, ny1 + size])
                Iou = IoU(crop_box, boxes)

                cropped_im = img[ny1: ny1 + size, nx1: nx1 + size, :]

                resized_im = cv2.resize(cropped_im, (12, 12), interpolation=cv2.INTER_LINEAR)

                if np.max(Iou) < 0.3:
                    # Iou with all gts must below 0.3
                    save_file = os.path.join(neg_save_dir, "%s.jpg" % n_idx)
                    f2.write(neg_save_dir + "/%s.jpg" % n_idx + ' 0\n')
                    cv2.imwrite(save_file, resized_im)
                    n_idx += 1

            for i in range(1000):
                size = npr.randint(int(min(w, h) * 0.8), np.ceil(1.25 * max(w, h)))

                # delta here is the offset of box center
                if w < 5:
                    print(w)
                    continue

                delta_x = npr.randint(-w * 0.2, w * 0.2)
                delta_y = npr.randint(-h * 0.2, h * 0.2)

                nx1 = int(max(x1 + w / 2 + delta_x - size / 2, 0))
                ny1 = int(max(y1 + h / 2 + delta_y - size / 2, 0))
                nx2 = nx1 + size
                ny2 = ny1 + size

                if nx2 > width or ny2 > height:
                    continue
                crop_box = np.array([nx1, ny1, nx2, ny2])

                offset_x1 = (x1 - nx1) / float(size)
                offset_y1 = (y1 - ny1) / float(size)
                offset_x2 = (x2 - nx2) / float(size)
                offset_y2 = (y2 - ny2) / float(size)
                # crop
                cropped_im = img[ny1: ny2, nx1: nx2, :]
                # resize
                resized_im = cv2.resize(cropped_im, (12, 12), interpolation=cv2.INTER_LINEAR)

                box_ = box.reshape(1, -1)
                iou = IoU(crop_box, box_)
                if iou >= 0.65:
                    save_file = os.path.join(pos_save_dir, "%s.jpg" % p_idx)
                    f1.write(pos_save_dir + "/%s.jpg" % p_idx + ' 1 %.2f %.2f %.2f %.2f\n' % (
                    offset_x1, offset_y1, offset_x2, offset_y2))
                    cv2.imwrite(save_file, resized_im)
                    p_idx += 1
                elif iou >= 0.4:
                    save_file = os.path.join(part_save_dir, "%s.jpg" % d_idx)
                    f3.write(part_save_dir + "/%s.jpg" % d_idx + ' -1 %.2f %.2f %.2f %.2f\n' % (
                    offset_x1, offset_y1, offset_x2, offset_y2))
                    cv2.imwrite(save_file, resized_im)
                    d_idx += 1
            box_idx += 1
            if idx % 100 == 0:
                print("%s images done, pos: %s part: %s neg: %s" % (idx, p_idx, d_idx, n_idx))
    f1.close()
    f2.close()
    f3.close()