def Make_PicXML_2(sample_filename,
                  save_pic_filename,
                  save_xml_filename,
                  aug_modes,
                  datasize,
                  start=0):
    No = []
    place_x = []
    place_y = 0

    #画像の読み込み
    pais = []
    for i in range(34):
        filename = sample_filename + '/' + str(i) + '.jpg'
        pais.append(cv.imread(filename))

    sample_height = pais[0].shape[0]
    sample_width = pais[0].shape[1]

    for i in range(datasize):

        #サイズの倍率(90~100)
        magni = min(size_x / NUMBER / sample_width,
                    size_y / sample_height) * random.randint(90, 100) / 100

        x = int(magni * sample_width)
        y = int(magni * sample_height)

        #牌の種類の決定
        No = []
        for num in range(NUMBER):
            No.append(random.randint(0, 33))

        #場所の決定
        place_x = []
        place_x.append(random.randint(0, int(size_x - x * NUMBER)))
        for num in range(NUMBER):
            place_x.append(place_x[0] + x * (num + 1))

        place_y = random.randint(1, int(size_y - y))

        #画像の生成
        img = np.zeros((size_y, size_x, 3), dtype=np.uint8)
        img = cv.rectangle(img, (0, 0), (size_x, size_y), (0, 128, 0),
                           cv.FILLED)

        for num in range(NUMBER):
            pai = cv.resize(pais[No[num]], (x, y))

            #牌反転処理
            if random.randint(0, 1) == 0:
                pai = cv.flip(pai, 0)

            img[place_y:place_y + y, place_x[num]:place_x[num] + x] = pai

        #bb型に変換
        boxes = []
        for num in range(NUMBER):
            boxes.append(
                ia.BoundingBox(x1=place_x[num],
                               y1=place_y,
                               x2=place_x[num] + x,
                               y2=place_y + y,
                               label=dict[str(No[num])]))
        bb = ia.BoundingBoxesOnImage(boxes, shape=(size_x, size_y, 3))

        #アーグメーションの実行
        for mode in range(len(aug_modes)):
            img_aug, bb_aug = augment(img, bb, aug_modes[mode])

            #保存
            '''境界線を記入した画像を生成
            for num in range(len(bb_aug.bounding_boxes)):
                img_aug = cv.rectangle(img_aug, (int(bb_aug.bounding_boxes[num].x1), int(bb_aug.bounding_boxes[num].y1)),(int(bb_aug.bounding_boxes[num].x2),int(bb_aug.bounding_boxes[num].y2)), (0, 0, 0) , thickness=8)
            '''

            filename = save_pic_filename + '/' + str(start + i) + '_' + str(
                mode) + '.jpg'
            cv.imwrite(filename, img_aug)

            #XMLファイルの生成、保存
            To_Xml(str(start + i) + '_' + str(mode),
                   bb_aug,
                   save_dir=save_xml_filename)

        if i % 500 == 0:
            print("now complete No." + str(i))
