def chapter_examples_bounding_boxes_shift(): import imgaug as ia from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage ia.seed(1) # Define image and two bounding boxes image = ia.quokka(size=(256, 256)) bbs = BoundingBoxesOnImage([ BoundingBox(x1=25, x2=75, y1=25, y2=75), BoundingBox(x1=100, x2=150, y1=25, y2=75) ], shape=image.shape) # Move both BBs 25px to the right and the second BB 25px down bbs_shifted = bbs.shift(left=25) bbs_shifted.bounding_boxes[1] = bbs_shifted.bounding_boxes[1].shift(top=25) # Draw images before/after moving BBs image = bbs.draw_on_image(image, color=[0, 255, 0], size=2, alpha=0.75) image = bbs_shifted.draw_on_image(image, color=[0, 0, 255], size=2, alpha=0.75) # ------------ save("examples_bounding_boxes", "shift.jpg", grid([image], cols=1, rows=1), quality=90)
def chapter_examples_bounding_boxes_projection(): import imgaug as ia from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage ia.seed(1) # Define image with two bounding boxes image = ia.quokka(size=(256, 256)) bbs = BoundingBoxesOnImage([ BoundingBox(x1=25, x2=75, y1=25, y2=75), BoundingBox(x1=100, x2=150, y1=25, y2=75) ], shape=image.shape) # Rescale image and bounding boxes image_rescaled = ia.imresize_single_image(image, (512, 512)) bbs_rescaled = bbs.on(image_rescaled) # Draw image before/after rescaling and with rescaled bounding boxes image_bbs = bbs.draw_on_image(image, size=2) image_rescaled_bbs = bbs_rescaled.draw_on_image(image_rescaled, size=2) # ------------ save("examples_bounding_boxes", "projection.jpg", grid([image_bbs, image_rescaled_bbs], cols=2, rows=1), quality=90)
def augument(impath): ia.seed(1) image = imageio.imread(impath) bbs = BoundingBoxesOnImage([ BoundingBox(x1=170, y1=130, x2=252, y2=248, label='18'), BoundingBox(x1=100, y1=154, x2=120, y2=175, label='1') ], shape=image.shape) ia.imshow(bbs.draw_on_image(image, size=2)) # apply augumentation # We choose a simple contrast augmentation (affects only the image) and an affine transformation (affects image and bounding boxes). seq = iaa.Sequential([ iaa.GammaContrast(1.5), iaa.Affine(translate_percent={"x": 0.1}, scale=0.8) ]) image_aug, bbs_aug = seq(image=image, bounding_boxes=bbs) ia.imshow(bbs_aug.draw_on_image(image_aug, size=2)) # we apply an affine transformation consisting only of rotation. image_aug, bbs_aug = iaa.Affine(rotate=50)(image=image, bounding_boxes=bbs) ia.imshow(bbs_aug.draw_on_image(image_aug))
def augment(x, y, x_new, y_new, deg): # Batch(images=x, bounding_boxes=[[BoundingBox(*row[2:6]), for row in y]); seq = iaa.Sequential([ iaa.Affine(rotate=deg) ]) for dpt_x, dpt_y, dpt_x_new, dpt_y_new in zip(x, y, x_new, y_new): bb1 = [t * img_size_red for t in dpt_y[2:6]] bb2 = [t * img_size_red for t in dpt_y[6:10]] img_aug, bbs_aug = seq(image=dpt_x, bounding_boxes=BoundingBoxesOnImage([ BoundingBox(*bb1), BoundingBox(*bb2)], shape=dpt_x.shape)) dpt_x_new[:,:,:] = img_aug bbs_aug_clipped = bbs_aug.remove_out_of_image().clip_out_of_image() dpt_y_new[:2] = [dpt_y[0],dpt_y[1]] for i, bb in enumerate(bbs_aug_clipped): if (bb.is_out_of_image(img_aug.shape)): # boundingbox is fully out of image # remove it dpt_y_new[i] = 0.0 dpt_y_new[4*i+2:4*i+6] = [0.0, 0.0, 0.0, 0.0] else: # boundingbox is completely or partially in the image dpt_y_new[4*i+2:4*i+6] = [t / img_size_red for t in [bb.x1, bb.y1, bb.x2, bb.y2]]
def add_bounding_box_right(self, position, size): x1 = position[0] + int(size[0] * 0.85) y1 = position[1] + int(size[1] * 0.73) x2 = position[0] + int(size[0] * 0.99) y2 = position[1] + int(size[1] * 0.99) bounding_box = BoundingBox(x1, y1, x2, y2) bounding_box.label = self.file_name self.bounding_boxes_on_image.bounding_boxes.append(bounding_box)
def add_bounding_box_left(self, position, size): x1 = position[0] + int(size[0] * 0.01) y1 = position[1] + int(size[1] * 0.01) x2 = position[0] + int(size[0] * 0.15) y2 = position[1] + int(size[1] * 0.27) bounding_box = BoundingBox(x1, y1, x2, y2) bounding_box.label = self.file_name self.bounding_boxes_on_image.bounding_boxes.append(bounding_box)
def test_augment_bounding_boxes__kernel_size_is_two__no_keep_size(self): from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage bbs = [BoundingBox(x1=1.5, y1=2.5, x2=3.5, y2=4.5)] bbsoi = BoundingBoxesOnImage(bbs, shape=(6, 6, 3)) expected = BoundingBoxesOnImage( [BoundingBox(x1=1.5 / 2, y1=2.5 / 2, x2=3.5 / 2, y2=4.5 / 2)], shape=(3, 3, 3)) self._test_augment_cbaoi__kernel_size_is_two__no_keep_size( bbsoi, expected, "augment_bounding_boxes")
def __call__(self, sample): seq_det = self.seq.to_deterministic() image, label = sample['image'], sample['label'] # print(sample) h, w, _ = image.shape x1 = w * (label[:, 1] - label[:, 3] / 2) y1 = h * (label[:, 2] - label[:, 4] / 2) x2 = w * (label[:, 1] + label[:, 3] / 2) y2 = h * (label[:, 2] + label[:, 4] / 2) list_of_bbox = [] for i in range(len(x1)): list_of_bbox.append( BoundingBox(x1=x1[i], y1=y1[i], x2=x2[i], y2=y2[i])) # print("length of list_of_bbox:{}".format(len(list_of_bbox))) bbs = BoundingBoxesOnImage(list_of_bbox, shape=image.shape) image_aug, bbs_aug = seq_det(image=image, bounding_boxes=bbs) # bbs_aug = bbs_aug.remove_out_of_image().clip_out_of_image() bbs_aug = bbs_aug.remove_out_of_image() label_new = [] for i in range(len(bbs_aug.bounding_boxes)): after = bbs_aug.bounding_boxes[i] x1a = after.x1 y1a = after.y1 x2a = after.x2 y2a = after.y2 try: A = BoundingBox(x1=x1a, y1=y1a, x2=x2a, y2=y2a) B = BoundingBox(x1=0, y1=0, x2=w - 1, y2=h - 1) R = A.intersection(B).area / A.area # print("R:{}".format(R)) if R <= 0.5: #Delete bbox that more than 1/3 area is out of the image continue if R < 1.0 and R > 0.5: #clip bbox inside the image xx = np.clip([x1a, x2a], 0, w - 1) yy = np.clip([y1a, y2a], 0, h - 1) x1a = xx[0] x2a = xx[1] y1a = yy[0] y2a = yy[1] x0 = ((x1a + x2a) / 2.0) / w y0 = ((y1a + y2a) / 2.0) / h w0 = (x2a - x1a) / w h0 = (y2a - y1a) / h labela = label[:, 0][i] label_new.append([labela, x0, y0, w0, h0]) except Exception as e: print(e) return {'image': image_aug, 'label': np.asarray(label_new)}
def _quokka_normalize_extract(extract): """Generate a normalized rectangle for the standard quokka image. Added in 0.5.0. (Moved from ``imgaug.imgaug``.) Parameters ---------- extract : 'square' or tuple of number or imgaug.augmentables.bbs.BoundingBox or imgaug.augmentables.bbs.BoundingBoxesOnImage Unnormalized representation of the image subarea to be extracted. * If ``str`` ``square``, then a squared area ``(x: 0 to max 643, y: 0 to max 643)`` will be extracted from the image. * If a ``tuple``, then expected to contain four ``number`` s denoting ``(x1, y1, x2, y2)``. * If a :class:`~imgaug.augmentables.bbs.BoundingBox`, then that bounding box's area will be extracted from the image. * If a :class:`~imgaug.augmentables.bbs.BoundingBoxesOnImage`, then expected to contain exactly one bounding box and a shape matching the full image dimensions (i.e. ``(643, 960, *)``). Then the one bounding box will be used similar to ``BoundingBox`` above. Returns ------- imgaug.augmentables.bbs.BoundingBox Normalized representation of the area to extract from the standard quokka image. """ # TODO get rid of this deferred import from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage if extract == "square": bb = BoundingBox(x1=0, y1=0, x2=643, y2=643) elif isinstance(extract, tuple) and len(extract) == 4: bb = BoundingBox(x1=extract[0], y1=extract[1], x2=extract[2], y2=extract[3]) elif isinstance(extract, BoundingBox): bb = extract elif isinstance(extract, BoundingBoxesOnImage): assert len(extract.bounding_boxes) == 1, ( "Provided BoundingBoxesOnImage instance may currently only " "contain a single bounding box.") assert extract.shape[0:2] == (643, 960), ( "Expected BoundingBoxesOnImage instance on an image of shape " "(643, 960, ?). Got shape %s." % (extract.shape, )) bb = extract.bounding_boxes[0] else: raise Exception( "Expected 'square' or tuple of four entries or BoundingBox or " "BoundingBoxesOnImage for parameter 'extract', " "got %s." % (type(extract), )) return bb
def test_augment_bounding_boxes__kernel_size_is_two__no_keep_size(self): from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage bbs = [BoundingBox(x1=1.5, y1=2.5, x2=3.5, y2=4.5)] bbsoi = BoundingBoxesOnImage(bbs, shape=(6, 6, 3)) aug = self.augmenter(2, keep_size=False) bbsoi_aug = aug.augment_bounding_boxes(bbsoi) expected = BoundingBoxesOnImage( [BoundingBox(x1=1.5 / 2, y1=2.5 / 2, x2=3.5 / 2, y2=4.5 / 2)], shape=(3, 3, 3)) assert_cbaois_equal(bbsoi_aug, expected)
def _read_labelme(_path_list, _pos): for i, name in enumerate(_path_list): pos = (_pos + i) with open(os.path.join(self.label_path, name[:name.rfind(".")] + ".json"), encoding=self.encoding) as f: jdata = f.read() data = json.loads(jdata) if self.img_path is None: img64 = data['imageData'] img = Image.open(BytesIO(base64.b64decode(img64))) else: img = Image.open(os.path.join(self.img_path, name)) img, zoom_r = _process_img(img, self.size) bbs = [] labels = [] for i in range(len(data['shapes'])): if data['shapes'][i]['label'] in self.class_names: label_text = data['shapes'][i]['label'] label = self.class_names.index(label_text) labels.append(label) point = np.array(data['shapes'][i]['points']) point = point / zoom_r bbs.append( BoundingBox(x1=point[0, 0], y1=point[0, 1], x2=point[1, 0], y2=point[1, 1])) bbs = BoundingBoxesOnImage(bbs, shape=img.shape) _imgaug_to_array(img, bbs, self.grid_shape, pos, labels)
def _read_labelimg(_path_list, _pos): for i, name in enumerate(_path_list): pos = (_pos + i) with open(os.path.join(self.label_path, name[:name.rfind(".")] + ".xml"), encoding=self.encoding) as f: soup = BeautifulSoup(f.read(), "xml") img = Image.open(os.path.join(self.img_path, name)) img, zoom_r = _process_img(img, self.size) bbs = [] labels = [] for obj in soup.select("object"): if obj.select_one("name").text in self.class_names: label_text = obj.select_one("name").text label = self.class_names.index(label_text) labels.append(label) xmin = int(obj.select_one("xmin").text) / zoom_r[0] xmax = int(obj.select_one("xmax").text) / zoom_r[0] ymin = int(obj.select_one("ymin").text) / zoom_r[1] ymax = int(obj.select_one("ymax").text) / zoom_r[1] bbs.append( BoundingBox(x1=xmin, y1=ymin, x2=xmax, y2=ymax)) bbs = BoundingBoxesOnImage(bbs, shape=img.shape) _imgaug_to_array(img, bbs, self.grid_shape, pos, labels)
def augment(record): record = deepcopy(record) image = plt.imread(record["filepath"]) annotations = record["annotations"] boxes = [annotation["bbox"] for annotation in annotations] classes = [annotation["category_id"] for annotation in annotations] boxes = BoundingBoxesOnImage( [ BoundingBox(*box, label=class_) for box, class_ in zip(boxes, classes) ], shape=image.shape, ) image, boxes = AUGMENTER(image=image, bounding_boxes=boxes) classes = [bbox.label for bbox in boxes.bounding_boxes] boxes = np.array([[box.x1, box.y1, box.x2, box.y2] for box in boxes.items]) image = image[..., [2, 1]] image = image.transpose(2, 0, 1).astype(np.float32) annotations = [{ "bbox": box, "bbox_mode": BoxMode.XYXY_ABS, "category_id": class_ } for box, class_ in zip(boxes, classes)] record["image"] = torch.as_tensor(image) instances = utils.annotations_to_instances(annotations, image.shape[1:]) record["instances"] = utils.filter_empty_instances(instances) return record
def get_image_with_box(img: np.ndarray, img_name: str, df: pd.DataFrame) -> np.ndarray: """ This function will: 1. get all bounding boxes that relate to the image for the DataFrame 2. concatenate them with imgaug package to a BoundingBoxesOnImage object 3. draw the Bounding boxes onto the image :param img: image as np array :param img_name: filename to locate the bounding boxes in the df :param df: DataFrame that holds the information about all bounding boxes :return: image with bounding boxes drawn onto it """ # create bounding box with imgaug img_boxs = df[df.filename == img_name] bbs = list() for _, row in img_boxs.iterrows(): x1 = row.xmin y1 = row.ymin x2 = row.xmax y2 = row.ymax bbs.append(BoundingBox(x1=x1, y1=y1, x2=x2, y2=y2)) # convert single bounding boxes to BOundingBoxOnImage instance to draw it on the picture bbs = BoundingBoxesOnImage(bbs, img.shape[:-1]) # draw image img = bbs.draw_on_image(img) return img
def __call__(self, img, anno): labels = anno[0].numpy() gts = anno[1].numpy() np_img = np.asarray(img) # get BoundingBoxesOnImage bbs = [] for gt in gts: bbs.append(BoundingBox(x1=gt[0], y1=gt[1], x2=gt[2], y2=gt[3])) bbs_on_img = BoundingBoxesOnImage(bbs, shape=np_img.shape) # draw_img = bbs_on_img.draw_on_image(np_img, size=2) r = np.random.sample() p = -self.percent + 2 * self.percent * r self.seq = iaa.Sequential([iaa.CropAndPad(percent=p, keep_size=False)]) # apply augment image_aug = self.seq.augment_image(np_img) bbs_aug = self.seq.augment_bounding_boxes(bbs_on_img).bounding_boxes gts = [] for bb in bbs_aug: gts.append([bb.x1, bb.y1, bb.x2, bb.y2]) gts = torch.from_numpy(np.array(gts)) return image_aug, (anno[0], gts, anno[2])
def __call__(self, img, anno): labels = anno[0].numpy() gts = anno[1].numpy() np_img = np.asarray(img) # get BoundingBoxesOnImage bbs = [] for gt in gts: bbs.append(BoundingBox(x1=gt[0], y1=gt[1], x2=gt[2], y2=gt[3])) bbs_on_img = BoundingBoxesOnImage(bbs, shape=np_img.shape) # draw_img = bbs_on_img.draw_on_image(np_img, size=2) height = np_img.shape[0] width = np_img.shape[1] if height >= width: length = height else: length = width # position is must, because the bbs and images are augmented separately self.seq = iaa.Sequential([ iaa.PadToFixedSize(width=length, height=length, position=self.position) ]) # apply augment image_aug = self.seq.augment_image(np_img) bbs_aug = self.seq.augment_bounding_boxes(bbs_on_img).bounding_boxes gts = [] for bb in bbs_aug: gts.append([bb.x1, bb.y1, bb.x2, bb.y2]) gts = torch.from_numpy(np.array(gts)) return image_aug, (anno[0], gts)
def __call__(self, img, anno): gts = anno[1].numpy() np_img = np.asarray(img) # get BoundingBoxesOnImage bbs = [] for gt in gts: bbs.append(BoundingBox(x1=gt[0], y1=gt[1], x2=gt[2], y2=gt[3])) bbs_on_img = BoundingBoxesOnImage(bbs, shape=np_img.shape) # draw_img = bbs_on_img.draw_on_image(np_img, size=2) x = np.random.randint(-self.x, self.x) y = np.random.randint(-self.y, self.y) self.seq = iaa.Sequential( [iaa.Affine(translate_percent={ "x": x, "y": y })]) # apply augment image_aug = self.seq.augment_image(np_img) bbs_aug = self.seq.augment_bounding_boxes(bbs_on_img).bounding_boxes gts = [] for bb in bbs_aug: gts.append([bb.x1, bb.y1, bb.x2, bb.y2]) gts = torch.from_numpy(np.array(gts)) return image_aug, (anno[0], gts, anno[2])
def augment_transform(image, bbox, text, random_remove_box=0.15): image_h, image_w = image.shape[-2:] ty = random.uniform(-random_y_translation, random_y_translation) tx = random.uniform(-random_x_translation, random_x_translation) aug_bbs = [] for i in range(bbox.shape[0]): x1, y1, x2, y2 = bbox[i] x1, y1, x2, y2 = x1 * image_w, y1 * image_h, x2 * image_w, y2 * image_h aug_bbs.append(BoundingBox(x1=x1, y1=y1, x2=x2, y2=y2)) bbs = BoundingBoxesOnImage(aug_bbs, shape=image.shape) seq = iaa.Sequential([ iaa.Affine( cval=255, translate_px={ "x": int(tx * image.shape[1]), "y": int(ty * image.shape[0]) }, scale=(0.9, 1.1), ), iaa.Crop(percent=(0., 0., .3, 0.)) ]) image_aug, bbs_aug = seq(image=image, bounding_boxes=bbs) bbox_out = [] for bb_aug in bbs_aug: x1, y1, x2, y2 = bb_aug.x1, bb_aug.y1, bb_aug.x2, bb_aug.y2 x1, y1, x2, y2 = x1 / image_w, y1 / image_h, x2 / image_w, y2 / image_h bbox_out.append([x1, y1, x2, y2]) bbox_out = np.array(bbox_out) return transform(image_aug, bbox_out, text)
def Resize(it): """ Resizes images according to the resize dimensions image: (array) Image resize: (tuple of integers) New dimensions target: (Dictionary) Containing BBox, Area, Labels and Index Returns normalized_image, target """ image, target = it resize = res new_target = target.copy() bbs = BoundingBoxesOnImage([ BoundingBox(x1=new_target['boxes'][0].item(), y1=new_target['boxes'][1].item(), x2=new_target['boxes'][2].item(), y2=new_target['boxes'][3].item()) ], image.shape) img = ia.imresize_single_image(np.array(image), resize) new_bbs = bbs.on(img) bbox = torch.tensor( [new_bbs[0].x1, new_bbs[0].y1, new_bbs[0].x2, new_bbs[0].y2]) new_target['area'] = torch.tensor([ (new_bbs[0].x2 - new_bbs[0].x1) * (new_bbs[0].y2 - new_bbs[0].y1) ]) new_target['boxes'] = bbox.unsqueeze(0) return img, [new_target]
def boxes_numpy2imgaug(annotations, image_shape): boxes = [] for annot in annotations: x1, y1, x2, y2, label = annot box = BoundingBox(x1, y1, x2, y2, label) boxes.append(box) return BoundingBoxesOnImage(boxes, image_shape)
def load_labels_from_annotation(self, filename: str) -> list: path_to_file = os.path.join(self.annotation_directory, filename + ".xml") with open(path_to_file) as fd: annotation = xmltodict.parse(fd.read()) objects = annotation["annotation"]['object'] if type(objects) is not list: objects = [objects] labels = [] for obj in objects: box = obj['bndbox'] labels.append(BoundingBox( x1=box["xmin"], y1=box["ymin"], x2=box["xmax"], y2=box["ymax"], label=self.classes.index(obj["name"]) )) return labels
def apply_image_on_background(self): image_path = os.getcwd( ) + '/dataset_original/' + self.file_name + '.jpg' # load image img = PIL_Image.open(image_path, 'r').convert('RGBA') # scale image scale_factor = randint(30, 110) / 100 # scale_factor = 1 img = img.resize( (int(img.size[0] * scale_factor), int(img.size[1] * scale_factor)), 0) img_w, img_h = img.size # randomize position position = (randint(0, self.bg_w - img_w), randint(0, self.bg_h - img_h)) # position = (0, 0) # remove overlapping bounding boxes self.remove_intersecting_bounding_boxes( BoundingBox(position[0], position[1], position[0] + img_w, position[1] + img_h)) # apply left bounding box self.add_bounding_box_left(position, img.size) # apply right bounding box self.add_bounding_box_right(position, img.size) # save self.background.paste(img, position) self.background.save("image_temp.jpg")
def test_plot_all(orig, normalized, target, denormalize): # plot image, normalized images with boxes, and denormalized image fig = plt.figure() ax1 = fig.add_subplot(221) ax2 = fig.add_subplot(222) ax3 = fig.add_subplot(223) bbs = BoundingBoxesOnImage([ BoundingBox(x1=x[0], x2=x[2], y1=x[1], y2=x[3]) for x in target['boxes'] ], shape=normalized.shape) bbs_args = {'size': 2, 'color': [255, 0, 0]} image_bbs = bbs.draw_on_image(normalized.permute(1, 2, 0), **bbs_args) denormed = denormalize(normalized) denormed_bbs = bbs.draw_on_image(denormed.permute(1, 2, 0), **bbs_args) print(orig) print(image_bbs) print(denormed) ax1.set_title('Input') ax2.set_title('Normalized') ax3.set_title('Denormalized') ax1.imshow(orig.permute(1, 2, 0)) ax2.imshow(np.clip(image_bbs, 0, 1)) ax3.imshow(np.clip(denormed_bbs, 0, 1)) plt.show() plt.pause(0.1)
def __call__(self, img, anno): if np.random.random_sample() > self.probability: return img, anno gts = anno[1].numpy() np_img = np.asarray(img) # get BoundingBoxesOnImage bbs = [] for gt in gts: bbs.append(BoundingBox(x1=gt[0], y1=gt[1], x2=gt[2], y2=gt[3])) bbs_on_img = BoundingBoxesOnImage(bbs, shape=np_img.shape) # draw_img = bbs_on_img.draw_on_image(np_img, size=2) self.seq = iaa.Sequential([iaa.Flipud(1)]) # apply augment image_aug = self.seq.augment_image(np_img) bbs_aug = self.seq.augment_bounding_boxes(bbs_on_img).bounding_boxes gts = [] for bb in bbs_aug: gts.append([bb.x1, bb.y1, bb.x2, bb.y2]) gts = torch.from_numpy(np.array(gts)) return image_aug, (anno[0], gts, anno[2])
def check(): image = imageio.imread("img1.jpg") bbs = BoundingBoxesOnImage([ BoundingBox(x1=0, x2=0, y1=0, y2=0) ], shape=image.shape) for i in range(1): rotate=iaa.Affine(rotate=(-12, 12)) image_aug, bbs_aug = rotate(image=image, bounding_boxes=bbs) for j in range(1): r="AddToHue" aug = iaa.AddToBrightness((-30, 30)) image_aug, bbs_aug = aug(image=image_aug, bounding_boxes=bbs_aug) aug = iaa.AddToHue((-15, 15)) image_aug, bbs_aug = aug(image=image_aug, bounding_boxes=bbs_aug) # cv2.imwrite("a.jpg",image_aug) print(bbs_aug[0].x1) ia.imshow(bbs_aug.draw_on_image(image_aug, size=2))
def __call__(self, img, anno): labels = anno[0].numpy() gts = anno[1].numpy() np_img = np.asarray(img) # get BoundingBoxesOnImage bbs = [] for gt in gts: bbs.append(BoundingBox(x1=gt[0], y1=gt[1], x2=gt[2], y2=gt[3])) bbs_on_img = BoundingBoxesOnImage(bbs, shape=np_img.shape) # draw_img = bbs_on_img.draw_on_image(np_img, size=2) degree = np.random.randint(low=-self.degree, high=self.degree) self.seq = iaa.Sequential([ iaa.Affine(rotate=degree) ]) # apply augment image_aug = self.seq.augment_image(np_img) bbs_aug = self.seq.augment_bounding_boxes(bbs_on_img).bounding_boxes gts = [] for bb in bbs_aug: gts.append([bb.x1, bb.y1, bb.x2, bb.y2]) gts = torch.from_numpy(np.array(gts)) return image_aug, (anno[0], gts)
def add_bbs(self, bb1, bb2): x1 = bb1.x1 + bb2.x1 y1 = bb1.y1 + bb2.y1 x2 = bb1.x1 + bb2.x2 y2 = bb1.y1 + bb2.y2 return BoundingBox(x1=x1, y1=y1, x2=x2, y2=y2)
def transforms_visualization(img_root, csv_path, plot_num): """ :param img_root: root to the images (positive included) :param csv_path: path to the csv generated from the xml annotations :param plot_num: number of images to plot """ df = pd.read_csv(csv_path) img_names = sorted(list(set(df['img_name']))) for name in img_names[:plot_num]: objects = df.loc[df['img_name'] == name] image = cv2.imread(os.path.join(img_root, name)) bboxes_list = [] for index, row in objects.iterrows(): bboxes_list.append( BoundingBox(x1=row['xmin'], x2=row['xmax'], y1=row['ymin'], y2=row['ymax'])) bbs = BoundingBoxesOnImage(bboxes_list, shape=image.shape) img_aug, bbs_aug = transforms(image=image, bounding_boxes=bbs) image_before = draw_bbs(image, bbs) cv2.imshow('Before', image_before) cv2.waitKey(0) image_after = draw_bbs(img_aug, bbs_aug) cv2.imshow('After', np.array(image_after)) cv2.waitKey(0) cv2.destroyAllWindows()
def deep_data_aug(image, bb_list): import imgaug as ia import imgaug.augmenters as iaa from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage bbs = BoundingBoxesOnImage([ BoundingBox(x1=bb_list[0][0], y1=bb_list[0][1], x2=bb_list[1][0], y2=bb_list[1][1]), ], shape=image.shape) seq = iaa.Sometimes( 0.5, iaa.SomeOf( (0, None), [ iaa.Fliplr(0.3), iaa.Flipud(0.2), iaa.GaussianBlur(sigma=(0.0, 3.0)), iaa.Multiply( (1.2, 1.5)), # change brightness, doesn't affect BBs iaa.AdditiveGaussianNoise(scale=(0, 0.05 * 255)) ], random_order=True)) # Augment BBs and images. image_aug, bbs_aug = seq(image=image, bounding_boxes=bbs) formated_bbs_aug = [[ bbs_aug.bounding_boxes[0].x1, bbs_aug.bounding_boxes[0].y1, bbs_aug.bounding_boxes[0].x2, bbs_aug.bounding_boxes[0].y2 ]] return image_aug, formated_bbs_aug
def __call__(self, img, anno): gts = anno[1].numpy() np_img = np.asarray(img) scale = self.h / np_img.shape[0] # get BoundingBoxesOnImage bbs = [] for gt in gts: bbs.append(BoundingBox(x1=gt[0], y1=gt[1], x2=gt[2], y2=gt[3])) bbs_on_img = BoundingBoxesOnImage(bbs, shape=np_img.shape) # draw_img = bbs_on_img.draw_on_image(np_img, size=2) self.seq = iaa.Sequential( [iaa.Resize({ "height": self.h, "width": self.w })]) # apply augment image_aug = self.seq.augment_image(np_img) bbs_aug = self.seq.augment_bounding_boxes(bbs_on_img).bounding_boxes gts = [] for bb in bbs_aug: gts.append([bb.x1, bb.y1, bb.x2, bb.y2]) gts = torch.from_numpy(np.array(gts)) anno[2]["scale"] = scale return image_aug, (anno[0], gts, anno[2])