Ejemplo n.º 2
0
        continue
    if base[0] == 'L' or base[0] == 'R': 
        # print(base)

        boxes = np.loadtxt(label, ndmin=2)

        H = img.shape[0]
        W = img.shape[1]
        
        bbs = []
        
        for box in boxes:
            x1, y1, x2, y2, l = convert_bbs_from_yolo(box[1]*W, box[2]*H, box[3]*W, box[4]*H, box[0])
            bbs.append(ia.BoundingBox(x1=x1, y1=y1, x2=x2, y2=y2,label=l))

        bbs=ia.BoundingBoxesOnImage(bbs, img.shape)

        for repeat in range(10):
            ia.seed(np.random.randint(0,1000))
            np.random.seed(np.random.randint(0,1000))
            seq = iaa.Sequential([
                    # iaa.Multiply((1.1, 1.1)),
                    # iaa.Fog(),
                    # iaa.PerspectiveTransform(scale=0.05),
                    # iaa.PiecewiseAffine(scale=0.015),
                    # iaa.ElasticTransformation(sigma=3, alpha = 3),
                    # iaa.Superpixels(p_replace = 0.1, n_segments=100),
                    # iaa.pillike.EnhanceSharpness(factor=5),
                    iaa.Affine(
                        translate_px={"x": int(np.random.normal(0,10)), "y": int(np.random.normal(0,10))},
                        scale=(np.random.normal(1,0.15),np.random.normal(1,0.15)),
Ejemplo n.º 3
0
            bndbox = read_xml_annotation(XML_DIR, name)
            shutil.copy(os.path.join(XML_DIR, name), AUG_XML_DIR)
            shutil.copy(os.path.join(IMG_DIR, name[:-4] + '.jpg'), AUG_IMG_DIR)

            for epoch in range(AUGLOOP):
                seq_det = seq.to_deterministic()  # 保持坐标和图像同步改变,而不是随机
                # 读取图片
                img = Image.open(os.path.join(IMG_DIR, name[:-4] + '.jpg'))
                # sp = img.size
                img = np.asarray(img)
                # bndbox 坐标增强
                for i in range(len(bndbox)):
                    bbs = ia.BoundingBoxesOnImage([
                        ia.BoundingBox(x1=bndbox[i][0],
                                       y1=bndbox[i][1],
                                       x2=bndbox[i][2],
                                       y2=bndbox[i][3]),
                    ],
                                                  shape=img.shape)

                    bbs_aug = seq_det.augment_bounding_boxes([bbs])[0]
                    boxes_img_aug_list.append(bbs_aug)

                    # new_bndbox_list:[[x1,y1,x2,y2],...[],[]]
                    n_x1 = int(
                        max(1, min(img.shape[1],
                                   bbs_aug.bounding_boxes[0].x1)))
                    n_y1 = int(
                        max(1, min(img.shape[0],
                                   bbs_aug.bounding_boxes[0].y1)))
                    n_x2 = int(
Ejemplo n.º 4
0
def process_json(job):
    train_csv_file = job.tempdir + '/train.csv'
    test_csv_file = job.tempdir + '/test.csv'
    fout = open(train_csv_file, "w")
    fout.write('filename,width,height,class,xmin,ymin,xmax,ymax\n')
    fout.close()
    fout = open(test_csv_file, "w")
    fout.write('filename,width,height,class,xmin,ymin,xmax,ymax\n')
    fout.close()
    statefile = 'projects/' + job.project['id'] + '/state.json'
    jsonbody = job.download_to_string(statefile)
    state = json.loads(jsonbody)
    if hasattr(job, 'jb'):
        job.jb.meta['current_step_size'] = len(state['photos'])
        job.jb.meta['current_step_processed'] = 0
        job.jb.save_meta()
    trn_sz = len(state['photos'])
    test_pct_set = False
    if hasattr(job, "test_pct") and job.test_pct > 0:
        trn_sz = int((1 - job.test_pct) * len(state['photos']))
        test_pct_set = True
    ct = 0
    for photo in state['photos']:
        if 'children' in photo and len(photo['children']) > 0:
            tags = []
            process_children(photo['children'], tags)
            fotopath = 'projects/' + photo['imgUrl']
            logger.debug(" looking for " + fotopath)
            bbox = []
            data = job.download_to_data(fotopath)
            img_array = np.array(bytearray(data), dtype=np.uint8)
            im = cv2.imdecode(img_array, -1)
            if hasattr(job, 'desired_size') and job.desired_size > 0:
                # old_size is in (height, width) format
                old_size = im.shape[:2]
                ratio = float(job.desired_size) / max(old_size)
                new_size = tuple([int(x * ratio) for x in old_size])

                # new_size should be in (width, height) format

                im = cv2.resize(im, (new_size[1], new_size[0]))

                delta_w = job.desired_size - new_size[1]
                delta_h = job.desired_size - new_size[0]
                top, bottom = 0, delta_h
                left, right = 0, delta_w

                color = [0, 0, 0]
                im = cv2.copyMakeBorder(im,
                                        top,
                                        bottom,
                                        left,
                                        right,
                                        cv2.BORDER_CONSTANT,
                                        value=color)
            # print(im.shape)
            for ch in tags:
                xmin = float(ch['xmin'] * im.shape[1])
                ymin = float(ch['ymin'] * im.shape[0])
                xmax = float(ch['xmax'] * im.shape[1])
                ymax = float(ch['ymax'] * im.shape[0])
                name = ch['tag']
                if name not in job.labelmap_dict:
                    job.labelmap_dict[name] = len(job.labelmap_dict) + 1
                bbox.append(
                    ia.BoundingBox(x1=xmin,
                                   y1=ymin,
                                   x2=xmax,
                                   y2=ymax,
                                   label=name))
            bbs = ia.BoundingBoxesOnImage(bbox, shape=im.shape)
            if ct <= trn_sz:
                fout = open(train_csv_file, "a")
            else:
                fout = open(test_csv_file, "a")
            tfile = fotopath.split('.')[0] + '.tcapture'
            timages = []
            if job.exists(tfile):
                tcapture = json.loads(job.download_to_string(tfile))
                timages = tcapture['images']
            for i in range(len(bbox)):
                after = bbox[i]
                fout.write(fotopath + ',' + str(im.shape[0]) + ',' +
                           str(im.shape[1]) + ',' + after.label + ',' +
                           str(after.x1) + ',' + str(after.y1) + ',' +
                           str(after.x2) + ',' + str(after.y2) + '\n')
                for tim in timages:
                    fout.write(tim['path'] + ',' + str(im.shape[0]) + ',' +
                               str(im.shape[1]) + ',' + after.label + ',' +
                               str(after.x1) + ',' + str(after.y1) + ',' +
                               str(after.x2) + ',' + str(after.y2) + '\n')
            if hasattr(job, 'aug') and job.aug:
                with concurrent.futures.ThreadPoolExecutor(
                        max_workers=multiprocessing.cpu_count()) as executor:
                    future_img = {
                        executor.submit(create_image, im, job, bbs, fout): i
                        for i in range(job.train_samples)
                    }
                    for future in concurrent.futures.as_completed(future_img):
                        img = future_img[future]
                        try:
                            data = future.result()
                        except Exception as exc:
                            print(
                                'train augmentation generated an exception: %s'
                                % (exc))
                if not test_pct_set:
                    fout.close()
                    fout = open(test_csv_file, "a")
                    with concurrent.futures.ThreadPoolExecutor(
                            max_workers=multiprocessing.cpu_count(
                            )) as executor:
                        future_img = {
                            executor.submit(create_image, im, job, bbs, fout):
                            i
                            for i in range(job.test_samples)
                        }
                        for future in concurrent.futures.as_completed(
                                future_img):
                            img = future_img[future]
                            try:
                                data = future.result()
                            except Exception as exc:
                                print(
                                    'test augmentation generated an exception: %s'
                                    % (exc))
            fout.close()
            ct += 1
            if hasattr(job, 'jb'):
                job.jb.meta['current_step_processed'] += 1
                job.jb.save_meta()

    print(job.labelmap_dict)
    job.upload_file(
        train_csv_file,
        'corpus/' + job.name + "/" + os.path.basename(train_csv_file))
    job.upload_file(
        test_csv_file,
        'corpus/' + job.name + "/" + os.path.basename(test_csv_file))
    job.train_csv_file = 'corpus/' + job.name + \
        "/" + os.path.basename(train_csv_file)
    job.test_csv_file = 'corpus/' + job.name + \
        "/" + os.path.basename(test_csv_file)
Ejemplo n.º 5
0
             flag = True
             # print("Error at {}, {} ymin > ymax".format(i, j))
         if not flag:
             writer.addObject(_class, round(xmin), round(ymin), round(xmax),
                              round(ymax))
             aug_bounding_boxes.append(
                 ia.BoundingBox(x1=xmax, y1=ymax, x2=xmin, y2=ymin))
     if not f:
         writer.save("darkflow/Data/Annotations/auto_{}.xml".format(i))
         cv2.imwrite("darkflow/Data/Images/auto_{}.jpg".format(i), image)
     if aug_bounding_boxes.__len__() > 0:
         for id in range(0, 50):
             seq_det = seq.to_deterministic()
             image1 = seq_det.augment_image(image=image)
             bounding_boxes = seq_det.augment_bounding_boxes([
                 ia.BoundingBoxesOnImage(aug_bounding_boxes, shape=(h, w))
             ])[0]
             writer = Writer(
                 "darkflow/Data/Images/auto_{}_aug_{}.jpg".format(i, id),
                 image1.shape[0], image1.shape[1])
             for box in bounding_boxes.bounding_boxes:
                 writer.addObject(_class, round(box.x2), round(box.y2),
                                  round(box.x1), round(box.y1))
             if not f:
                 writer.save(
                     "darkflow/Data/Annotations/auto_{}_aug_{}.xml".format(
                         i, id))
                 cv2.imwrite(
                     "darkflow/Data/Images/auto_{}_aug_{}.jpg".format(
                         i, id), image1)
 except Exception as e:
Ejemplo n.º 6
0
    def __getitem__(self, index):
        seqDet = self.augments.to_deterministic()

        # --------------------------------------------------------------------------------

        img_path = self.img_files[index % len(self.img_files)].rstrip()
        img = cv2.imread(img_path)

        # Handles images with less than three channels
        while len(img.shape) != 3:
            index += 1
            img_path = self.img_files[index % len(self.img_files)].rstrip()
            img = cv2.imread(img_path)

        h, w, _ = img.shape

        # --------------------------------------------------------------------------------

        label_path = self.label_files[index % len(self.img_files)].rstrip()

        if os.path.exists(label_path):
            labels = np.loadtxt(label_path).reshape(-1, 5)

            x1 = w * (labels[:, 1] - labels[:, 3] / 2)
            y1 = h * (labels[:, 2] - labels[:, 4] / 2)
            x2 = w * (labels[:, 1] + labels[:, 3] / 2)
            y2 = h * (labels[:, 2] + labels[:, 4] / 2)

            labels[:, 1] = x1
            labels[:, 2] = y1
            labels[:, 3] = x2
            labels[:, 4] = y2

        else:
            labels = np.array([])

        # --------------------------------------------------------------------------------

        bbs = ia.BoundingBoxesOnImage([
            ia.BoundingBox(x1=label[1],
                           y1=label[2],
                           x2=label[3],
                           y2=label[4],
                           label=label[0]) for label in labels
        ],
                                      shape=img.shape)
        augImg = seqDet.augment_images([img])[0]
        augImg = np.ascontiguousarray(augImg)
        augBBS = seqDet.augment_bounding_boxes([bbs])[0]
        augBBS = augBBS.remove_out_of_image().clip_out_of_image()

        # --------------------------------------------------------------------------------

        dim_diff = np.abs(h - w)

        # Upper (left) and lower (right) padding
        pad1, pad2 = dim_diff // 2, dim_diff - dim_diff // 2

        # Determine padding
        pad = ((pad1, pad2), (0, 0),
               (0, 0)) if h <= w else ((0, 0), (pad1, pad2), (0, 0))

        paddedResize = iaa.Sequential([
            iaa.PadToFixedSize(w + (2 * pad[1][0]),
                               h + (2 * pad[0][0]),
                               position="center",
                               pad_mode='constant',
                               pad_cval=128),
            iaa.Resize({
                "height": self.img_shape[0],
                "width": self.img_shape[1]
            })
        ])

        resizedImg = paddedResize.augment_images([augImg])[0]
        resizedBBS = paddedResize.augment_bounding_boxes([augBBS])[0]

        # --------------------------------------------------------------------------------

        # origDebug = bbs.draw_on_image(img, thickness=2, color=[0, 255, 0])
        # augmentedDebug = augBBS.draw_on_image(augImg, thickness=2, color=[0, 0, 255])
        # inputDebug = resizedBBS.draw_on_image(resizedImg, thickness=2, color=[255, 0, 0])
        # print("Original: ", origDebug.shape)
        # print("Augmented: ", augmentedDebug.shape)
        # print("Resized: ", inputDebug.shape)
        # cv2.imshow("orig", origDebug)
        # cv2.imshow("augmented", augmentedDebug)
        # cv2.imshow("resized", inputDebug)
        # cv2.waitKey(0)

        # --------------------------------------------------------------------------------
        resizedH, resizedW, _ = resizedImg.shape

        # Normalize
        inputImg = resizedImg / 255.

        # Channels-first
        inputImg = np.transpose(inputImg, (2, 0, 1))

        # As pytorch tensor
        inputImg = torch.from_numpy(inputImg).float()

        labelsArr = np.zeros((len(resizedBBS.bounding_boxes), 5),
                             dtype=np.float32)
        for i, box in enumerate(resizedBBS.bounding_boxes):
            cx = ((box.x1 + box.x2) / 2) / resizedW
            cy = ((box.y1 + box.y2) / 2) / resizedH
            w = (box.x2 - box.x1) / resizedW
            h = (box.y2 - box.y1) / resizedH

            labelsArr[i] = [box.label, cx, cy, w, h]

        # Fill matrix
        filledLabels = np.zeros((self.max_objects, 5))
        if labels is not None:
            filledLabels[range(len(labelsArr))
                         [:self.max_objects]] = labelsArr[:self.max_objects]

        filledLabels = torch.from_numpy(filledLabels)

        return img_path, inputImg, filledLabels
Ejemplo n.º 7
0
 def bbsoi(self):
     bbs = [ia.BoundingBox(x1=0, y1=1, x2=2, y2=3)]
     return [ia.BoundingBoxesOnImage(bbs, shape=self.image.shape)]
Ejemplo n.º 8
0
def main():
    # datapath为存放训练图片的地方
    datapath = '/home/zhex/data/yuncong/our/'
    # original_file为需要被增强的
    original_file = '/home/zhex/data/yuncong/our_train.txt'  # 需要被增强的训练真值txt
    # aug_file只记录了新增的增强后图片的box,要得到原始+增强的所有label:cat original_file augfile>finalfile(txt拼接)
    # aug_file输出是pdpd需要的格式,pytorch需要另行转换(可以拼接得到finalfile后直接将finalfile转换)
    aug_file = 'augfile_our.txt'
    dict_before = readlist(original_file)
    new_fp = open(aug_file, 'w')
    # augscene = {'Mall': 3, 'Part_B': 10, 'Part_A': 13}  # 需要哪些场景,新增几倍数量的新数据
    augscene = {'our': 13}
    for scene in augscene:
        for i in range(augscene[scene]):
            for img_id in dict_before.keys():
                if scene in img_id:
                    print(img_id)
                    img = Image.open(datapath + img_id)
                    img = np.array(img)
                    bbs = ia.BoundingBoxesOnImage([
                        ia.BoundingBox(x1=x, y1=y, x2=x + w, y2=y + h)
                        for [x, y, w, h] in dict_before[img_id]
                    ],
                                                  shape=img.shape)

                    # 设置数据增强方式
                    seq = iaa.SomeOf(
                        (1, 3),
                        [
                            iaa.Crop(px=(0, 16)),  # 裁剪
                            iaa.Multiply((0.7, 1.3)),  # 改变色调
                            iaa.Affine(scale=(0.5, 0.7)),  # 放射变换
                            iaa.GaussianBlur(sigma=(0, 1.5)),  # 高斯模糊
                            # iaa.AddToHueAndSaturation(value=(25,-25)),
                            iaa.ChannelShuffle(1),  # RGB三通道随机交换
                            iaa.ElasticTransformation(alpha=0.1),
                            # iaa.Grayscale(alpha=(0.2, 0.5)),
                            iaa.Pepper(p=0.03),
                            iaa.AdditiveGaussianNoise(scale=(0.03 * 255,
                                                             0.05 * 255)),
                            iaa.Dropout(p=(0.03, 0.05)),
                            iaa.Salt(p=(0.03, 0.05)),
                            iaa.AverageBlur(k=(1, 3)),
                            iaa.Add((-10, 10)),
                            iaa.CoarseSalt(size_percent=0.01)
                        ])
                    seq_det = seq.to_deterministic(
                    )  # 保持坐标和图像同步改变,每个batch都要调用一次,不然每次的增强都是一样的
                    image_aug = seq_det.augment_images([img])[0]
                    bbs_aug = seq_det.augment_bounding_boxes([bbs])[0]

                    pic_name = img_id.split('/')[-1].split('.')[0]
                    pic_dir = img_id.split(pic_name)[0]
                    if not os.path.exists(datapath + 'myaug/' + pic_dir):
                        os.makedirs(datapath + 'myaug/' + pic_dir)
                    new_img_id = 'myaug/' + pic_dir + pic_name + '_{}'.format(
                        i) + '.jpg'
                    Image.fromarray(image_aug).save(datapath + new_img_id)

                    new_fp = writelist(new_fp, new_img_id,
                                       bbs_aug.bounding_boxes)
Ejemplo n.º 9
0
    def doAugmentation(self):
        configurationFile = os.path.abspath(
            '.') + '/AugmenterConfigurations.xml'

        # parsing configuration file
        configurationTree = ET.parse(configurationFile)
        configurationRoot = configurationTree.getroot()

        # the directory of images to augment
        imageSourceDirectory = configurationRoot.findall(
            'imageSourceDirectory')[0].text
        # the directory of original xml
        xmlSourceDirectory = configurationRoot.findall(
            'xmlSourceDirectory')[0].text
        # the directory to save augmented images
        imageDestinationDirectory = configurationRoot.findall(
            'imageDestinationDirectory')[0].text
        # mkdir if destination directory doesn't exist
        if os.path.isdir(imageDestinationDirectory) is False:
            os.mkdir(imageDestinationDirectory)

        # load all of the augmenters described in configuration file
        augmenters = configurationRoot.findall('augmenter')

        # file type
        # be aware of the file type, ex: jpg v.s. JPG and jpg v.s. jpeg, they are different!
        fileExtension = '.jpg'

        # getting addresses of images to augment
        finishPartCount = 0
        imageAddresses = [
            imageSourceDirectory + '/' + f
            for f in os.listdir(imageSourceDirectory)
            if (f.__contains__(fileExtension))
        ]
        totalImageCount = len(imageAddresses)

        # counting the number of augmenters actually using
        augmenterCount = 0
        for a in augmenters:
            if a[1].text == 'Yes':
                augmenterCount += 1

        # data for showing augmented samples
        originalImageToShow = None
        augmentedImageToShow = []
        titlesToShow = []

        # augmentation
        augmenterHistory = [0] * len(augmenters)
        self.ui.stateTextEdit.append('Starting augmentation...')
        QCoreApplication.processEvents(QEventLoop.AllEvents)
        for a in augmenters:
            if a[1].text == 'Yes':  # checking whether the user want to use this augmenter
                self.ui.stateTextEdit.append('part: ' +
                                             str(finishPartCount + 1) + '/' +
                                             str(augmenterCount) +
                                             ' , augmenter: ' + a[0].text)
                QCoreApplication.processEvents(QEventLoop.AllEvents)

                # generate imgaug augmenter
                seq = self.generateAugmenter(augmenters, a[0].text,
                                             augmenterHistory)

                finishImageCount = 0
                for address in imageAddresses:
                    boundingBoxes = []

                    # getting target image and xml file
                    image = imageio.imread(address)
                    augmentedTree = ET.parse(
                        address.replace(imageSourceDirectory,
                                        xmlSourceDirectory).replace(
                                            fileExtension, '.xml'))
                    augmentedRoot = augmentedTree.getroot()

                    # getting bounding boxes
                    for obj in augmentedRoot.iter('object'):
                        boundingBoxes.append(
                            ia.BoundingBox(x1=int(obj[4][0].text),
                                           y1=int(obj[4][1].text),
                                           x2=int(obj[4][2].text),
                                           y2=int(obj[4][3].text),
                                           label=obj[0].text))
                    BBS = ia.BoundingBoxesOnImage(boundingBoxes,
                                                  shape=image.shape)

                    # augmentation
                    augmentedImage, augmentedBBS = seq(image=image,
                                                       bounding_boxes=BBS)

                    # xml handling
                    for fileName in augmentedRoot.iter('filename'):
                        newNameAttributes = '_'
                        if a[0].text == 'Crop':
                            newNameAttributes = newNameAttributes + a[0].text
                            if a[2][0].text == '0' and a[2][3].text == '0':
                                newNameAttributes = newNameAttributes + '=' + 'topLeft'
                            elif a[2][0].text == '0' and a[2][1].text == '0':
                                newNameAttributes = newNameAttributes + '=' + 'topRight'
                            elif a[2][2].text == '0' and a[2][1].text == '0':
                                newNameAttributes = newNameAttributes + '=' + 'bottomRight'
                            elif a[2][2].text == '0' and a[2][3].text == '0':
                                newNameAttributes = newNameAttributes + '=' + 'bottomLeft'
                            else:
                                newNameAttributes = newNameAttributes + '=' + 'center_percent' + a[
                                    2][0].text.replace('.', 'p')
                        elif a[0].text == 'Flipud' or a[0].text == 'Fliplr':
                            newNameAttributes = newNameAttributes + a[0].text
                        elif a[0].text == 'Rot':
                            newNameAttributes = newNameAttributes + a[
                                0].text + '=' + a[2][0].text
                        elif a[0].text == 'Add':
                            newNameAttributes = newNameAttributes + a[
                                0].text + '=' + a[2][0].text
                        else:
                            newNameAttributes = newNameAttributes + a[0].text
                            for args in a[2]:
                                newNameAttributes = newNameAttributes + '_' + args.tag + '=' + args.text.replace(
                                    '.', 'p')
                        newName = str(
                            fileName.text.replace(
                                fileExtension,
                                newNameAttributes)) + fileExtension
                        fileName.text = newName
                    for folder in augmentedRoot.iter('folder'):
                        newFolder = str(a[0].text)
                        folder.text = newFolder
                    for path in augmentedRoot.iter('path'):
                        newPath = str(imageDestinationDirectory
                                      ) + '/' + a[0].text + '/' + newName
                        path.text = newPath
                    for size in augmentedRoot.iter('size'):
                        size[0].text = str(augmentedImage.shape[1])
                        size[1].text = str(augmentedImage.shape[0])
                        size[2].text = str(augmentedImage.shape[2])
                    i = 0
                    for obj in augmentedRoot.findall('object'):
                        if augmentedBBS.bounding_boxes[
                                i].is_fully_within_image(augmentedImage.shape):
                            obj[4][0].text = str(
                                augmentedBBS.bounding_boxes[i].x1)
                            obj[4][1].text = str(
                                augmentedBBS.bounding_boxes[i].y1)
                            obj[4][2].text = str(
                                augmentedBBS.bounding_boxes[i].x2)
                            obj[4][3].text = str(
                                augmentedBBS.bounding_boxes[i].y2)
                        elif augmentedBBS.bounding_boxes[
                                i].is_partly_within_image(
                                    augmentedImage.shape):
                            augmentedBBS.bounding_boxes[i].clip_out_of_image(
                                augmentedImage.shape)
                            obj[4][0].text = str(
                                augmentedBBS.bounding_boxes[i].x1)
                            obj[4][1].text = str(
                                augmentedBBS.bounding_boxes[i].y1)
                            obj[4][2].text = str(
                                augmentedBBS.bounding_boxes[i].x2)
                            obj[4][3].text = str(
                                augmentedBBS.bounding_boxes[i].y2)
                        else:
                            augmentedRoot.remove(obj)
                        i += 1

                    # draw bounding boxes on image (uncomment to enable)
                    # augmentedImage = augmentedBBS.draw_on_image(
                    #     augmentedImage, size=5, color=[0, 0, 255])

                    # saving new xml file
                    # mkdir if destination directory doesn't exist
                    if os.path.isdir(newPath.replace(newName, '')) is False:
                        os.mkdir(newPath.replace(newName, ''))
                        os.mkdir(newPath.replace(newName, '/xmlFile'))
                    augmentedTree.write(
                        newPath.replace(newName,
                                        '/xmlFile/' + newName).replace(
                                            fileExtension, '.xml')
                    )  # for saving jpg and xml into seperate directories

                    # saving new image
                    imageio.imsave(newPath, augmentedImage)

                    # collecting samples to show
                    if configurationRoot.findall(
                            'showAugmentedSamples')[0].text == 'Yes':
                        if finishPartCount is 0 and finishImageCount is 0:
                            originalImageToShow = image
                        if finishImageCount is 0:  # sample images to show later
                            augmentedImageToShow.append(augmentedImage)
                            titlesToShow.append(newNameAttributes[1:])

                    finishImageCount += 1
                    self.ui.stateTextEdit.append(
                        str(finishImageCount) + '/' + str(totalImageCount) +
                        ', saved to: ' + newPath)
                    QCoreApplication.processEvents(QEventLoop.AllEvents)
                finishPartCount += 1
                self.ui.stateTextEdit.append('')
                QCoreApplication.processEvents(QEventLoop.AllEvents)

        # showing augmented samples
        # checking whether the user want to show augmented samples
        if configurationRoot.findall('showAugmentedSamples')[0].text == 'Yes':
            totalSampleCount = math.ceil(augmenterCount / 3)
            for i in range(0, augmenterCount, 3):
                self.ui.stateTextEdit.append('showing sample: ' +
                                             str(int((i / 3) + 1)) + '/' +
                                             str(totalSampleCount))
                QCoreApplication.processEvents(QEventLoop.AllEvents)
                plt.figure(figsize=(12.8, 7.2))
                plt.axis('off')
                if augmenterCount - i is 1:
                    plt.subplot(1, 2, 1)
                elif augmenterCount - i is 2:
                    plt.subplot(1, 3, 1)
                else:
                    plt.subplot(2, 2, 1)
                plt.imshow(originalImageToShow)
                plt.title('Original')
                j = 0
                while j < 3 and i + j < len(augmentedImageToShow):
                    if augmenterCount - i is 1:
                        plt.subplot(1, 2, j + 2)
                    elif augmenterCount - i is 2:
                        plt.subplot(1, 3, j + 2)
                    else:
                        plt.subplot(2, 2, j + 2)
                    plt.imshow(augmentedImageToShow[i + j])
                    plt.title(titlesToShow[i + j])
                    plt.axis('off')
                    j += 1
                plt.show()

        self.ui.stateTextEdit.append('Augmentation finished.')
        QCoreApplication.processEvents(QEventLoop.AllEvents)
Ejemplo n.º 10
0
import imgaug
from skimage.data import chelsea

if __name__ == '__main__':
    raw_im = chelsea()
    im = imgaug.imresize_single_image(raw_im, raw_im.shape[:2])

    # j,i,j+,i+
    bb = imgaug.BoundingBox(128, 64, 128 + 64 + 160, 64 + 128)

    imgaug.imshow(bb.draw_on_image(im, color=(0, 255, 0), size=5))

    seq = imgaug.augmenters.Sequential([
        imgaug.augmenters.Resize((0.5, 2.)),
        imgaug.augmenters.Fliplr(),
        imgaug.augmenters.Flipud(),
        imgaug.augmenters.CropToFixedSize(width=128, height=128)
    ])

    for _ in range(10):
        aug_ims, aug_bbs = seq(image=im,
                               bounding_boxes=imgaug.BoundingBoxesOnImage(
                                   [bb], shape=im.shape))

        imgaug.imshow(aug_bbs.draw_on_image(aug_ims, color=(0, 255, 0),
                                            size=5))
Ejemplo n.º 11
0
def data_aug(img, bboxs=None, keypoints=None, joint_nums=17):
    '''
    :param img: 需要进行数据增强的图像
    :param bboxs: list, [ [x1, y1, x2, y2], ..., [xn1, yn1, xn2, yn2] ]
    :param keypoints: 关键点, COCO format or Ai-challenger format, list of list, [ [num_joints x 3], [num_joints x 3], ..., ]
    :return:
    '''
    is_flip = [random.randint(0, 1), random.randint(0, 1)]
    seq = iaa.Sequential([
        iaa.Affine(rotate=(-15, 15), scale=(0.8, 1.2), mode='constant'),
        iaa.Multiply((0.7, 1.5)),
        iaa.Grayscale(iap.Choice(a=[0, 1], p=[0.8, 0.2]),
                      from_colorspace='BGR'),
        iaa.Fliplr(is_flip[0]),
        iaa.Flipud(is_flip[1]),
    ])

    seq_det = seq.to_deterministic()
    bbs = None
    kps = None
    bbs_aug = None
    kps_aug = None
    # joint_nums = 14
    new_bboxs = []
    new_keypoints = []
    kps_ori = copy.copy(keypoints)
    kps_ori = np.reshape(np.asarray(kps_ori),
                         newshape=(-1, joint_nums,
                                   3)) if kps_ori is not None else None

    if bboxs is not None:
        assert type(bboxs) == type([])
        bbs = ia.BoundingBoxesOnImage([], shape=img.shape)
        for box in bboxs:
            bbs.bounding_boxes.append(
                ia.BoundingBox(x1=box[0], y1=box[1], x2=box[2], y2=box[3]))

    if keypoints is not None:
        kps = ia.KeypointsOnImage([], shape=img.shape)
        assert type(keypoints) == type([])
        for single_person_keypoints in keypoints:
            for i in range(joint_nums):
                joint = single_person_keypoints[i * 3:i * 3 + 3]
                kps.keypoints.append(ia.Keypoint(x=joint[0], y=joint[1]))

    img_aug = seq_det.augment_image(img)
    if bbs is not None:
        # print(bbs)
        bbs_aug = seq_det.augment_bounding_boxes([bbs])
        # print(bbs_aug)
        for i in range(len(bbs_aug[0].bounding_boxes)):
            box_aug = bbs_aug[0].bounding_boxes[i]
            box = [box_aug.x1, box_aug.y1, box_aug.x2, box_aug.y2]
            new_bboxs.append(box)

    if kps is not None:
        # print(kps)
        kps_aug = seq_det.augment_keypoints([kps])

        for i in range(len(kps_aug[0].keypoints)):
            point = kps_aug[0].keypoints[i]
            new_keypoints.append([point.x, point.y, 1])

        new_keypoints = np.reshape(np.asarray(new_keypoints),
                                   newshape=(-1, joint_nums, 3))

        # keep ori keypoint visiable attribute
        for i in range(kps_ori.shape[0]):
            for joint in range(kps_ori.shape[1]):
                new_keypoints[i][joint][2] = kps_ori[i][joint][2]
                if kps_ori[i][joint][0] == 0 or kps_ori[i][joint][1] == 0:
                    new_keypoints[i][joint] = np.asarray([0, 0, 0])

        # if flip, change keypoint order (left <-> right)
        # ai-format: [ 0-right_shoulder, 1-right_elbow, 2-right_wrist,
        #              3-left_shoulder, 4-left_elbow, 5-left_wrist,
        #              6-right_hip, 7-right_knee, 8-right_ankle,
        #              9-left_hip, 10-left_knee, 11-left_ankle,
        #              12-head, 13-neck ]
        # coco-format: TODO add coco-foramt change index
        # change_index = [[0, 3], [1, 4], [2, 5], [6, 9], [7, 10], [8, 11]]
        change_index = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12],
                        [13, 14], [15, 16]]
        for flip in is_flip:
            if flip:
                for i in range(kps_ori.shape[0]):
                    for index in change_index:
                        right_point = copy.copy(new_keypoints[i][index[0]])
                        new_keypoints[i][index[0]] = new_keypoints[i][index[1]]
                        new_keypoints[i][index[1]] = right_point
        new_keypoints = [
            list(np.reshape(single_person_keypoints, (-1, )))
            for single_person_keypoints in new_keypoints
        ]

    # test
    # if bbs is not None:
    #     img_before = bbs.draw_on_image(img, color=(0, 255, 0), thickness=2)
    #     img_after = bbs_aug.draw_on_image(img_aug, color=(0,0,255), thickness=2)
    #     cv2.imshow('box ori', img_before)
    #     cv2.imshow('box after', img_after)
    #     cv2.waitKey(0)
    # if kps is not None:
    #     img_before = kps.draw_on_image(img, color=(0, 255, 0), size=5)
    #     img_after = kps_aug.draw_on_image(img_aug, color=(0, 0, 255), size=5)
    #     for i in range(kps_ori.shape[0]):
    #         for joint in range(kps_ori.shape[1]):
    #             point = kps_ori[i][joint]
    #             cv2.putText(img_before, str(joint), (int(point[0]), int(point[1])), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 250), 1)
    #             point = new_keypoints[i][3*joint:3*joint+3]
    #             # cv2.putText(img_after, str(point[2]), (int(point[0]), int(point[1])), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 250), 1)
    #             cv2.putText(img_after, str(joint), (int(point[0]), int(point[1])), cv2.FONT_HERSHEY_COMPLEX, 1,
    #                         (0, 0, 250), 1)
    #     cv2.imshow('kps ori', img_before)
    #     cv2.imshow('kps after', img_after)
    #     cv2.waitKey(0)

    return img_aug, new_bboxs, new_keypoints
def main():
    image = data.astronaut()
    image = ia.imresize_single_image(image, (HEIGHT, WIDTH))

    kps = []
    for y in range(NB_ROWS):
        ycoord = BB_Y1 + int(y * (BB_Y2 - BB_Y1) / (NB_COLS - 1))
        for x in range(NB_COLS):
            xcoord = BB_X1 + int(x * (BB_X2 - BB_X1) / (NB_ROWS - 1))
            kp = (xcoord, ycoord)
            kps.append(kp)
    kps = set(kps)
    kps = [ia.Keypoint(x=xcoord, y=ycoord) for (xcoord, ycoord) in kps]
    kps = ia.KeypointsOnImage(kps, shape=image.shape)

    bb = ia.BoundingBox(x1=BB_X1, x2=BB_X2, y1=BB_Y1, y2=BB_Y2)
    bbs = ia.BoundingBoxesOnImage([bb], shape=image.shape)

    pairs = []
    params = [{
        "rotate": 45
    }, {
        "translate_px": 20
    }, {
        "translate_percent": 0.1
    }, {
        "scale": 1.2
    }, {
        "scale": 0.8
    }, {
        "shear": 45
    }, {
        "rotate": 45,
        "cval": 255
    }, {
        "translate_px": 20,
        "mode": "constant"
    }, {
        "translate_px": 20,
        "mode": "edge"
    }, {
        "translate_px": 20,
        "mode": "symmetric"
    }, {
        "translate_px": 20,
        "mode": "reflect"
    }, {
        "translate_px": 20,
        "mode": "wrap"
    }, {
        "scale": 0.5,
        "order": 0
    }, {
        "scale": 0.5,
        "order": 1
    }, {
        "scale": 0.5,
        "order": 2
    }, {
        "scale": 0.5,
        "order": 3
    }, {
        "scale": 0.5,
        "order": 4
    }, {
        "scale": 0.5,
        "order": 5
    }, {
        "rotate": 45,
        "translate_px": 20,
        "scale": 1.2
    }, {
        "rotate": 45,
        "translate_px": 20,
        "scale": 0.8
    }, {
        "rotate": (-45, 45),
        "translate_px": (-20, 20),
        "scale": (0.8, 1.2),
        "order": ia.ALL,
        "mode": ia.ALL,
        "cval": ia.ALL
    }, {
        "rotate": (-45, 45),
        "translate_px": (-20, 20),
        "scale": (0.8, 1.2),
        "order": ia.ALL,
        "mode": ia.ALL,
        "cval": ia.ALL
    }, {
        "rotate": (-45, 45),
        "translate_px": (-20, 20),
        "scale": (0.8, 1.2),
        "order": ia.ALL,
        "mode": ia.ALL,
        "cval": ia.ALL
    }, {
        "rotate": (-45, 45),
        "translate_px": (-20, 20),
        "scale": (0.8, 1.2),
        "order": ia.ALL,
        "mode": ia.ALL,
        "cval": ia.ALL
    }]
    seqs_skimage = [iaa.Affine(backend="skimage", **p) for p in params]
    seqs_cv2 = [iaa.Affine(backend="auto", **p) for p in params]
    #seqs_cv2 = []
    #for p in params:
    #    seqs_cv2 = [iaa.Affine(backend="cv2", **p) for p in params]

    for seq_skimage, seq_cv2 in zip(seqs_skimage, seqs_cv2):
        #seq_skimage.localize_random_state_()
        #seq_cv2.localize_random_state_()
        #seq_cv2.copy_random_state_(seq_skimage)

        seq_skimage_det = seq_skimage.to_deterministic()
        seq_cv2_det = seq_cv2.to_deterministic()

        seq_cv2_det.copy_random_state_(seq_skimage_det)

        image_aug_skimage = seq_skimage_det.augment_image(image)
        image_aug_cv2 = seq_cv2_det.augment_image(image)
        #print(image_aug.dtype, np.min(image_aug), np.max(image_aug))
        kps_aug_skimage = seq_skimage_det.augment_keypoints([kps])[0]
        kps_aug_cv2 = seq_cv2_det.augment_keypoints([kps])[0]
        bbs_aug_skimage = seq_skimage_det.augment_bounding_boxes([bbs])[0]
        bbs_aug_cv2 = seq_cv2_det.augment_bounding_boxes([bbs])[0]

        image_before_skimage = np.copy(image)
        image_before_cv2 = np.copy(image)
        image_before_skimage = kps.draw_on_image(image_before_skimage)
        image_before_cv2 = kps.draw_on_image(image_before_cv2)
        image_before_skimage = bbs.draw_on_image(image_before_skimage)
        image_before_cv2 = bbs.draw_on_image(image_before_cv2)

        image_after_skimage = np.copy(image_aug_skimage)
        image_after_cv2 = np.copy(image_aug_cv2)
        image_after_skimage = kps_aug_skimage.draw_on_image(
            image_after_skimage)
        image_after_cv2 = kps_aug_cv2.draw_on_image(image_after_cv2)
        image_after_skimage = bbs_aug_skimage.draw_on_image(
            image_after_skimage)
        image_after_cv2 = bbs_aug_cv2.draw_on_image(image_after_cv2)

        pairs.append(
            np.hstack(
                (image_before_skimage, image_after_skimage, image_after_cv2)))

    misc.imshow(np.vstack(pairs))
    misc.imsave("affine.jpg", np.vstack(pairs))
Ejemplo n.º 13
0
    img_lst = glob(current_dir + "/*.jpg")

    for img_name in tqdm(img_lst):
        img = Image.open(img_name)
        img = np.array(img)

        results = readAnnotations(img_name.replace("jpg", "xml"))
        bndboxes = []
        for bndbox in results:
            bndboxes.append(
                ia.BoundingBox(x1=bndbox[1],
                               y1=bndbox[2],
                               x2=bndbox[3],
                               y2=bndbox[4]))

        bbs = ia.BoundingBoxesOnImage(bndboxes, shape=img.shape)

        for i in range(int(args.times)):
            seq = iaa.Sequential([
                iaa.Flipud(0.5),
                iaa.Multiply((1.2, 1.5)),
                iaa.Affine(translate_px={
                    "x": 10,
                    "y": 10
                },
                           scale=(0.8, 0.95),
                           rotate=(-10, 10))
            ])

            # 保持坐标和图像同步改变,而不是随机
            seq_det = seq.to_deterministic()
Ejemplo n.º 14
0
    def __call__(self, sample):
        image, keypoints, bboxes, is_visible, size ,name = sample['image'], sample['keypoints'], sample['bbox'], sample['is_visible'], sample['size'], sample['name']

        h, w = image.shape[:2]
        kps_coords = []
        kps = []

        for temp in keypoints:
            if temp[0] !=0 or temp[1] !=0:
                kps_coords.append((temp[0],temp[1]))

        for kp_x, kp_y in kps_coords:
            kps.append(ia.Keypoint(x=kp_x, y=kp_y))

        box_list = []
        for bbox in bboxes:
            box_list.append(ia.BoundingBox(x1 = bbox[0]-bbox[2]//2,
                                y1=bbox[1]-bbox[3]//2,
                                x2=bbox[0]+bbox[2]//2,
                                y2=bbox[1]+bbox[3]//2))

        bbs = ia.BoundingBoxesOnImage(box_list, shape=image.shape)
        kps_oi = ia.KeypointsOnImage(kps, shape=image.shape)

        if self.mode =='train':
            seq = iaa.Sequential([
                iaa.Affine(
                    rotate=(-40, 40),
                    scale=(0.35, 2.5),
                ), # random rotate by -40-40deg and scale to 35-250%, affects keypoints
                iaa.Crop(
                    px = (int(0.1*random.random()*h), int(0.1*random.random()*w), int(0.1*random.random()*h), int(0.1*random.random()*w)), 
                ),
                iaa.Resize({"height": self.output_size[0], "width": self.output_size[1]})
            ])
        else:
            seq = iaa.Sequential([
                iaa.Scale({"height": self.output_size[0], "width": self.output_size[1]})
            ])

        seq_det = seq.to_deterministic()
        image_aug = seq_det.augment_images([image])[0]
        keypoints_aug = seq_det.augment_keypoints([kps_oi])[0]
        bbs_aug = seq_det.augment_bounding_boxes([bbs])[0]

        # update keypoints and bbox
        cnt = 0
        for ck, temp in enumerate(keypoints):
            if temp[0] != 0 or temp[1] != 0:
                # ignore outside keypoints
                if keypoints_aug.keypoints[cnt].x >=0 and keypoints_aug.keypoints[cnt].x < image_aug.shape[1] and \
                    keypoints_aug.keypoints[cnt].y >=0 and keypoints_aug.keypoints[cnt].y < image_aug.shape[0]:
                    temp[0] = keypoints_aug.keypoints[cnt].x
                    temp[1] = keypoints_aug.keypoints[cnt].y
                else:
                    temp[0] = 0.0 
                    temp[1] = 0.0 
                cnt +=1 
        keypoints = np.asarray(keypoints, dtype= np.float32)
        # Delete empty keypoints
        keypoints = list(keypoints.reshape(-1,len(name_list),2))

        blacklist = []
        for idx, (temp, tempbb, tempvis) in enumerate(zip(keypoints, bbs_aug.bounding_boxes, is_visible)):

            if tempbb.x1 < 0.0:
                tempbb.x1 = 0.0
            elif tempbb.x1 > image_aug.shape[1]:
                tempbb.x1 = image_aug.shape[1]

            if tempbb.y1 < 0.0:
                tempbb.y1 = 0.0
            elif tempbb.y1 > image_aug.shape[0]:
                tempbb.y1 = image_aug.shape[0]

            if tempbb.x2 < 0.0:
                tempbb.x2 = 0.0
            elif tempbb.x2 > image_aug.shape[1]:
                tempbb.x2 = image_aug.shape[1]

            if tempbb.y2 < 0.0:
                tempbb.y2 = 0.0
            elif tempbb.y2 > image_aug.shape[0]:
                tempbb.y2 = image_aug.shape[0]

            if (np.unique(temp) == 0).all():
                blacklist.append(idx)
            
            # Update keypoint visibility
            for jdx, (yx, vis) in enumerate(zip(list(temp), tempvis)):
                if (np.unique(yx) == 0).all():
                    tempvis[jdx] = False

        for i in sorted(blacklist, reverse=True):
            del keypoints[i]
            del bbs_aug.bounding_boxes[i]
            del is_visible[i]

        if len(keypoints) == 0:
            keypoints.append(np.zeros((len(name_list),2) ))
            
        keypoints = np.asarray(keypoints, dtype= np.float32)
        
        # bbox
        new_bboxes = []
        if len(bbs_aug.bounding_boxes) > 0:
            for i in range(len(bbs_aug.bounding_boxes)):
                new_bbox = []
                temp = bbs_aug.bounding_boxes[i]
                new_bbox.append((temp.x2+temp.x1)/2)    #center x
                new_bbox.append((temp.y2+temp.y1)/2)    #center y
                new_bbox.append((temp.x2-temp.x1))      #width
                new_bbox.append((temp.y2-temp.y1))      #height
                new_bboxes.append(new_bbox)
        return {'image': image_aug, 'keypoints': keypoints, 'bbox': new_bboxes, 'is_visible':is_visible, 'size': size}
Ejemplo n.º 15
0
dir = 'images_augmentation/train/'

dir_original = 'images_augmentation/train_original/'

images, annotations = read_train_dataset(dir_original)

for idx in range(len(images)):
    image = images[idx]
    boxes = annotations[idx][0]

    ia_bounding_boxes = []
    for box in boxes:
        ia_bounding_boxes.append(
            ia.BoundingBox(x1=box[1], y1=box[2], x2=box[3], y2=box[4]))

    bbs = ia.BoundingBoxesOnImage(ia_bounding_boxes, shape=image.shape)

    seq = iaa.Sequential([
        #iaa.Multiply((1.2, 1.5)),
        iaa.Affine(translate_px={
            "x": -30,
            "y": -40
        },
                   scale=(0.6, 0.8)
                   #rotate=-30
                   )
    ])

    seq_det = seq.to_deterministic()

    image_aug = seq_det.augment_images([image])[0]
     transf = iaa.GaussianBlur(2.5)
 elif da_choice==3:
     transf=iaa.ElasticTransformation(alpha=(0.5, 1.5), sigma=0.25)
 elif da_choice==4:
     transf=iaa.ContrastNormalization((0.5, 2.0))
 elif da_choice==5:
     transf=iaa.Sharpen(alpha=(0,1.0),lightness=20.0)
 elif da_choice==6:
     transf=iaa.Emboss(alpha=(0, 1.0), strength=(0, 2.0))
 elif da_choice==7:
     transf=iaa.SaltAndPepper(0.08)
         
 if da==1:
     #Data augmentation
     imcv2=np.array(im)
     bb=ia.BoundingBoxesOnImage([ia.BoundingBox(x1=x_min, y1=y_min, x2=x_max, y2=y_max)],shape=imcv2.shape)
     transf_det=transf.to_deterministic()
     bbs_aug=transf_det.augment_bounding_boxes([bb])[0]
     bbs_aug=bbs_aug.bounding_boxes[0]
     
     x_min=bbs_aug.x1
     x_max=bbs_aug.x2
     y_min=bbs_aug.y1
     y_max=bbs_aug.y2
     
     print(x_min)
     print(x_max)
     print(y_min)
     print(y_max)
     
 xmn.text=str(np.float64((x_min)/1))  #/widthc
def image_augment(seq, data_dir, out_dir, out_label_dir, annotation_xml, name,
                  classes):
    boxes_img_aug_list = []
    imgaug_files = []
    new_bndbox_list = []

    bndbox = read_xml_annotation(annotation_xml, name)
    for epoch in range(FLAGS.imgaugloop):

        # Keep the coordinates and the image changing synchronously, not randomly
        seq_det = seq.to_deterministic()

        # read image
        img = Image.open(
            os.path.join(data_dir, "JPEGImages", name[:-4] + ".jpg"))
        img = np.array(img)

        # change bndbox
        for i in range(len(bndbox)):
            bbs = ia.BoundingBoxesOnImage(
                [
                    ia.BoundingBox(
                        x1=bndbox[i][0],
                        y1=bndbox[i][1],
                        x2=bndbox[i][2],
                        y2=bndbox[i][3],
                    ),
                ],
                shape=img.shape,
            )

            bbs_aug = seq_det.augment_bounding_boxes([bbs])[0]
            boxes_img_aug_list.append(bbs_aug)

            # new_bndbox_list:[[x1,y1,x2,y2],...[],[]]
            new_bndbox_list.append([
                int(bbs_aug.bounding_boxes[0].x1),
                int(bbs_aug.bounding_boxes[0].y1),
                int(bbs_aug.bounding_boxes[0].x2),
                int(bbs_aug.bounding_boxes[0].y2),
            ])

        # save the augment image
        image_aug = seq_det.augment_images([img])[0]
        auged_name = str(name[:-4]) + "_aug_" + str(epoch) + ".jpg"

        path = os.path.join(data_dir, "JPEGImages", auged_name)
        image_auged = bbs.draw_on_image(image_aug, thickness=0)
        image_saved = Image.fromarray(image_auged)
        image_saved.save(path)

        # draw bbox
        if FLAGS.augcheck:
            draw = ImageDraw.Draw(image_saved)
            for rect in new_bndbox_list:
                draw.rectangle(rect, outline=(0, 255, 0), width=2)

            val_path = os.path.join(
                data_dir,
                "JPEGImages",
                str(name[:-4]) + "_aug_" + str(epoch) + "_val.jpg",
            )
            image_saved.save(val_path)

        # save new XML
        auged_xml = change_xml_list_annotation(
            annotation_xml,
            name[:-4],
            new_bndbox_list,
            os.path.join(data_dir, "Annotations"),
            epoch,
        )
        # print(auged_name)

        convert_annotation(data_dir, out_dir, out_label_dir, auged_xml,
                           auged_name, classes)

        # append to imgaug_files
        imgaug_files.append(
            os.path.relpath(os.path.join(out_label_dir, auged_name)))

        new_bndbox_list = []

    return imgaug_files
def doAugmentation():
    # argparse
    parser = ArgumentParser()
    parser.add_argument("conf", help="the path of augmenter configurations")
    arguments = parser.parse_args()
    configurationFile = os.path.abspath('.') + '/' + arguments.conf
    # for debugging
    # configurationFile = os.path.abspath('.') + '\\AugmenterConfigurations.xml'

    # parsing configuration file
    configurationTree = ET.parse(configurationFile)
    configurationRoot = configurationTree.getroot()

    # the directory of images to augment
    imageSourceDirectory = configurationRoot.findall(
        'imageSourceDirectory')[0].text
    # the directory of original xml
    xmlSourceDirectory = configurationRoot.findall(
        'xmlSourceDirectory')[0].text
    # the directory to save augmented images
    imageDestinationDirectory = configurationRoot.findall(
        'imageDestinationDirectory')[0].text
    # the directory to save augmented xml files
    xmlDestinationDirectory = configurationRoot.findall(
        'xmlDestinationDirectory')[0].text
    # mkdir if destination directory doesn't exist
    if os.path.isdir(imageDestinationDirectory) is False:
        os.mkdir(imageDestinationDirectory)
    '''deprecated
    # augmenters. Visit https://github.com/aleju/imgaug to find more augmenters.
    # sequential augmentation. Applies all the augmenters(sequentially) to an image, generates an image that contains all the augmenters.
    # seq = iaa.Sequential([
    #     iaa.SigmoidContrast(cutoff=0.6, gain=7)])  # modify "iaa.Add(-45), iaa.Crop(precent=0.2), iaa.GaussianBlur(2)" to get the augmentation type you want
    # seperate augmentation. Applies one augmenter to an image and generated augmented image.
    deprecated'''

    # load all of the augmenters in configuration file
    augmenters = configurationRoot.findall('augmenter')

    # file type
    # be aware of the file type, ex: jpg vs. JPG or jpg vs. jpeg, they are different!
    fileExtension = configurationRoot.findall('fileExtension')[0].text

    # getting addresses of images to augment
    imageAddresses = []
    totalImageCount = 0
    finishPartCount = 0
    for f in os.listdir(imageSourceDirectory):
        if (f.__contains__(fileExtension)):
            imageAddresses.append(imageSourceDirectory + '/' + f)
            totalImageCount += 1

    # counting the number of augmenters actually using
    augmenterCount = 0
    for a in augmenters:
        if a[1].text == 'Yes':
            augmenterCount += 1

    # data for showing augmented samples
    originalImageToShow = None
    augmentedImageToShow = []
    titlesToShow = []

    # augmentation
    augmenterHistory = [0] * len(augmenters)
    print("starting augmentation")
    for a in augmenters:
        if a[1].text == 'Yes':  # checking whether the user want to use this augmenter
            print("part: " + str(finishPartCount + 1) + "/" +
                  str(augmenterCount))

            # generate imgaug augmenter
            seq = generateAugmenter(augmenters, a[0].text, augmenterHistory)

            finishImageCount = 0
            for address in imageAddresses:
                boundingBoxes = []

                # getting target image and xml file
                image = imageio.imread(address)
                augmentedTree = ET.parse(
                    address.replace(imageSourceDirectory,
                                    xmlSourceDirectory).replace(
                                        fileExtension, '.xml'))
                augmentedRoot = augmentedTree.getroot()

                # getting bounding boxes
                for obj in augmentedRoot.iter('object'):
                    boundingBoxes.append(
                        ia.BoundingBox(x1=int(obj[4][0].text),
                                       y1=int(obj[4][1].text),
                                       x2=int(obj[4][2].text),
                                       y2=int(obj[4][3].text),
                                       label=obj[0].text))
                BBS = ia.BoundingBoxesOnImage(boundingBoxes, shape=image.shape)

                # augmentation
                augmentedImage, augmentedBBS = seq(image=image,
                                                   bounding_boxes=BBS)

                # xml handling
                for fileName in augmentedRoot.iter('filename'):
                    newNameAttributes = '_'
                    if a[0].text == 'Crop':
                        newNameAttributes = newNameAttributes + a[0].text
                        if a[2][0].text == '0' and a[2][3].text == '0':
                            newNameAttributes = newNameAttributes + '=' + 'topLeft'
                        elif a[2][0].text == '0' and a[2][1].text == '0':
                            newNameAttributes = newNameAttributes + '=' + 'topRight'
                        elif a[2][2].text == '0' and a[2][1].text == '0':
                            newNameAttributes = newNameAttributes + '=' + 'bottomRight'
                        elif a[2][2].text == '0' and a[2][3].text == '0':
                            newNameAttributes = newNameAttributes + '=' + 'bottomLeft'
                    elif a[0].text == 'Flipud' or a[0].text == 'Fliplr':
                        newNameAttributes = newNameAttributes + a[0].text
                    elif a[0].text == 'Rot':
                        newNameAttributes = newNameAttributes + a[
                            0].text + '=' + a[2][0].text
                    elif a[0].text == 'Add':
                        newNameAttributes = newNameAttributes + a[
                            0].text + '=' + a[2][0].text
                    else:
                        newNameAttributes = newNameAttributes + a[0].text
                        for args in a[2]:
                            newNameAttributes = newNameAttributes + '_' + args.tag + '=' + args.text.replace(
                                '.', 'p')
                    newName = str(
                        fileName.text.replace(
                            fileExtension, newNameAttributes)) + fileExtension
                    fileName.text = newName
                for folder in augmentedRoot.iter('folder'):
                    newFolder = str(a[0].text)
                    folder.text = newFolder
                for path in augmentedRoot.iter('path'):
                    newPath = str(imageDestinationDirectory
                                  ) + '/' + a[0].text + '/' + newName
                    path.text = newPath
                for size in augmentedRoot.iter('size'):
                    size[0].text = str(augmentedImage.shape[1])
                    size[1].text = str(augmentedImage.shape[0])
                    size[2].text = str(augmentedImage.shape[2])
                i = 0
                for obj in augmentedRoot.findall('object'):
                    if augmentedBBS.bounding_boxes[i].is_fully_within_image(
                            augmentedImage.shape):
                        obj[4][0].text = str(augmentedBBS.bounding_boxes[i].x1)
                        obj[4][1].text = str(augmentedBBS.bounding_boxes[i].y1)
                        obj[4][2].text = str(augmentedBBS.bounding_boxes[i].x2)
                        obj[4][3].text = str(augmentedBBS.bounding_boxes[i].y2)
                    elif augmentedBBS.bounding_boxes[i].is_partly_within_image(
                            augmentedImage.shape):
                        augmentedBBS.bounding_boxes[i].clip_out_of_image(
                            augmentedImage.shape)
                        obj[4][0].text = str(augmentedBBS.bounding_boxes[i].x1)
                        obj[4][1].text = str(augmentedBBS.bounding_boxes[i].y1)
                        obj[4][2].text = str(augmentedBBS.bounding_boxes[i].x2)
                        obj[4][3].text = str(augmentedBBS.bounding_boxes[i].y2)
                    else:
                        augmentedRoot.remove(obj)
                    i += 1

                # draw bounding boxes on image (uncomment to enable)
                # augmentedImage = augmentedBBS.draw_on_image(
                #     augmentedImage, size=5, color=[0, 0, 255])

                # saving new xml file
                # mkdir if destination directory doesn't exist
                if os.path.isdir(newPath.replace(newName, '')) is False:
                    if os.path.isdir(imageDestinationDirectory) is False:
                        os.mkdir(imageDestinationDirectory)
                    os.mkdir(newPath.replace(newName, ''))
                    # os.mkdir(newPath.replace(newName, '/xmlFile'))
                # augmentedTree.write(newPath.replace(newName, '/xmlFile/' + newName).replace(fileExtension, '.xml'))  # for saving jpg and xml into seperate directories
                if os.path.isdir(
                        newPath.replace(imageDestinationDirectory,
                                        xmlDestinationDirectory).replace(
                                            newName, '')) is False:
                    if os.path.isdir(xmlDestinationDirectory) is False:
                        os.mkdir(xmlDestinationDirectory)
                    os.mkdir(
                        newPath.replace(imageDestinationDirectory,
                                        xmlDestinationDirectory).replace(
                                            newName, ''))
                augmentedTree.write(
                    newPath.replace(imageDestinationDirectory,
                                    xmlDestinationDirectory).replace(
                                        fileExtension, '.xml'))

                # saving new image
                imageio.imsave(newPath, augmentedImage)

                # collecting samples to show
                if configurationRoot.findall(
                        'showAugmentedSamples')[0].text == 'Yes':
                    if finishPartCount is 0 and finishImageCount is 0:
                        originalImageToShow = image
                    if finishImageCount is 0:  # sample images to show later
                        augmentedImageToShow.append(augmentedImage)
                        titlesToShow.append(newNameAttributes[1:])

                finishImageCount += 1
                print(
                    str(finishImageCount) + "/" + str(totalImageCount) +
                    ", saved to: " + newPath)
            finishPartCount += 1
            print('')

    # showing augmented samples
    # checking whether the user want to show augmented samples
    if configurationRoot.findall('showAugmentedSamples')[0].text == 'Yes':
        totalSampleCount = math.ceil(augmenterCount / 3)
        for i in range(0, augmenterCount, 3):
            print('showing sample: ' + str(int((i / 3) + 1)) + '/' +
                  str(totalSampleCount))
            plt.figure(figsize=(12.8, 7.2))
            plt.axis('off')
            if augmenterCount - i is 1:
                plt.subplot(1, 2, 1)
            elif augmenterCount - i is 2:
                plt.subplot(1, 3, 1)
            else:
                plt.subplot(2, 2, 1)
            plt.imshow(originalImageToShow)
            plt.title('Original')
            j = 0
            while j < 3 and i + j < len(augmentedImageToShow):
                if augmenterCount - i is 1:
                    plt.subplot(1, 2, j + 2)
                elif augmenterCount - i is 2:
                    plt.subplot(1, 3, j + 2)
                else:
                    plt.subplot(2, 2, j + 2)
                plt.imshow(augmentedImageToShow[i + j])
                plt.title(titlesToShow[i + j])
                plt.axis('off')
                j += 1
            plt.show()

    print("Augmentation finished.")
Ejemplo n.º 19
0
 def bbsoi_flipped(self):
     # note that x1 and x2 were inverted (otherwise would be x1>x2)
     bbs = [ia.BoundingBox(x1=3 - 2, y1=1, x2=3 - 0, y2=3)]
     return [ia.BoundingBoxesOnImage(bbs, shape=self.image.shape)]
def getInfo(f, d):
    filename_split = os.path.splitext(f)
    filename_zero, fileext = filename_split
    basename = os.path.basename(filename_zero)
    print("file: ", basename)
    tree = ET.ElementTree(file=f)
    root = tree.getroot()
    def chunks(l, n):
        for i in range(0, len(l), n):
            yield l[i:i+n]
    points_list = []
    for name in root.findall(".//bndbox/"):
        points = [name.text]
        #print("points: ", points)
        points_list.append(points)
    flat_points_list = [int(item) for sublist in points_list for item in sublist]
    print("points_list: ", flat_points_list)
    img = args.imPath+basename+'.jpg'
    img_aug = augment_img(img, d)
    img_open = np.array(Image.open(img))
    frame_box = ia.BoundingBoxesOnImage([
        ia.BoundingBox(x1=int(1), y1=int(1), x2=int(img_open.shape[1]-1), y2=int(img_open.shape[0]-1))], shape=img_open.shape)
    frame_box = ia.BoundingBoxesOnImage([
        ia.BoundingBox(x1=int(1), y1=int(1), x2=int(767), y2=int(767))], shape=img_open.shape)
    frame_box = ia.KeypointsOnImage([
        ia.Keypoint(x=0, y=int(img_open.shape[0])),
        ia.Keypoint(x=int(img_open.shape[1]), y=int(img_open.shape[0])),
        ia.Keypoint(x=int(img_open.shape[1]), y=0),
        ia.Keypoint(x=0, y=0)], shape=img_open.shape)
    print("frame_box: ", frame_box)
    frame_box_aug = augment_keypoints_frame(frame_box, img_open, d)
    print("frame_box_aug: ", frame_box_aug)
    frame_box_aug_flat = [int(item) for sublist in frame_box_aug for item in sublist]
    print("frame_box_aug_flat: ", frame_box_aug_flat)
    frame_box_aug_cv, frame_box_aug_cv_rect = back_forward_convert(frame_box_aug_flat)
    print("frame_box_aug_cv: ", frame_box_aug_cv)
    img_crop = crop_minAreaRect(img_aug, frame_box_aug_cv_rect)
    misc.imsave(args.imPath+basename+'_rotate'+str(d)+'_cropFrame'+'.jpg', img_crop)
    pairs = list(zip(*[iter(flat_points_list)] * 2))
    chunked = list(chunks(pairs, 4))
    print("chunked: ", chunked)
    print("pairs: ", pairs)
    #img_aug, chunked_points_aug_list = augment(f, chunked)
    ordered_points_list = []
    bbs_aug_list = []
    for chunk in chunked:
        flat_points_list_chunk = [item for sublist in chunk for item in sublist]
        #flat_points_aug_list_chunk, bbs_aug = augment_keypoints(flat_points_list_chunk, img_aug, d)
        flat_points_aug_list_chunk = augment_keypoints(flat_points_list_chunk, img_aug, d)
        #bbs_aug_list.append(bbs_aug)
        print("flat_points_aug_list_chunk: ", flat_points_aug_list_chunk)
        ordered_points_list_chunk = order_points(flat_points_aug_list_chunk)
        ordered_points_list.append(ordered_points_list_chunk)
    #bbs_aug = bbs_aug_list.on(img_aug)
    #img_bbs_aug = bbs_aug.draw_on_image(img_aug, thickness=2)
    #misc.imsave(args.imPath+basename+'_rotate'+str(d)+'_crop75_bbsRescaled'+'.jpg', img_bbs_aug)
    img_shape = img_aug.shape
    print("image shape: ", img_shape)
    filename = basename
    print("original points list: ", chunked)
    print("ordered_points_list: ", ordered_points_list)
    filename_aug = filename+'_rotate'+str(d)

    #filename_aug = filename    

    xSorted = sorted(pairs,key=itemgetter(0))
    xSorted_extract = [i[0] for i in xSorted]
    xmin = int(min(xSorted_extract))
    xmax = int(max(xSorted_extract))
    ySorted = sorted(pairs,key=itemgetter(1))
    ySorted_extract = [i[1] for i in ySorted]
    ymin = int(min(ySorted_extract))
    ymax = int(min(ySorted_extract))

    img_xmin = 0
    img_xmax = img_shape[0]
    img_ymin = 0
    img_ymax = img_shape[1]

    #print("xmin, xmax, ymin, ymax: ", xmin, xmax, ymin, ymax)
    #print("img_xmin, img_xmax, img_ymin, img_ymax: ", img_xmin, img_xmax, img_ymin, img_ymax)

    if xmin < img_xmin:
        out_of_bounds.append(filename_aug)        
        print("box off frame for file: ", filename_aug)
    elif xmax > img_xmax:
        out_of_bounds.append(filename_aug)
        print("box off frame for file: ", filename_aug)
    elif ymin < img_ymin:
        out_of_bounds.append(filename_aug)
        print("box off frame for file: ", filename_aug)
    elif ymax > img_ymax:
        out_of_bounds.append(filename_aug)
        print("box off frame for file: ", filename_aug)

    return filename_aug, ordered_points_list, img_shape
Ejemplo n.º 21
0
 def bbsoi_flipped(self):
     # note that y1 and y2 were inverted (otherwise would be y1>y2)
     bbs = [ia.BoundingBox(x1=0, y1=3 - 3, x2=2, y2=3 - 1)]
     return [ia.BoundingBoxesOnImage(bbs, shape=self.image.shape)]
Ejemplo n.º 22
0
    filename = annotations[idx]
    height, width, channel = hwc[idx]
    label = []

    for box in boxes:
        label.append(box[0])
        bbox_center_x = box[1] * width
        bbox_center_y = box[2]* height
        bbox_width = box[3] * width
        bbox_height = box[4] * height
        bbox_top_left_x = bbox_center_x - bbox_width/2
        bbox_top_left_y = bbox_center_y - bbox_height/2
        bbox_bottom_right_x = bbox_center_x + bbox_width/2
        bbox_bottom_right_y = bbox_center_y + bbox_height/2
        bbox.append(ia.BoundingBox(bbox_top_left_x, bbox_top_left_y, bbox_bottom_right_x, bbox_bottom_right_y))
    bbs = ia.BoundingBoxesOnImage(bbox, shape = image.shape)
    # # 만약 어떻게 바운딩박스되는지 보고싶으면
    # ia.imshow(bbs.draw_on_image(image, size=2))

    seq1 = iaa.Sequential([
        iaa.Fliplr(0.5),  # horizontal flips
        iaa.Crop(percent=(0, 0.1)),  # random crops
        # Small gaussian blur with random sigma between 0 and 0.5.
        # But we only blur about 50% of all images.
        iaa.Sometimes(
            0.5,
            iaa.GaussianBlur(sigma=(0, 0.5)))
        ])
    # Strengthen or weaken the contrast in each image.
    seq2 = iaa.LinearContrast((0.75, 1.5))
    # Add gaussian noise.
Ejemplo n.º 23
0
def process_pascal_voc_aug(job):
    kwargs = {'Bucket': job.bucket, 'Prefix': job.class_folder}

    train_csv_file = job.tempdir + '/train.csv'
    test_csv_file = job.tempdir + '/test.csv'
    if not os.path.isfile(train_csv_file):
        print("creating training csv file")
        fout = open(train_csv_file, "w")
        fout.write('filename,width,height,class,xmin,ymin,xmax,ymax\n')
        fout.close()
    if not os.path.isfile(test_csv_file):
        print("creating test csv file")
        fout = open(test_csv_file, "w")
        fout.write('filename,width,height,class,xmin,ymin,xmax,ymax\n')
        fout.close()
    while True:
        resp = job.s3.list_objects_v2(**kwargs)

        try:
            for obj in resp['Contents']:
                _key = obj['Key']
                _obj = job.s3.get_object(Bucket=job.bucket, Key=_key)
                e = ET.fromstring(_obj['Body'].read().decode('utf-8'))
                fname = os.path.basename(e.find('./filename').text)
                folder = job.project['id'] + '/train'
                bbox = []
                params = {'Bucket': job.bucket, 'Key': folder + '/' + fname}
                url = job.s3.generate_presigned_url(ClientMethod='get_object',
                                                    Params=params)
                url_response = http.request('GET', url)
                img_array = np.array(bytearray(url_response.data),
                                     dtype=np.uint8)
                im = cv2.imdecode(img_array, -1)
                for node in e.iter('object'):
                    xmin = int(node.find('./bndbox/xmin').text)
                    ymin = int(node.find('./bndbox/ymin').text)
                    xmax = int(node.find('./bndbox/xmax').text)
                    ymax = int(node.find('./bndbox/ymax').text)
                    name = node.find('./name').text
                    if name not in job.labelmap_dict:
                        job.labelmap_dict[name] = len(job.labelmap_dict) + 1
                    bbox.append(
                        ia.BoundingBox(x1=xmin,
                                       y1=ymin,
                                       x2=xmax,
                                       y2=ymax,
                                       label=node.find('./name').text))
                bbs = ia.BoundingBoxesOnImage(bbox, shape=im.shape)

                fout = open(train_csv_file, "a")
                with concurrent.futures.ThreadPoolExecutor(
                        max_workers=multiprocessing.cpu_count()) as executor:
                    future_img = {
                        executor.submit(create_image, im, job, bbs, fout): i
                        for i in range(job.train_samples)
                    }
                    for future in concurrent.futures.as_completed(future_img):
                        img = future_img[future]
                        try:
                            data = future.result()
                        except Exception as exc:
                            print('%r generated an exception: %s' %
                                  (str(i), exc))

                fout.close()
                fout = open(test_csv_file, "a")
                with concurrent.futures.ThreadPoolExecutor(
                        max_workers=multiprocessing.cpu_count()) as executor:
                    future_img = {
                        executor.submit(create_image, im, job, bbs, fout): i
                        for i in range(job.test_samples)
                    }
                    for future in concurrent.futures.as_completed(future_img):
                        img = future_img[future]
                        try:
                            data = future.result()
                        except Exception as exc:
                            print('generated an exception: %s' % (exc))

                fout.close()
                if hasattr(job, 'jb'):
                    job.jb.meta['current_step_processed'] += 1
                    job.jb.save_meta()

        except KeyError:
            break
        try:
            kwargs['ContinuationToken'] = resp['NextContinuationToken']
        except KeyError:
            break
    job.s3.upload_file(
        train_csv_file, job.bucket,
        'corpus/' + job.name + "/" + os.path.basename(train_csv_file))
    job.s3.upload_file(
        test_csv_file, job.bucket,
        'corpus/' + job.name + "/" + os.path.basename(test_csv_file))
    job.train_csv_file = 'corpus/' + job.name + \
        "/" + os.path.basename(train_csv_file)
    job.test_csv_file = 'corpus/' + job.name + \
        "/" + os.path.basename(test_csv_file)
Ejemplo n.º 24
0
def img_and_key_point_augmentation(augmentation, img, bbox, key_points):
    """
    Augment image and key points, bounding boxes !!
    :param augmentation: augmentation settings
    :param img: Only one image is needed. Not batch images
    :param bbox: [[x1,y1,x2,y2],[x1,y1,x2,y2]...]
    :param key_points: [[[x1,y1,x2,y2....],[x1,y1,x2,y2....]...]]
    :return: Returns augment image and key points, bbox
    """

    # img_copy = img.copy()
    image_shape = img.shape
    h, w = image_shape[0:2]

    # Convert the stochastic sequence of augmenters to a deterministic one.
    # The deterministic sequence will always apply the exactly same effects to the images.
    det = augmentation.to_deterministic()

    ia_bbox = list()
    for bounding_box in bbox:
        x1, y1, x2, y2 = bounding_box
        ia_bbox.append(ia.BoundingBox(x1=x1, y1=y1, x2=x2, y2=y2))

    bbs = ia.BoundingBoxesOnImage(ia_bbox, shape=image_shape)
    bbs_aug = det.augment_bounding_boxes([bbs])[0]
    # img = bbs_aug.draw_on_image(img)

    after_bbox = list()
    for bounding_box in bbs_aug.bounding_boxes:
        bbox_list = [
            bounding_box.x1_int, bounding_box.y1_int, bounding_box.x2_int,
            bounding_box.y2_int
        ]

        if bbox_list[0] >= w: bbox_list[0] = w - 1
        if bbox_list[1] >= h: bbox_list[1] = h - 1
        if bbox_list[2] >= w: bbox_list[2] = w - 1
        if bbox_list[3] >= h: bbox_list[3] = h - 1

        if bbox_list[0] == bbox_list[2] or bbox_list[1] == bbox_list[3]:
            return img_and_key_point_augmentation(augmentation, img, bbox,
                                                  key_points)

        bbox_list = list(map(lambda x: max(x, 0), bbox_list))
        after_bbox.append(bbox_list)

    after_key_points = list()
    for key_point_list in key_points:
        after_key_point_list = list()
        for key_point in key_point_list:
            xy_points = list()
            for i, x in enumerate(key_point[::2]):
                y = key_point[(i * 2) + 1]
                xy_points.append(ia.Keypoint(x=x, y=y))

            keypoints_on_image = det.augment_keypoints(
                [ia.KeypointsOnImage(xy_points, shape=image_shape)])
            # img = keypoints_on_image[0].draw_on_image(img)

            xy_points = list()
            for key_point in keypoints_on_image[0].keypoints:
                kp = [key_point.x_int, key_point.y_int]
                if 0 > min(kp) or w <= max(kp[::2]) or h <= max(kp[1::2]):
                    # print(kp)
                    return img_and_key_point_augmentation(
                        augmentation, img, bbox, key_points)
                xy_points.extend(kp)

            after_key_point_list.append(xy_points)

        after_key_points.append(after_key_point_list)

    img_aug = det.augment_image(img)
    assert img_aug.shape == image_shape, "Augmentation shouldn't change image size"

    return img_aug, after_bbox, after_key_points
Ejemplo n.º 25
0
def main():
    parser = argparse.ArgumentParser(description="Check augmenters visually.")
    parser.add_argument(
        "--only",
        default=None,
        help=
        "If this is set, then only the results of an augmenter with this name will be shown. "
        "Optionally, comma-separated list.",
        required=False)
    args = parser.parse_args()

    images = [
        ia.quokka_square(size=(128, 128)),
        ia.imresize_single_image(data.astronaut(), (128, 128))
    ]

    keypoints = [
        ia.KeypointsOnImage([
            ia.Keypoint(x=50, y=40, vis=None, label=None),
            ia.Keypoint(x=70, y=38, vis=None, label=None),
            ia.Keypoint(x=62, y=52, vis=None, label=None)
        ],
                            shape=images[0].shape),
        ia.KeypointsOnImage([
            ia.Keypoint(x=55, y=32, vis=None, label=None),
            ia.Keypoint(x=42, y=95, vis=None, label=None),
            ia.Keypoint(x=75, y=89, vis=None, label=None)
        ],
                            shape=images[1].shape)
    ]

    bounding_boxes = [
        ia.BoundingBoxesOnImage([
            ia.BoundingBox(x1=10, y1=10, x2=20, y2=20),
            ia.BoundingBox(x1=40, y1=50, x2=70, y2=60)
        ],
                                shape=images[0].shape),
        ia.BoundingBoxesOnImage([
            ia.BoundingBox(x1=10, y1=10, x2=20, y2=20),
            ia.BoundingBox(x1=40, y1=50, x2=70, y2=60)
        ],
                                shape=images[1].shape)
    ]

    augmenters = [
        iaa.Sequential([
            iaa.CoarseDropout(p=0.5, size_percent=0.05),
            iaa.AdditiveGaussianNoise(scale=0.1 * 255),
            iaa.Crop(percent=0.1)
        ],
                       name="Sequential"),
        iaa.SomeOf(2,
                   children=[
                       iaa.CoarseDropout(p=0.5, size_percent=0.05),
                       iaa.AdditiveGaussianNoise(scale=0.1 * 255),
                       iaa.Crop(percent=0.1)
                   ],
                   name="SomeOf"),
        iaa.OneOf(children=[
            iaa.CoarseDropout(p=0.5, size_percent=0.05),
            iaa.AdditiveGaussianNoise(scale=0.1 * 255),
            iaa.Crop(percent=0.1)
        ],
                  name="OneOf"),
        iaa.Sometimes(0.5,
                      iaa.AdditiveGaussianNoise(scale=0.1 * 255),
                      name="Sometimes"),
        iaa.WithColorspace("HSV",
                           children=[iaa.Add(20)],
                           name="WithColorspace"),
        iaa.WithChannels([0], children=[iaa.Add(20)], name="WithChannels"),
        iaa.AddToHueAndSaturation((-20, 20),
                                  per_channel=True,
                                  name="AddToHueAndSaturation"),
        iaa.Noop(name="Noop"),
        iaa.Resize({
            "width": 64,
            "height": 64
        }, name="Resize"),
        iaa.CropAndPad(px=(-8, 8), name="CropAndPad-px"),
        iaa.Pad(px=(0, 8), name="Pad-px"),
        iaa.Crop(px=(0, 8), name="Crop-px"),
        iaa.Crop(percent=(0, 0.1), name="Crop-percent"),
        iaa.Fliplr(0.5, name="Fliplr"),
        iaa.Flipud(0.5, name="Flipud"),
        iaa.Superpixels(p_replace=0.75, n_segments=50, name="Superpixels"),
        iaa.Grayscale(0.5, name="Grayscale0.5"),
        iaa.Grayscale(1.0, name="Grayscale1.0"),
        iaa.GaussianBlur((0, 3.0), name="GaussianBlur"),
        iaa.AverageBlur(k=(3, 11), name="AverageBlur"),
        iaa.MedianBlur(k=(3, 11), name="MedianBlur"),
        iaa.BilateralBlur(d=10, name="BilateralBlur"),
        iaa.Sharpen(alpha=(0.1, 1.0), lightness=(0, 2.0), name="Sharpen"),
        iaa.Emboss(alpha=(0.1, 1.0), strength=(0, 2.0), name="Emboss"),
        iaa.EdgeDetect(alpha=(0.1, 1.0), name="EdgeDetect"),
        iaa.DirectedEdgeDetect(alpha=(0.1, 1.0),
                               direction=(0, 1.0),
                               name="DirectedEdgeDetect"),
        iaa.Add((-50, 50), name="Add"),
        iaa.Add((-50, 50), per_channel=True, name="AddPerChannel"),
        iaa.AddElementwise((-50, 50), name="AddElementwise"),
        iaa.AdditiveGaussianNoise(loc=0,
                                  scale=(0.0, 0.1 * 255),
                                  name="AdditiveGaussianNoise"),
        iaa.Multiply((0.5, 1.5), name="Multiply"),
        iaa.Multiply((0.5, 1.5), per_channel=True, name="MultiplyPerChannel"),
        iaa.MultiplyElementwise((0.5, 1.5), name="MultiplyElementwise"),
        iaa.Dropout((0.0, 0.1), name="Dropout"),
        iaa.CoarseDropout(p=0.05,
                          size_percent=(0.05, 0.5),
                          name="CoarseDropout"),
        iaa.Invert(p=0.5, name="Invert"),
        iaa.Invert(p=0.5, per_channel=True, name="InvertPerChannel"),
        iaa.ContrastNormalization(alpha=(0.5, 2.0),
                                  name="ContrastNormalization"),
        iaa.SaltAndPepper(p=0.05, name="SaltAndPepper"),
        iaa.Salt(p=0.05, name="Salt"),
        iaa.Pepper(p=0.05, name="Pepper"),
        iaa.CoarseSaltAndPepper(p=0.05,
                                size_percent=(0.01, 0.1),
                                name="CoarseSaltAndPepper"),
        iaa.CoarseSalt(p=0.05, size_percent=(0.01, 0.1), name="CoarseSalt"),
        iaa.CoarsePepper(p=0.05, size_percent=(0.01, 0.1),
                         name="CoarsePepper"),
        iaa.Affine(scale={
            "x": (0.8, 1.2),
            "y": (0.8, 1.2)
        },
                   translate_px={
                       "x": (-16, 16),
                       "y": (-16, 16)
                   },
                   rotate=(-45, 45),
                   shear=(-16, 16),
                   order=ia.ALL,
                   cval=(0, 255),
                   mode=ia.ALL,
                   name="Affine"),
        iaa.PiecewiseAffine(scale=0.03,
                            nb_rows=(2, 6),
                            nb_cols=(2, 6),
                            name="PiecewiseAffine"),
        iaa.PerspectiveTransform(scale=0.1, name="PerspectiveTransform"),
        iaa.ElasticTransformation(alpha=(0.5, 8.0),
                                  sigma=1.0,
                                  name="ElasticTransformation"),
        iaa.Alpha(factor=(0.0, 1.0),
                  first=iaa.Add(100),
                  second=iaa.Dropout(0.5),
                  per_channel=False,
                  name="Alpha"),
        iaa.Alpha(factor=(0.0, 1.0),
                  first=iaa.Add(100),
                  second=iaa.Dropout(0.5),
                  per_channel=True,
                  name="AlphaPerChannel"),
        iaa.Alpha(factor=(0.0, 1.0),
                  first=iaa.Affine(rotate=(-45, 45)),
                  per_channel=True,
                  name="AlphaAffine"),
        iaa.AlphaElementwise(factor=(0.0, 1.0),
                             first=iaa.Add(50),
                             second=iaa.ContrastNormalization(2.0),
                             per_channel=False,
                             name="AlphaElementwise"),
        iaa.AlphaElementwise(factor=(0.0, 1.0),
                             first=iaa.Add(50),
                             second=iaa.ContrastNormalization(2.0),
                             per_channel=True,
                             name="AlphaElementwisePerChannel"),
        iaa.AlphaElementwise(factor=(0.0, 1.0),
                             first=iaa.Affine(rotate=(-45, 45)),
                             per_channel=True,
                             name="AlphaElementwiseAffine"),
        iaa.SimplexNoiseAlpha(first=iaa.EdgeDetect(1.0),
                              per_channel=False,
                              name="SimplexNoiseAlpha"),
        iaa.FrequencyNoiseAlpha(first=iaa.EdgeDetect(1.0),
                                per_channel=False,
                                name="FrequencyNoiseAlpha")
    ]

    augmenters.append(
        iaa.Sequential([iaa.Sometimes(0.2, aug.copy()) for aug in augmenters],
                       name="Sequential"))
    augmenters.append(
        iaa.Sometimes(0.5, [aug.copy() for aug in augmenters],
                      name="Sometimes"))

    for augmenter in augmenters:
        if args.only is None or augmenter.name in [
                v.strip() for v in args.only.split(",")
        ]:
            print("Augmenter: %s" % (augmenter.name, ))
            grid = []
            for image, kps, bbs in zip(images, keypoints, bounding_boxes):
                aug_det = augmenter.to_deterministic()
                imgs_aug = aug_det.augment_images(
                    np.tile(image[np.newaxis, ...], (16, 1, 1, 1)))
                kps_aug = aug_det.augment_keypoints([kps] * 16)
                bbs_aug = aug_det.augment_bounding_boxes([bbs] * 16)
                imgs_aug_drawn = [
                    kps_aug_one.draw_on_image(img_aug)
                    for img_aug, kps_aug_one in zip(imgs_aug, kps_aug)
                ]
                imgs_aug_drawn = [
                    bbs_aug_one.draw_on_image(img_aug)
                    for img_aug, bbs_aug_one in zip(imgs_aug_drawn, bbs_aug)
                ]
                grid.append(np.hstack(imgs_aug_drawn))
            ia.imshow(np.vstack(grid))
Ejemplo n.º 26
0
    ymax.text = str(new_ymax)
    tree.write(os.path.join(root, str(image_id) + "_aug" + '.xml'))


if __name__ == "__main__":
    # cmd = os.getcwd()
    cmd = "/Users/wangbenkang/Desktop/500/Example"
    image_id = "000010"
    img = Image.open(os.path.join(cmd, str(image_id) + '.jpg'))
    img = np.array(img)

    bndbox = read_xml_annotation(cmd, str(image_id) + '.xml')

    bbs = ia.BoundingBoxesOnImage(
        [
            ia.BoundingBox(
                x1=bndbox[0], y1=bndbox[1], x2=bndbox[2], y2=bndbox[3])  #改这里!
        ],
        shape=img.shape)
    seq = iaa.Sequential([
        iaa.Flipud(0.5),  # vertically flip 20% of all images
        iaa.Multiply((1.2, 1.5)),  # change brightness, doesn't affect BBs
        iaa.Affine(
            translate_px={
                "x": 10,
                "y": 10
            },
            scale=(0.8, 0.95),
            rotate=(-10, 10)
        )  # translate by 40/60px on x/y axis, and scale to 50-70%, affects BBs
    ])
    seq_det = seq.to_deterministic()  # 保持坐标和图像同步改变,而不是随机
Ejemplo n.º 27
0
def main(_):
    writer = tf.python_io.TFRecordWriter(FLAGS.output_path)

    sometimes = lambda aug: iaa.Sometimes(0.5, aug)
    seq = iaa.Sequential(
    [
        iaa.Fliplr(0.5), # horizontally flip 50% of all images
        iaa.Flipud(0.2), # vertically flip 20% of all images
        # crop images by -10% to 20% of their height/width
        sometimes(iaa.CropAndPad(
            percent=(-0.05, 0.1),
            pad_mode=ia.ALL,
            pad_cval=(0, 255)
        )),
        sometimes(iaa.Affine(
            translate_percent={"x": (-0.2, 0.2), "y": (-0.2, 0.2)}, # translate by -50 to +50 percent (per axis)
            rotate=(-20, 20), # rotate by -90 to +90 degrees
            order=[0, 1], # use nearest neighbour or bilinear interpolation (fast)
            cval=(0, 255), # if mode is constant, use a cval between 0 and 255
            mode=ia.ALL # use any of scikit-image's warping modes (see 2nd image from the top for examples)
        )),
    ],
    random_order=True)

    ann              = None
    num_batches      = 80
    images, bboxs    = [], []

    dir_path = '/home/kshitiz/workspace/autonomous_drone_for_tracking/data/detector_' + FLAGS.flag + '/'
    xml_files = [f for f in os.listdir(dir_path) if f.endswith('.xml')]

    num_orig_samples = len(xml_files)

    for i,xml_file in enumerate(xml_files):
        path = dir_path + xml_file
        tree = ET.parse(path)
        root = tree.getroot()

        obj = root.findall('object')
        bndbox = obj[0].find('bndbox')

        xmin = int(bndbox.find('xmin').text)
        xmax = int(bndbox.find('xmax').text)
        ymin = int(bndbox.find('ymin').text)
        ymax = int(bndbox.find('ymax').text)


        image = np.asarray(Image.open((path.split('.')[0] + '.png')), dtype='uint8')
        bbox  = ia.BoundingBoxesOnImage([ia.BoundingBox(x1=xmin, y1=ymin, x2=xmax, y2=ymax)], shape=image.shape)

        images.append(image)
        bboxs.append(bbox)

        # image_copy = image.copy()
        # vis_util.draw_bounding_boxes_on_image_array( image_copy,
        #                                              np.array([[float(ymin)/image.shape[0], float(xmin)/image.shape[1], float(ymax)/image.shape[0], float(xmax)/image.shape[1] ]]),
        #                                              color='yellow',
        #                                              thickness=4)
       	# imgplot = plt.imshow(image_copy)
        # plt.show()


    for i in range(num_batches):
        seq_det    = seq.to_deterministic()
        aug_images = seq_det.augment_images(images)
        aug_bboxs  = seq_det.augment_bounding_boxes(bboxs)

        for j, (image_np, abbox) in enumerate(zip(aug_images, aug_bboxs)):

        	#aug_bboxs[]
            bbox = abbox.bounding_boxes[0]
            result   = Image.fromarray(image_np)
            out_path = '/home/kshitiz/workspace/autonomous_drone_for_tracking/TF_ObjectDetection/data/' + \
                        FLAGS.flag + '/' + str(i*num_orig_samples+j).zfill(6) + '.png'
            result.save(out_path)

            # image = image_np.copy()
            # vis_util.draw_bounding_boxes_on_image_array( image,
            #                                             np.array([[ float(bbox.y1)/image.shape[0], float(bbox.x1)/image.shape[1], float(bbox.y2)/image.shape[0], float(bbox.x2)/image.shape[1]]]),
            #                                             color='yellow',
            #                                             thickness=4)
            # imgplot = plt.imshow(image)
            # plt.show()


            tf_example = create_tf_example(out_path, bbox, image.shape)
            writer.write(tf_example.SerializeToString())

            os.remove(out_path)

        if i%10==0 and i!=0:
            print "Number of batches processed", i

    writer.close()
Ejemplo n.º 28
0
    def test_deepcopy(self):
        batch = ia.Batch()
        observed = batch.deepcopy()
        keys = list(observed.__dict__.keys())
        assert len(keys) >= 12
        for attr_name in keys:
            assert getattr(observed, attr_name) is None

        batch = ia.Batch(images=np.zeros((1, 1, 3), dtype=np.uint8))
        observed = batch.deepcopy()
        for attr_name in observed.__dict__.keys():
            if attr_name != "images_unaug":
                assert getattr(observed, attr_name) is None
        assert ia.is_np_array(observed.images_unaug)

        batch = ia.Batch(
            images=np.zeros((1, 1, 3), dtype=np.uint8),
            heatmaps=[
                ia.HeatmapsOnImage(np.zeros((1, 1, 1), dtype=np.float32),
                                   shape=(4, 4, 3))
            ],
            segmentation_maps=[
                ia.SegmentationMapOnImage(np.zeros((1, 1), dtype=np.int32),
                                          shape=(5, 5, 3),
                                          nb_classes=20)
            ],
            keypoints=[
                ia.KeypointsOnImage([ia.Keypoint(x=1, y=2)], shape=(6, 6, 3))
            ],
            bounding_boxes=[
                ia.BoundingBoxesOnImage(
                    [ia.BoundingBox(x1=1, y1=2, x2=3, y2=4)], shape=(7, 7, 3))
            ],
            polygons=[
                ia.PolygonsOnImage([ia.Polygon([(0, 0), (10, 0), (10, 10)])],
                                   shape=(100, 100, 3))
            ],
            data={
                "test": 123,
                "foo": "bar",
                "test2": [1, 2, 3]
            })
        observed = batch.deepcopy()
        for attr_name in observed.__dict__.keys():
            if "_unaug" not in attr_name and attr_name != "data":
                assert getattr(observed, attr_name) is None

        assert ia.is_np_array(observed.images_unaug)
        assert observed.images_unaug.shape == (1, 1, 3)
        assert isinstance(observed.heatmaps_unaug[0], ia.HeatmapsOnImage)
        assert isinstance(observed.segmentation_maps_unaug[0],
                          ia.SegmentationMapOnImage)
        assert isinstance(observed.keypoints_unaug[0], ia.KeypointsOnImage)
        assert isinstance(observed.bounding_boxes_unaug[0],
                          ia.BoundingBoxesOnImage)
        assert isinstance(observed.polygons_unaug[0], ia.PolygonsOnImage)
        assert isinstance(observed.data, dict)

        assert observed.heatmaps_unaug[0].shape == (4, 4, 3)
        assert observed.segmentation_maps_unaug[0].shape == (5, 5, 3)
        assert observed.keypoints_unaug[0].shape == (6, 6, 3)
        assert observed.bounding_boxes_unaug[0].shape == (7, 7, 3)
        assert observed.polygons_unaug[0].shape == (100, 100, 3)

        assert observed.heatmaps_unaug[0].arr_0to1.shape == (1, 1, 1)
        assert observed.segmentation_maps_unaug[0].arr.shape == (1, 1, 20)
        assert observed.keypoints_unaug[0].keypoints[0].x == 1
        assert observed.keypoints_unaug[0].keypoints[0].y == 2
        assert observed.bounding_boxes_unaug[0].bounding_boxes[0].x1 == 1
        assert observed.bounding_boxes_unaug[0].bounding_boxes[0].y1 == 2
        assert observed.bounding_boxes_unaug[0].bounding_boxes[0].x2 == 3
        assert observed.bounding_boxes_unaug[0].bounding_boxes[0].y2 == 4
        assert observed.polygons_unaug[0].polygons[0].exterior[0, 0] == 0
        assert observed.polygons_unaug[0].polygons[0].exterior[0, 1] == 0
        assert observed.polygons_unaug[0].polygons[0].exterior[1, 0] == 10
        assert observed.polygons_unaug[0].polygons[0].exterior[1, 1] == 0
        assert observed.polygons_unaug[0].polygons[0].exterior[2, 0] == 10
        assert observed.polygons_unaug[0].polygons[0].exterior[2, 1] == 10

        assert observed.data["test"] == 123
        assert observed.data["foo"] == "bar"
        assert observed.data["test2"] == [1, 2, 3]
Ejemplo n.º 29
0
def test_BoundingBoxesOnImage():
    reseed()

    # test height/width
    bb1 = ia.BoundingBox(y1=10, x1=20, y2=30, x2=40, label=None)
    bb2 = ia.BoundingBox(y1=15, x1=25, y2=35, x2=45, label=None)
    bbsoi = ia.BoundingBoxesOnImage([bb1, bb2], shape=(40, 50, 3))
    assert bbsoi.height == 40
    assert bbsoi.width == 50

    bb1 = ia.BoundingBox(y1=10, x1=20, y2=30, x2=40, label=None)
    bb2 = ia.BoundingBox(y1=15, x1=25, y2=35, x2=45, label=None)
    bbsoi = ia.BoundingBoxesOnImage([bb1, bb2],
                                    shape=np.zeros((40, 50, 3),
                                                   dtype=np.uint8))
    assert bbsoi.height == 40
    assert bbsoi.width == 50

    # empty
    bb = ia.BoundingBox(y1=10, x1=20, y2=30, x2=40, label=None)
    bbsoi = ia.BoundingBoxesOnImage([bb], shape=(40, 50, 3))
    assert not bbsoi.empty

    bbsoi = ia.BoundingBoxesOnImage([], shape=(40, 50, 3))
    assert bbsoi.empty

    # on()
    bb1 = ia.BoundingBox(y1=10, x1=20, y2=30, x2=40, label=None)
    bb2 = ia.BoundingBox(y1=15, x1=25, y2=35, x2=45, label=None)
    bbsoi = ia.BoundingBoxesOnImage([bb1, bb2],
                                    shape=np.zeros((40, 50, 3),
                                                   dtype=np.uint8))

    bbsoi_projected = bbsoi.on((40, 50))
    assert bbsoi_projected.bounding_boxes[0].y1 == 10
    assert bbsoi_projected.bounding_boxes[0].x1 == 20
    assert bbsoi_projected.bounding_boxes[0].y2 == 30
    assert bbsoi_projected.bounding_boxes[0].x2 == 40
    assert bbsoi_projected.bounding_boxes[1].y1 == 15
    assert bbsoi_projected.bounding_boxes[1].x1 == 25
    assert bbsoi_projected.bounding_boxes[1].y2 == 35
    assert bbsoi_projected.bounding_boxes[1].x2 == 45

    bbsoi_projected = bbsoi.on((40 * 2, 50 * 2, 3))
    assert bbsoi_projected.bounding_boxes[0].y1 == 10 * 2
    assert bbsoi_projected.bounding_boxes[0].x1 == 20 * 2
    assert bbsoi_projected.bounding_boxes[0].y2 == 30 * 2
    assert bbsoi_projected.bounding_boxes[0].x2 == 40 * 2
    assert bbsoi_projected.bounding_boxes[1].y1 == 15 * 2
    assert bbsoi_projected.bounding_boxes[1].x1 == 25 * 2
    assert bbsoi_projected.bounding_boxes[1].y2 == 35 * 2
    assert bbsoi_projected.bounding_boxes[1].x2 == 45 * 2

    bbsoi_projected = bbsoi.on(np.zeros((40 * 2, 50 * 2, 3), dtype=np.uint8))
    assert bbsoi_projected.bounding_boxes[0].y1 == 10 * 2
    assert bbsoi_projected.bounding_boxes[0].x1 == 20 * 2
    assert bbsoi_projected.bounding_boxes[0].y2 == 30 * 2
    assert bbsoi_projected.bounding_boxes[0].x2 == 40 * 2
    assert bbsoi_projected.bounding_boxes[1].y1 == 15 * 2
    assert bbsoi_projected.bounding_boxes[1].x1 == 25 * 2
    assert bbsoi_projected.bounding_boxes[1].y2 == 35 * 2
    assert bbsoi_projected.bounding_boxes[1].x2 == 45 * 2

    # from_xyxy_array()
    bbsoi = ia.BoundingBoxesOnImage.from_xyxy_array(np.float32(
        [[0.0, 0.0, 1.0, 1.0], [1.0, 2.0, 3.0, 4.0]]),
                                                    shape=(40, 50, 3))
    assert len(bbsoi.bounding_boxes) == 2
    assert np.allclose(bbsoi.bounding_boxes[0].x1, 0.0)
    assert np.allclose(bbsoi.bounding_boxes[0].y1, 0.0)
    assert np.allclose(bbsoi.bounding_boxes[0].x2, 1.0)
    assert np.allclose(bbsoi.bounding_boxes[0].y2, 1.0)
    assert np.allclose(bbsoi.bounding_boxes[1].x1, 1.0)
    assert np.allclose(bbsoi.bounding_boxes[1].y1, 2.0)
    assert np.allclose(bbsoi.bounding_boxes[1].x2, 3.0)
    assert np.allclose(bbsoi.bounding_boxes[1].y2, 4.0)
    assert bbsoi.shape == (40, 50, 3)

    bbsoi = ia.BoundingBoxesOnImage.from_xyxy_array(np.int32([[0, 0, 1, 1],
                                                              [1, 2, 3, 4]]),
                                                    shape=(40, 50, 3))
    assert len(bbsoi.bounding_boxes) == 2
    assert np.allclose(bbsoi.bounding_boxes[0].x1, 0.0)
    assert np.allclose(bbsoi.bounding_boxes[0].y1, 0.0)
    assert np.allclose(bbsoi.bounding_boxes[0].x2, 1.0)
    assert np.allclose(bbsoi.bounding_boxes[0].y2, 1.0)
    assert np.allclose(bbsoi.bounding_boxes[1].x1, 1.0)
    assert np.allclose(bbsoi.bounding_boxes[1].y1, 2.0)
    assert np.allclose(bbsoi.bounding_boxes[1].x2, 3.0)
    assert np.allclose(bbsoi.bounding_boxes[1].y2, 4.0)
    assert bbsoi.shape == (40, 50, 3)

    bbsoi = ia.BoundingBoxesOnImage.from_xyxy_array(np.zeros((0, 4),
                                                             dtype=np.float32),
                                                    shape=(40, 50, 3))
    assert len(bbsoi.bounding_boxes) == 0
    assert bbsoi.shape == (40, 50, 3)

    # to_xyxy_array()
    xyxy_arr = np.float32([[0.0, 0.0, 1.0, 1.0], [1.0, 2.0, 3.0, 4.0]])
    bbsoi = ia.BoundingBoxesOnImage.from_xyxy_array(xyxy_arr,
                                                    shape=(40, 50, 3))
    xyxy_arr_out = bbsoi.to_xyxy_array()
    assert np.allclose(xyxy_arr, xyxy_arr_out)
    assert xyxy_arr_out.dtype == np.float32

    xyxy_arr_out = bbsoi.to_xyxy_array(dtype=np.int32)
    assert np.allclose(xyxy_arr.astype(np.int32), xyxy_arr_out)
    assert xyxy_arr_out.dtype == np.int32

    xyxy_arr_out = ia.BoundingBoxesOnImage(
        [], shape=(40, 50, 3)).to_xyxy_array(dtype=np.int32)
    assert xyxy_arr_out.shape == (0, 4)

    # draw_on_image()
    bb1 = ia.BoundingBox(y1=10, x1=20, y2=30, x2=40, label=None)
    bb2 = ia.BoundingBox(y1=15, x1=25, y2=35, x2=45, label=None)
    bbsoi = ia.BoundingBoxesOnImage([bb1, bb2], shape=(40, 50, 3))
    image = bbsoi.draw_on_image(np.zeros(bbsoi.shape, dtype=np.uint8),
                                color=[0, 255, 0],
                                alpha=1.0,
                                thickness=1,
                                copy=True,
                                raise_if_out_of_image=False)
    assert np.all(image[10 - 1, 20 - 1, :] == [0, 0, 0])
    assert np.all(image[10 - 1, 20 - 0, :] == [0, 0, 0])
    assert np.all(image[10 - 0, 20 - 1, :] == [0, 0, 0])
    assert np.all(image[10 - 0, 20 - 0, :] == [0, 255, 0])
    assert np.all(image[10 + 1, 20 + 1, :] == [0, 0, 0])

    assert np.all(image[30 - 1, 40 - 1, :] == [0, 0, 0])
    assert np.all(image[30 + 1, 40 - 0, :] == [0, 0, 0])
    assert np.all(image[30 + 0, 40 + 1, :] == [0, 0, 0])
    assert np.all(image[30 + 0, 40 + 0, :] == [0, 255, 0])
    assert np.all(image[30 + 1, 40 + 1, :] == [0, 0, 0])

    assert np.all(image[15 - 1, 25 - 1, :] == [0, 0, 0])
    assert np.all(image[15 - 1, 25 - 0, :] == [0, 0, 0])
    assert np.all(image[15 - 0, 25 - 1, :] == [0, 0, 0])
    assert np.all(image[15 - 0, 25 - 0, :] == [0, 255, 0])
    assert np.all(image[15 + 1, 25 + 1, :] == [0, 0, 0])

    assert np.all(image[35 - 1, 45 - 1, :] == [0, 0, 0])
    assert np.all(image[35 + 1, 45 + 0, :] == [0, 0, 0])
    assert np.all(image[35 + 0, 45 + 1, :] == [0, 0, 0])
    assert np.all(image[35 + 0, 45 + 0, :] == [0, 255, 0])
    assert np.all(image[35 + 1, 45 + 1, :] == [0, 0, 0])

    # remove_out_of_image()
    bb1 = ia.BoundingBox(y1=10, x1=20, y2=30, x2=40, label=None)
    bb2 = ia.BoundingBox(y1=15, x1=25, y2=35, x2=51, label=None)
    bbsoi = ia.BoundingBoxesOnImage([bb1, bb2], shape=(40, 50, 3))
    bbsoi_slim = bbsoi.remove_out_of_image(fully=True, partly=True)
    assert len(bbsoi_slim.bounding_boxes) == 1
    assert bbsoi_slim.bounding_boxes[0] == bb1

    # clip_out_of_image()
    bb1 = ia.BoundingBox(y1=10, x1=20, y2=30, x2=40, label=None)
    bb2 = ia.BoundingBox(y1=15, x1=25, y2=35, x2=51, label=None)
    bbsoi = ia.BoundingBoxesOnImage([bb1, bb2], shape=(40, 50, 3))
    eps = np.finfo(np.float32).eps
    bbsoi_clip = bbsoi.clip_out_of_image()
    assert len(bbsoi_clip.bounding_boxes) == 2
    assert bbsoi_clip.bounding_boxes[0].y1 == 10
    assert bbsoi_clip.bounding_boxes[0].x1 == 20
    assert bbsoi_clip.bounding_boxes[0].y2 == 30
    assert bbsoi_clip.bounding_boxes[0].x2 == 40
    assert bbsoi_clip.bounding_boxes[1].y1 == 15
    assert bbsoi_clip.bounding_boxes[1].x1 == 25
    assert bbsoi_clip.bounding_boxes[1].y2 == 35
    assert 50 - 2 * eps < bbsoi_clip.bounding_boxes[1].x2 < 50

    # shift()
    bb1 = ia.BoundingBox(y1=10, x1=20, y2=30, x2=40, label=None)
    bb2 = ia.BoundingBox(y1=15, x1=25, y2=35, x2=51, label=None)
    bbsoi = ia.BoundingBoxesOnImage([bb1, bb2], shape=(40, 50, 3))
    bbsoi_shifted = bbsoi.shift(right=1)
    assert len(bbsoi_shifted.bounding_boxes) == 2
    assert bbsoi_shifted.bounding_boxes[0].y1 == 10
    assert bbsoi_shifted.bounding_boxes[0].x1 == 20 - 1
    assert bbsoi_shifted.bounding_boxes[0].y2 == 30
    assert bbsoi_shifted.bounding_boxes[0].x2 == 40 - 1
    assert bbsoi_shifted.bounding_boxes[1].y1 == 15
    assert bbsoi_shifted.bounding_boxes[1].x1 == 25 - 1
    assert bbsoi_shifted.bounding_boxes[1].y2 == 35
    assert bbsoi_shifted.bounding_boxes[1].x2 == 51 - 1

    # copy()
    bb1 = ia.BoundingBox(y1=10, x1=20, y2=30, x2=40, label=None)
    bb2 = ia.BoundingBox(y1=15, x1=25, y2=35, x2=51, label=None)
    bbsoi = ia.BoundingBoxesOnImage([bb1, bb2], shape=(40, 50, 3))
    bbsoi_copy = bbsoi.copy()
    assert len(bbsoi.bounding_boxes) == 2
    assert bbsoi_copy.bounding_boxes[0].y1 == 10
    assert bbsoi_copy.bounding_boxes[0].x1 == 20
    assert bbsoi_copy.bounding_boxes[0].y2 == 30
    assert bbsoi_copy.bounding_boxes[0].x2 == 40
    assert bbsoi_copy.bounding_boxes[1].y1 == 15
    assert bbsoi_copy.bounding_boxes[1].x1 == 25
    assert bbsoi_copy.bounding_boxes[1].y2 == 35
    assert bbsoi_copy.bounding_boxes[1].x2 == 51

    bbsoi.bounding_boxes[0].y1 = 0
    assert bbsoi_copy.bounding_boxes[0].y1 == 0

    # deepcopy()
    bb1 = ia.BoundingBox(y1=10, x1=20, y2=30, x2=40, label=None)
    bb2 = ia.BoundingBox(y1=15, x1=25, y2=35, x2=51, label=None)
    bbsoi = ia.BoundingBoxesOnImage([bb1, bb2], shape=(40, 50, 3))
    bbsoi_copy = bbsoi.deepcopy()
    assert len(bbsoi.bounding_boxes) == 2
    assert bbsoi_copy.bounding_boxes[0].y1 == 10
    assert bbsoi_copy.bounding_boxes[0].x1 == 20
    assert bbsoi_copy.bounding_boxes[0].y2 == 30
    assert bbsoi_copy.bounding_boxes[0].x2 == 40
    assert bbsoi_copy.bounding_boxes[1].y1 == 15
    assert bbsoi_copy.bounding_boxes[1].x1 == 25
    assert bbsoi_copy.bounding_boxes[1].y2 == 35
    assert bbsoi_copy.bounding_boxes[1].x2 == 51

    bbsoi.bounding_boxes[0].y1 = 0
    assert bbsoi_copy.bounding_boxes[0].y1 == 10

    # repr() / str()
    bb1 = ia.BoundingBox(y1=10, x1=20, y2=30, x2=40, label=None)
    bb2 = ia.BoundingBox(y1=15, x1=25, y2=35, x2=51, label=None)
    bbsoi = ia.BoundingBoxesOnImage([bb1, bb2], shape=(40, 50, 3))
    bb1_expected = "BoundingBox(x1=20.0000, y1=10.0000, x2=40.0000, y2=30.0000, label=None)"
    bb2_expected = "BoundingBox(x1=25.0000, y1=15.0000, x2=51.0000, y2=35.0000, label=None)"
    expected = "BoundingBoxesOnImage([%s, %s], shape=(40, 50, 3))" % (
        bb1_expected, bb2_expected)
    assert bbsoi.__repr__() == bbsoi.__str__() == expected
    def _ndarray_to_BoundingBoxesOnImage(bboxes: np.ndarray, img_shape) -> ia.BoundingBoxesOnImage:
        bb_list = []
        for bbox in bboxes:
            bb_list.append(ia.BoundingBox(*bbox))

        return ia.BoundingBoxesOnImage(bb_list, shape=img_shape)