Example #1
0
def examine_aug_images(filename: str, resized_images_df: pd.DataFrame,
                       augmented_images_df: pd.DataFrame):

    grouped_resized = resized_images_df.groupby('filename')
    grouped_augmented = augmented_images_df.groupby('filename')

    group_r_df = grouped_resized.get_group(filename)
    group_r_df = group_r_df.reset_index()
    group_r_df = group_r_df.drop(['index'], axis=1)
    bb_r_array = group_r_df.drop(['filename', 'width', 'height', 'class'],
                                 axis=1).values
    resized_img = imageio.imread('images_train/' + filename)
    bbs_r = BoundingBoxesOnImage.from_xyxy_array(bb_r_array,
                                                 shape=resized_img.shape)

    group_a_df = grouped_augmented.get_group('aug1_' + filename)
    group_a_df = group_a_df.reset_index()
    group_a_df = group_a_df.drop(['index'], axis=1)
    bb_a_array = group_a_df.drop(['filename', 'width', 'height', 'class'],
                                 axis=1).values
    augmented_img = imageio.imread('images_aug/' + 'aug1_' + filename)
    bbs_a = BoundingBoxesOnImage.from_xyxy_array(bb_a_array,
                                                 shape=augmented_img.shape)

    ia.imshow(
        np.hstack([
            bbs_r.draw_on_image(resized_img, size=2),
            bbs_a.draw_on_image(augmented_img, size=2)
        ]))

    # Examine random example
    filename = resized_images_df['filename'].unique()[np.random.randint(
        0, len(resized_images_df['filename'].unique()), 1)][0]
    examine_aug_images(filename, resized_images_df, augmented_images_df)
Example #2
0
def image_aug(df, images_path, aug_images_path, image_prefix, augmentor):
    aug_bbs_xy = pd.DataFrame(columns=[
        'filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax'
    ])
    grouped = df.groupby('filename')

    for filename in df['filename'].unique():
        group_df = grouped.get_group(filename)
        group_df = group_df.reset_index()
        group_df = group_df.drop(['index'], axis=1)
        image = imageio.imread(images_path + filename)
        bb_array = group_df.drop(['filename', 'width', 'height', 'class'],
                                 axis=1).values
        bbs = BoundingBoxesOnImage.from_xyxy_array(bb_array, shape=image.shape)
        image_aug, bbs_aug = augmentor(image=image, bounding_boxes=bbs)
        bbs_aug = bbs_aug.remove_out_of_image()
        bbs_aug = bbs_aug.clip_out_of_image()
        if re.findall('Image...', str(bbs_aug)) == ['Image([]']:
            pass
        else:
            imageio.imwrite(aug_images_path + image_prefix + filename,
                            image_aug)
            info_df = group_df.drop(['xmin', 'ymin', 'xmax', 'ymax'], axis=1)
            for index, _ in info_df.iterrows():
                info_df.at[index, 'width'] = image_aug.shape[1]
                info_df.at[index, 'height'] = image_aug.shape[0]
            info_df['filename'] = info_df['filename'].apply(
                lambda x: image_prefix + x)
            bbs_df = bbs_obj_to_df(bbs_aug)
            aug_df = pd.concat([info_df, bbs_df], axis=1)
            aug_bbs_xy = pd.concat([aug_bbs_xy, aug_df])

    aug_bbs_xy = aug_bbs_xy.reset_index()
    aug_bbs_xy = aug_bbs_xy.drop(['index'], axis=1)
    return aug_bbs_xy
Example #3
0
def draw_ground_truth_label(labelname, img):
    yolo_bb = np.loadtxt('Test/' + labelname)
    H, W = 640, 640
    if yolo_bb.size == 0: return yolo_bb
    imgaug_bb = np.zeros(yolo_bb.shape)
    if yolo_bb.ndim <= 1:
        class_id = yolo_bb[0]
        center_x, center_y, w, h = yolo_bb[1] * W, yolo_bb[2] * H, yolo_bb[
            3] * W, yolo_bb[4] * H
        x1 = center_x - w / 2
        y1 = center_y - h / 2
        x2 = center_x + w / 2
        y2 = center_y + h / 2
        imgaug_bb = np.array([class_id, x1, y1, x2, y2])
        imgaug_bb = imgaug_bb.reshape(1, -1)
    else:
        for n, bb in enumerate(yolo_bb):
            class_id = bb[0]
            center_x, center_y, w, h = bb[1] * W, bb[2] * H, bb[3] * W, bb[
                4] * H
            x1 = center_x - w / 2
            y1 = center_y - h / 2
            x2 = center_x + w / 2
            y2 = center_y + h / 2
            imgaug_bb[n] = np.array([class_id, x1, y1, x2, y2])

    gt = BoundingBoxesOnImage.from_xyxy_array(imgaug_bb[:, 1:],
                                              shape=img.shape)
    for n, bb in enumerate(gt):
        bb.label = imgaug_bb[n, 0].astype('int')

    return gt.draw_on_image(img, size=2, color=[0, 0, 255])
    def __init__(self,
                 df,
                 x_col,
                 x1_col,
                 y1_col,
                 x2_col,
                 y2_col,
                 a_col,
                 dim,
                 batch_size=32,
                 as_floats=False,
                 zero_mean=True,
                 shuffle=True,
                 augment=False,
                 flipV=0.5,
                 flipH=0.5,
                 rotate=0.5,
                 n_others=0,
                 p_other=0.5):

        # Make sure the df we get has default index
        df.reset_index(drop=True, inplace=True)

        self.augment = augment
        self.as_floats = as_floats
        self.zero_mean = zero_mean
        self.flipH = flipH
        self.flipV = flipV
        self.rotate = rotate
        self.n_others = n_others
        self.p_other = p_other
        self.batch_size = batch_size
        self.image_paths = df[x_col]
        self.angles = df[a_col]
        self.indices = df.index.tolist()

        print(df.shape, min(self.indices), max(self.indices), "LEN", len(self))

        self.shuffle = shuffle
        self.x_col = x_col
        self.dim = dim
        self.bbs = []
        self.resize = iaa.Resize(self.dim)

        for i in self.indices:
            bb = np.asarray(
                [df[x1_col][i], df[y1_col][i], df[x2_col][i], df[y2_col][i]])
            # Optionally expect and export relative values as bounding boxes:
            if as_floats:
                # bb = [c*self.dim for c in bb] # Convert from pixels to percentages
                if self.zero_mean:
                    bb = (bb + 1) / 2
                bb = bb * self.dim
            self.bbs.append(
                BoundingBoxesOnImage.from_xyxy_array(bb.reshape((1, 4)),
                                                     (self.dim, self.dim)))

        self.on_epoch_end()
Example #5
0
def get_bboxes(df, imgs_name, img_shape):
    bboxes_iaa = []
    for img_name in imgs_name:
        img_data = df[df.filename == img_name]
        bboxes = img_data.loc[:, ["xmin", "ymin", "xmax", "ymax"]].to_numpy()
        bboxes = BoundingBoxesOnImage.from_xyxy_array(bboxes, shape=img_shape)
        bboxes_iaa.append(bboxes)

    return bboxes_iaa
Example #6
0
def image_aug(df: pd.DataFrame, images_path: str, aug_images_path: str,
              image_prefix: str, augmentor):
    # create data frame which we're going to populate with augmented image info
    aug_bbs_xy = pd.DataFrame(columns=[
        'filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax'
    ])
    grouped = df.groupby('filename')

    for filename in df['filename'].unique():
        #   get separate data frame grouped by file name
        group_df = grouped.get_group(filename)
        group_df = group_df.reset_index()
        group_df = group_df.drop(['index'], axis=1)
        #   read the image
        image = imageio.imread(images_path + filename)
        #   get bounding boxes coordinates and write into array
        bb_array = group_df.drop(['filename', 'width', 'height', 'class'],
                                 axis=1).values
        #   pass the array of bounding boxes coordinates to the imgaug library
        bbs = BoundingBoxesOnImage.from_xyxy_array(bb_array, shape=image.shape)
        #   apply augmentation on image and on the bounding boxes
        image_aug, bbs_aug = augmentor(image=image, bounding_boxes=bbs)
        #   disregard bounding boxes which have fallen out of image pane
        bbs_aug = bbs_aug.remove_out_of_image()
        #   clip bounding boxes which are partially outside of image pane
        bbs_aug = bbs_aug.clip_out_of_image()

        #   don't perform any actions with the image if there are no bounding boxes left in it
        if re.findall('Image...', str(bbs_aug)) == ['Image([]']:
            pass

        #   otherwise continue
        else:
            #   write augmented image to a file
            imageio.imwrite(aug_images_path + image_prefix + filename,
                            image_aug)
            #   create a data frame with augmented values of image width and height
            info_df = group_df.drop(['xmin', 'ymin', 'xmax', 'ymax'], axis=1)
            for index, _ in info_df.iterrows():
                info_df.at[index, 'width'] = image_aug.shape[1]
                info_df.at[index, 'height'] = image_aug.shape[0]
            #   rename filenames by adding the predifined prefix
            info_df['filename'] = info_df['filename'].apply(
                lambda x: image_prefix + x)
            #   create a data frame with augmented bounding boxes coordinates using the function we created earlier
            bbs_df = bbs_obj_to_df(bbs_aug)
            #   concat all new augmented info into new data frame
            aug_df = pd.concat([info_df, bbs_df], axis=1)
            #   append rows to aug_bbs_xy data frame
            aug_bbs_xy = pd.concat([aug_bbs_xy, aug_df])

            # return dataframe with updated images and bounding boxes annotations
    aug_bbs_xy = aug_bbs_xy.reset_index()
    aug_bbs_xy = aug_bbs_xy.drop(['index'], axis=1)
    return aug_bbs_xy
Example #7
0
    def aug_with_imgaug(self,image, bboxes,aug = aug):
        if random.random() < 0.5:
            bbs = BoundingBoxesOnImage.from_xyxy_array(bboxes[:,:-1], shape= image.shape)
            image, bbs = aug(image=image, bounding_boxes=bbs)
            #disregard bounding boxes which have fallen out of image pane    
            bbs = bbs.remove_out_of_image()

            #clip bounding boxes which are partially outside of image pane
            bbs = bbs.clip_out_of_image()
            bboxes = np.column_stack((bbs.to_xyxy_array(),bboxes[:,-1][:bbs.to_xyxy_array().shape[0],np.newaxis])).astype(int)
            
        return image, bboxes
Example #8
0
def resize_imgaug(df, images_path, aug_images_path, image_prefix):
    # create data frame which we're going to populate with augmented image info
    aug_bbs_xy = pd.DataFrame(columns=[
        'filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax'
    ])
    grouped = df.groupby('filename')

    for filename in df['filename'].unique():
        #   Get separate data frame grouped by file name
        group_df = grouped.get_group(filename)
        group_df = group_df.reset_index()
        group_df = group_df.drop(['index'], axis=1)

        #   The only difference between if and elif statements below is the use of height_resize and width_resize augmentors
        #   deffined previously.

        #   If image height is greater than or equal to image width
        #   AND greater than 600px perform resizing augmentation shrinking image height to 600px.
        #  if group_df['height'].unique()[0] >= group_df['width'].unique()[0] and group_df['height'].unique()[0] <1024:
        #   read the image
        image = imageio.imread(images_path + filename)
        #   get bounding boxes coordinates and write into array
        bb_array = group_df.drop(['filename', 'width', 'height', 'class'],
                                 axis=1).values
        #   pass the array of bounding boxes coordinates to the imgaug library
        bbs = BoundingBoxesOnImage.from_xyxy_array(bb_array, shape=image.shape)
        #   apply augmentation on image and on the bounding boxes
        image_aug, bbs_aug = height_resize(image=image, bounding_boxes=bbs)
        #   write augmented image to a file
        imageio.imwrite(aug_images_path + image_prefix + filename, image_aug)
        #   create a data frame with augmented values of image width and height
        info_df = group_df.drop(['xmin', 'ymin', 'xmax', 'ymax'], axis=1)
        for index, _ in info_df.iterrows():
            info_df.at[index, 'width'] = image_aug.shape[1]
            info_df.at[index, 'height'] = image_aug.shape[0]
        #   rename filenames by adding the predifined prefix
        info_df['filename'] = info_df['filename'].apply(
            lambda x: image_prefix + x)
        #   create a data frame with augmented bounding boxes coordinates using the function we created earlier
        bbs_df = bbs_obj_to_df(bbs_aug)
        #   concat all new augmented info into new data frame
        aug_df = pd.concat([info_df, bbs_df], axis=1)
        #   append rows to aug_bbs_xy data frame
        aug_bbs_xy = pd.concat([aug_bbs_xy, aug_df])

    #   if image width is greater than image height
    #   AND greater than 600px perform resizing augmentation shrinking image width to 600px

    # return dataframe with updated images and bounding boxes annotations
    aug_bbs_xy = aug_bbs_xy.reset_index()
    aug_bbs_xy = aug_bbs_xy.drop(['index'], axis=1)
    return aug_bbs_xy
Example #9
0
def prepare_images(labels_raw_validate_path: str, images_raw_path: str,
                   images_validate_path: str, height: int, width: int):
    """
    :param labels_raw_validate_path: path of folder containing original xml labels for images
    :param images_raw_path: path of folder containing raw images
    :param images_validate_path: path of folder containing images that were labelled for training + later augmented
    images
    :param height: height of resized image
    :param width: width of resized image
    :return:
    labels_df = dataframe of original images xml labels
    resize_images_df = dataframe of resized images xml labels
    """

    # apply the function to convert all XML files in images/ folder into labels_validate.csv
    labels_df = xml_to_csv(os.path.dirname(labels_raw_validate_path))
    labels_df.to_csv('labels_validate.csv', index=False)
    print('Successfully converted xml to csv.')

    # Copy images that were labelled
    files = glob.glob(labels_raw_validate_path + '/*.xml')
    files = [re.findall(r'\d+', x)[0] for x in files]
    files = [images_raw_path + '/frame' + str(x) + '.jpg' for x in files]
    for file in files:
        shutil.copy(file, images_validate_path)  # file, destination

    # apply resizing augmentation to our images and write the updated images and bounding boxes annotations to the
    # DataFrame. we will not apply prefix to our files and will overwrite images in the same directory
    resized_images_validate_df = resize_imgaug(
        df=labels_df,
        images_path=images_validate_path,
        aug_images_path=images_validate_path,  # source & aug folders same
        image_prefix='',
        height=height,
        width=width)
    resized_images_validate_df.to_csv('resized_images_validate.csv',
                                      index=False)

    # visualise the resized valentin-petkov-loL9nnBK-fE-unsplash.jpg image with bounding boxes
    # to make sure our bounding boxes were resized correctly as well
    grouped = resized_images_validate_df.groupby('filename')
    group_df = grouped.get_group('frame243.jpg')
    group_df = group_df.reset_index()
    group_df = group_df.drop(['index'], axis=1)
    bb_array = group_df.drop(['filename', 'width', 'height', 'class'],
                             axis=1).values
    image = imageio.imread('images_validate/frame243.jpg')
    bbs = BoundingBoxesOnImage.from_xyxy_array(bb_array, shape=image.shape)
    ia.imshow(bbs.draw_on_image(image, size=2))

    return labels_df, resized_images_validate_df
Example #10
0
def resize_imgaug(df, images_path, aug_images_path, image_prefix):
    aug_bbs_xy = pd.DataFrame(columns=
                              ['filename', 'xmin', 'ymin', 'xmax', 'ymax', 'label']
                             )
    grouped = df.groupby('filename')    
    
    for filename in df['filename'].unique():
        group_df = grouped.get_group(filename)
        group_df = group_df.reset_index()
        group_df = group_df.drop(['index'], axis=1)

        image = imageio.imread(filename)
        height=image.shape[0]
        width=image.shape[1]
       
        fil=filename.split('/')
        fil1=fil[0]
        fil2=fil[1]

        if(group_df['label'].isnull().values.any()):
            image = imageio.imread(images_path+filename)
            image_aug = height_resize(image=image)
            imageio.imwrite(aug_images_path+'/'+fil1+'/'+image_prefix+fil2, image_aug)  

            group_df['xmin'] =''
            group_df['xmax'] =''
            group_df['ymin'] =''
            group_df['ymax'] =''
            info_df = group_df

            info_df['filename'] = info_df['filename'].apply(lambda x: aug_images_path+fil1+'/'+image_prefix+fil2)
            aug_bbs_xy = pd.concat([aug_bbs_xy, info_df])

           

        else:
            image = imageio.imread(images_path+filename)
            bb_array = group_df.drop(['filename', 'label'], axis=1).values
            bbs = BoundingBoxesOnImage.from_xyxy_array(bb_array, shape=image.shape)
            image_aug, bbs_aug = height_resize(image=image, bounding_boxes=bbs)
            imageio.imwrite(aug_images_path+'/'+fil1+'/'+image_prefix+fil2, image_aug)  
            info_df = group_df.drop(['xmin', 'ymin', 'xmax', 'ymax'], axis=1)   
            info_df['filename'] = info_df['filename'].apply(lambda x: aug_images_path+fil1+'/'+image_prefix+fil2)
            bbs_df = bbs_obj_to_df(bbs_aug)
            aug_df = pd.concat([info_df, bbs_df], axis=1)
            aug_bbs_xy = pd.concat([aug_bbs_xy, aug_df])

    aug_bbs_xy = aug_bbs_xy.reset_index()
    aug_bbs_xy = aug_bbs_xy.drop(['index'], axis=1)
    return aug_bbs_xy
Example #11
0
def analyze_pred_gt_image(data, i, threshold):
    filename, img, single_image_yolo_pred = read_ith_pred_result_yolo(
        data, i, threshold)
    single_image_imgaug_pred = convertYOLO2Other(single_image_yolo_pred)
    imgaug_bbox_single_img = BoundingBoxesOnImage.from_xyxy_array(
        single_image_imgaug_pred[:, 1:5], shape=img.shape)
    for n, bb in enumerate(imgaug_bbox_single_img):
        bb.label = single_image_imgaug_pred[n, 0].astype('int')

    print(filename)
    print(single_image_yolo_pred)
    print(imgaug_bbox_single_img)
    img_with_yolo = imgaug_bbox_single_img.draw_on_image(img, size=2)

    # draw the ground truth
    label_file = filename.split('.jpg')[0] + '.txt'
    img_with_gt = draw_ground_truth_label(label_file, img)

    ia.imshow(np.hstack([img_with_yolo, img_with_gt]))
    imageio.imwrite("sampleImages/pred_vs_gt_bbox_" + filename,
                    np.hstack([img_with_yolo, img_with_gt]))
Example #12
0
def augment_image(df, images_path, aug_dest_dir, image_suffix, augmentor):
    aug_bbs_xy = pandas.DataFrame(columns=[
        'filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax'
    ])
    grouped = df.groupby('filename')

    for filename in df['filename'].unique():
        group_df = grouped.get_group(filename)
        group_df = group_df.reset_index()
        group_df = group_df.drop(['index'], axis=1)
        image = imageio.imread("{}/{}".format(images_path, filename))
        bb_array = group_df.drop(['filename', 'width', 'height', 'class'],
                                 axis=1).values
        bbs = BoundingBoxesOnImage.from_xyxy_array(bb_array, shape=image.shape)
        image_aug, bbs_aug = augmentor(image=image, bounding_boxes=bbs)
        bbs_aug = bbs_aug.remove_out_of_image()
        bbs_aug = bbs_aug.clip_out_of_image()

        if re.findall('Image...', str(bbs_aug)) == ['Image([]']:
            pass
        else:
            filename_data = Path(filename)
            filename_final = "{}{}{}".format(filename_data.stem, image_suffix,
                                             filename_data.suffix)
            imageio.imwrite("{}/{}".format(aug_dest_dir, filename_final),
                            image_aug)
            info_df = group_df.drop(['xmin', 'ymin', 'xmax', 'ymax'], axis=1)
            for index, _ in info_df.iterrows():
                info_df.at[index, 'width'] = image_aug.shape[1]
                info_df.at[index, 'height'] = image_aug.shape[0]
            info_df['filename'] = filename_final
            bbs_df = bbs_obj_to_df(bbs_aug)
            aug_df = pandas.concat([info_df, bbs_df], axis=1)
            aug_bbs_xy = pandas.concat([aug_bbs_xy, aug_df])

    aug_bbs_xy = aug_bbs_xy.reset_index()
    aug_bbs_xy = aug_bbs_xy.drop(['index'], axis=1)
    return aug_bbs_xy
Example #13
0
def resize_imgaug(df: pd.DataFrame,
                  images_path: str,
                  aug_images_path: str,
                  image_prefix: str,
                  height: int,
                  width: int = None):

    # to resize the images we create two augmenters
    # one is used when the image height is more than 416px and the other when the width is more than 416px
    if width is None:
        width = 'keep-aspect-ratio'
    height_resize = iaa.Sequential(
        [iaa.Resize({
            "height": height,
            "width": width
        })])
    width_resize = iaa.Sequential(
        [iaa.Resize({
            "height": width,
            "width": height
        })])

    # create data frame which we're going to populate with augmented image info
    aug_bbs_xy = pd.DataFrame(columns=[
        'filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax'
    ])
    grouped = df.groupby('filename')

    for filename in df['filename'].unique():

        #   Get separate data frame grouped by file name
        group_df = grouped.get_group(filename)
        group_df = group_df.reset_index()
        group_df = group_df.drop(['index'], axis=1)

        # The only difference between if and elif statements below is the use of height_resize and width_resize
        # augmentors defined previously.

        #   If image height is greater than or equal to image width
        #   AND greater than 416px perform resizing augmentation shrinking image height to 416px.
        if group_df['height'].unique()[0] >= group_df['width'].unique(
        )[0] and group_df['height'].unique()[0] > 416:
            #   read the image
            image = imageio.imread(images_path + filename)
            #   get bounding boxes coordinates and write into array
            bb_array = group_df.drop(['filename', 'width', 'height', 'class'],
                                     axis=1).values
            #   pass the array of bounding boxes coordinates to the imgaug library
            bbs = BoundingBoxesOnImage.from_xyxy_array(bb_array,
                                                       shape=image.shape)
            #   apply augmentation on image and on the bounding boxes
            image_aug, bbs_aug = height_resize(image=image, bounding_boxes=bbs)
            #   write augmented image to a file
            imageio.imwrite(aug_images_path + image_prefix + filename,
                            image_aug)
            #   create a data frame with augmented values of image width and height
            info_df = group_df.drop(['xmin', 'ymin', 'xmax', 'ymax'], axis=1)
            for index, _ in info_df.iterrows():
                info_df.at[index, 'width'] = image_aug.shape[1]
                info_df.at[index, 'height'] = image_aug.shape[0]
            #   rename filenames by adding the predifined prefix
            info_df['filename'] = info_df['filename'].apply(
                lambda x: image_prefix + x)
            #   create a data frame with augmented bounding boxes coordinates using the function we created earlier
            bbs_df = bbs_obj_to_df(bbs_aug)
            #   concat all new augmented info into new data frame
            aug_df = pd.concat([info_df, bbs_df], axis=1)
            #   append rows to aug_bbs_xy data frame
            aug_bbs_xy = pd.concat([aug_bbs_xy, aug_df])

        #   if image width is greater than image height
        #   AND greater than 416px perform resizing augmentation shrinking image width to 416px
        elif group_df['width'].unique()[0] > group_df['height'].unique(
        )[0] and group_df['width'].unique()[0] > 416:
            #   read the image
            image = imageio.imread(images_path + filename)
            #   get bounding boxes coordinates and write into array
            bb_array = group_df.drop(['filename', 'width', 'height', 'class'],
                                     axis=1).values
            #   pass the array of bounding boxes coordinates to the imgaug library
            bbs = BoundingBoxesOnImage.from_xyxy_array(bb_array,
                                                       shape=image.shape)
            #   apply augmentation on image and on the bounding boxes
            image_aug, bbs_aug = width_resize(image=image, bounding_boxes=bbs)
            #   write augmented image to a file
            imageio.imwrite(aug_images_path + image_prefix + filename,
                            image_aug)
            #   create a data frame with augmented values of image width and height
            info_df = group_df.drop(['xmin', 'ymin', 'xmax', 'ymax'], axis=1)
            for index, _ in info_df.iterrows():
                info_df.at[index, 'width'] = image_aug.shape[1]
                info_df.at[index, 'height'] = image_aug.shape[0]
            #   rename filenames by adding the predifined prefix
            info_df['filename'] = info_df['filename'].apply(
                lambda x: image_prefix + x)
            #   create a data frame with augmented bounding boxes coordinates using the function we created earlier
            bbs_df = bbs_obj_to_df(bbs_aug)
            #   concat all new augmented info into new data frame
            aug_df = pd.concat([info_df, bbs_df], axis=1)
            #   append rows to aug_bbs_xy data frame
            aug_bbs_xy = pd.concat([aug_bbs_xy, aug_df])

        #     append image info without any changes if it's height and width are both less than 416px
        else:
            aug_bbs_xy = pd.concat([aug_bbs_xy, group_df])
    # return dataframe with updated images and bounding boxes annotations
    aug_bbs_xy = aug_bbs_xy.reset_index()
    aug_bbs_xy = aug_bbs_xy.drop(['index'], axis=1)

    return aug_bbs_xy
def get_inner_bbs(image_path, dst_img_dir, array_info, p_numbers):
    '''
    :param image_path: src img path
    :param dst_img_dir: img save path
    :param coor_array: label coor array
    :param p_numbers: Numbers of images to enhance
    :return: [(bbs_array, img_info),
            (bbs_array, img_info)]
    '''

    try:
        assert array_info.shape[1] == 5
        coor_array = array_info[:, :-1]
        cls_array = array_info[:, -1]

        image = Image.open(image_path)
        image = np.array(image)
        img_name = os.path.split(image_path)[-1].split(".")[0]
        bbs = BoundingBoxesOnImage.from_xyxy_array(coor_array,
                                                   shape=image.shape)
    except Exception as e:
        print(f"err:{e}")
        print(array_info.shape)
        print(image_path)
        return None

    # # Draw the original picture
    # image_before = draw_bbs(image, bbs, 100)
    # ia.imshow(image_before)

    # Image augmentation sequence
    seq = iaa.Sequential(
        [
            iaa.Fliplr(0.5),
            iaa.Crop(percent=(0, 0.1)),
            iaa.Sometimes(0.5, iaa.GaussianBlur(sigma=(0, 0.5))),
            # Strengthen or weaken the contrast in each image.
            iaa.LinearContrast((0.75, 1.5)),
            iaa.AdditiveGaussianNoise(
                loc=0, scale=(0.0, 0.05 * 255), per_channel=0.5),
            # change illumination
            iaa.Multiply((0.3, 1.2), per_channel=0.2),
            # affine transformation
            iaa.Affine(scale={
                "x": (0.8, 1.2),
                "y": (0.8, 1.2)
            },
                       translate_percent={
                           "x": (-0.2, 0.2),
                           "y": (-0.2, 0.2)
                       },
                       rotate=(-5, 5),
                       shear=(-8, 8))
        ],
        random_order=True)  # apply augmenters in random order

    res_list = []
    # gen img and coor
    try:
        for epoch in range(p_numbers):
            image_aug, bbs_aug = seq(image=image, bounding_boxes=bbs)
            # bbs_aug = bbs_aug.remove_out_of_image().clip_out_of_image()

            # # draw aug img and label
            image_after = bbs_aug.draw_on_image(image_aug,
                                                size=2,
                                                color=[0, 0, 255])
            ia.imshow(image_after)

            # save img
            h, w, c = image_aug.shape

            img_aug_name = rf'{dst_img_dir}/{img_name}_{epoch}.jpg'
            im = Image.fromarray(image_aug)

            im.save(img_aug_name)

            bbs_array = bbs_aug.to_xyxy_array()
            result_array = np.column_stack((bbs_array, cls_array))
            res_list.append([result_array, (img_aug_name, h, w, c)])
    except Exception as e:
        print(e)
        print(img_aug_name)
        return None
    # return coor and img info
    return res_list
def image_aug(df, images_path, aug_images_path, image_prefix, augmentor):
    aug_bbs_xy = pd.DataFrame(
        columns=['filename', 'xmin', 'ymin', 'xmax', 'ymax', 'label'])
    grouped = df.groupby(['label'])
    grouped2 = df.groupby(['filename'])

    for label in grouped.size().index:
        print(label)
        group_df = grouped.get_group(label)
        group_df = group_df.reset_index()
        group_df = group_df.drop(['index'], axis=1)
        counter = 0
        counter3 = 0
        counter2 = 0
        while (group_df['filename'].unique().size + counter) < 1000:
            if ((group_df['filename'].unique().size + counter) > 999):
                break

            for filename in group_df['filename'].unique():
                if ((group_df['filename'].unique().size + counter) > 999):
                    break

                group_df2 = grouped2.get_group(filename)
                group_df2 = group_df2.reset_index()
                group_df2 = group_df2.drop(['index'], axis=1)

                counter += 1
                yolo = str(counter)

                fil = filename.split('/')
                fil1 = fil[0]
                fil2 = fil[1]
                fil3 = fil[2]

                if (group_df['label'].isnull().values.any()):
                    image = imageio.imread(filename)
                    image_aug = augmentor(image=image)

                    yolo = str(counter)
                    imageio.imwrite(
                        aug_images_path + '/' + image_prefix + yolo + '_' +
                        fil3, image_aug)
                    group_df2['xmin'] = ''
                    group_df2['xmax'] = ''
                    group_df2['ymin'] = ''
                    group_df2['ymax'] = ''
                    info_df = group_df2

                    info_df['filename'] = info_df['filename'].apply(
                        lambda x: aug_images_path + fil1 + '/' + image_prefix +
                        fil2)
                    aug_bbs_xy = pd.concat([aug_bbs_xy, info_df])
                    counter2 += 1

                else:

                    image = imageio.imread(filename)
                    bb_array = group_df2.drop(['filename', 'label'],
                                              axis=1).values
                    bbs = BoundingBoxesOnImage.from_xyxy_array(
                        bb_array, shape=image.shape)
                    image_aug, bbs_aug = augmentor(image=image,
                                                   bounding_boxes=bbs)
                    bbs_aug = bbs_aug.remove_out_of_image()
                    bbs_aug = bbs_aug.clip_out_of_image()

                    if re.findall('Image...', str(bbs_aug)) == ['Image([]']:
                        pass

                    else:
                        imageio.imwrite(
                            aug_images_path + fil2 + '/' + image_prefix +
                            yolo + '_' + fil3, image_aug)
                        counter3 += 1

                        info_df = group_df2.drop(
                            ['xmin', 'ymin', 'xmax', 'ymax'], axis=1)

                        info_df['filename'] = info_df['filename'].apply(
                            lambda x: aug_images_path + fil2 + '/' +
                            image_prefix + yolo + '_' + fil3)

                        bbs_df = bbs_obj_to_df(bbs_aug)

                        aug_df = pd.concat([info_df, bbs_df], axis=1)

                        aug_bbs_xy = pd.concat([aug_bbs_xy, aug_df])

    aug_bbs_xy = aug_bbs_xy.reset_index()
    aug_bbs_xy = aug_bbs_xy.drop(['index'], axis=1)
    return aug_bbs_xy
Example #16
0
def transform(csv_input_path,
              src_dir,
              dest_dir,
              area_threshold,
              csv_output_path=None,
              num_transform=5,
              test_mode=False,
              keep_orig_img=False):

    df = pd.read_csv(csv_input_path)
    df_drop_duplicates = df.drop_duplicates()
    print(">>> Original df: {} objects".format(df.shape[0]))
    print(">>> Dropped-duplicates df: {} objects".format(
        df_drop_duplicates.shape[0]))
    df_out = pd.DataFrame(columns=df.columns)
    img_list = sorted(df.filename.unique())

    skip_gen_img = 0

    sequence = create_sequence()

    if test_mode:
        img_list = img_list[:30]
        print(">>> Testing with 30 images.")
    else:
        expected = (
            num_transform +
            1) * df.shape[0] if keep_orig_img else num_transform * df.shape[0]
        print('>>> Number of expected objects: {}'.format(expected))

    with tqdm(img_list, unit="imgs") as t:
        for img in t:
            t.set_postfix(skipped_gen_imgs=skip_gen_img)
            if not img.lower().endswith("jpg"):
                continue

            name, ext = os.path.splitext(img)

            img_data = df_drop_duplicates[df_drop_duplicates.filename == img]
            num_duplicates = int(df[df.filename == img].shape[0] /
                                 img_data.shape[0])
            img_shape = (img_data.iloc[0, 2], img_data.iloc[0, 1])
            img_area = img_shape[0] * img_shape[1]

            bboxes = np.asarray(img_data.iloc[:, 4:], dtype=np.int)
            bboxes_iaa = BoundingBoxesOnImage.from_xyxy_array(bboxes,
                                                              shape=img_shape)

            suffix = 0
            img_array = cv2.imread(os.path.join(src_dir, img))

            # If keeping original image and the bounding boxes satisfy the threshold condition.
            if keep_orig_img and all(
                    cal_bboxes_fraction(img_area, bboxes) >= area_threshold):
                df_out = df_out.append(img_data, ignore_index=True)
                cv2.imwrite(os.path.join(dest_dir, img), img_array)

            for _ in range(num_transform * num_duplicates):
                transformed_img, transformed_bboxes = sequence(
                    image=img_array, bounding_boxes=bboxes_iaa)

                for transformed_bbox in transformed_bboxes.bounding_boxes:
                    if not transformed_bbox.is_fully_within_image(
                            transformed_img):
                        skip_gen_img += 1
                        break

                else:
                    transformed_bboxes = transformed_bboxes.to_xyxy_array(
                        dtype=np.int)
                    if any(
                            cal_bboxes_fraction(img_area, transformed_bboxes) <
                            area_threshold):
                        skip_gen_img += 1
                        continue

                    transformed_name = name + "_{}".format(suffix) + ext
                    transformed_path = os.path.join(dest_dir, transformed_name)
                    # When the file exists
                    while os.path.isfile(transformed_path):
                        suffix += 1
                        transformed_name = name + "_{}".format(suffix) + ext
                        transformed_path = os.path.join(
                            dest_dir, transformed_name)

                    transformed_data = copy_data(img_data, transformed_name,
                                                 transformed_bboxes)
                    df_out = df_out.append(transformed_data, ignore_index=True)

                    cv2.imwrite(os.path.join(dest_dir, transformed_name),
                                transformed_img)
                    suffix += 1
    print('''
=================================
Total images processed: {}
Total images generated: {}
Total generated images skipped: {}
=================================

'''.format(len(img_list), len(os.listdir(dest_dir)), skip_gen_img))

    # Shuffle the DataFrame
    df_out = df_out.sample(frac=1.0).reset_index(drop=True)
    if csv_output_path is not None:
        df_out.to_csv(csv_output_path, index=False)
    return df
Example #17
0
    def up_sample_positives(self):
        def ia_format_bbox(bbox):
            return [bbox[0], bbox[1], bbox[0] + bbox[2], bbox[1] + bbox[3]]

        def reverse_ia_format_bbox(bbox):
            new_bbox = bbox
            new_bbox[2] = bbox[2] - bbox[0]
            new_bbox[3] = bbox[3] - bbox[1]
            return new_bbox

        augmented_annotations = {}

        augmentor = iaa.SomeOf(2, [
            iaa.Affine(scale=(0.5, 1.5)),
            iaa.Affine(rotate=(-60, 60)),
            iaa.Affine(translate_percent={
                "x": (-0.3, 0.3),
                "y": (-0.3, 0.3)
            }),
            iaa.Fliplr(1),
            iaa.Multiply((0.5, 1.5)),
            iaa.GaussianBlur(sigma=(1.0, 3.0)),
            iaa.AdditiveGaussianNoise(scale=(0.03 * 255, 0.05 * 255))
        ])

        positive_annotations = self.positive_annotations()
        for _, image_filename in enumerate(positive_annotations.keys()):
            metadata = positive_annotations[image_filename]
            bboxes = []
            for triplet in metadata:
                tomato = self.mapping[triplet["id"]]
                assert tomato
                bbox = triplet["box"]
                bboxes.append(ia_format_bbox(bbox))
            img_file_path = os.path.join(self.data_dir_path, image_filename)
            image = imageio.imread(img_file_path)
            ia_boxxes = BoundingBoxesOnImage.from_xyxy_array(np.array(bboxes),
                                                             shape=image.shape)

            for epoch in range(self.upsampling_factor):
                aug_img, aug_bboxes = augmentor(image=image,
                                                bounding_boxes=ia_boxxes)
                aug_bboxes = aug_bboxes.remove_out_of_image()
                aug_bboxes = aug_bboxes.clip_out_of_image()
                aug_bboxes = aug_bboxes.to_xyxy_array()
                if aug_bboxes.size == 0:
                    continue
                aug_bboxes = aug_bboxes.tolist()
                aug_bboxes = [
                    reverse_ia_format_bbox(aug_bbox) for aug_bbox in aug_bboxes
                ]

                aug_img_filename = '{}_aug_{}.jpg'.format(
                    os.path.splitext(image_filename)[0], epoch)
                aug_img_filepath = os.path.join(self.formated_data_dir_path,
                                                'JPEGImages', aug_img_filename)
                imageio.imwrite(aug_img_filepath, aug_img)
                augmented_annotations.setdefault(aug_img_filename, [])
                for aug_bbox in aug_bboxes:
                    augmented_annotations[aug_img_filename].append({
                        "box":
                        aug_bbox,
                        "id":
                        "9f2c42629209f86b2d5fbe152eb54803_lab",
                        "is_background":
                        False
                    })

        return augmented_annotations
     t.append(coords[i].split(','))
 t = np.array(t).astype(np.uint32)
 
 coords = t[:,0:4]
 class_idx = t[:,-1]
 class_det = np.take(classes, class_idx)
 
 #%
 
 #ia.seed(1)
 # for giving one box
 # bbs = BoundingBoxesOnImage([
 #     BoundingBox(x1=coords[0], x2=coords[2], y1=coords[1], y2=coords[3])
 # ], shape=img.shape)
 
 bbs = BoundingBoxesOnImage.from_xyxy_array(coords, shape=img.shape)
 for i in range(len(bbs)):
     bbs[i].label = class_det[i]
     
 #ia.imshow(bbs.draw_on_image(img, color=[255, 0, 0], size=10))
 '''
 Start applying augmentations
 '''
 num = np.random.randint(1, 100)
 if (num % 2) == 0:
     image_aug, bbs_aug = seq_1.augment(image=img, bounding_boxes=bbs)
 elif (num % 2) != 0:
     image_aug, bbs_aug = seq_2.augment(image=img, bounding_boxes=bbs)
 #   disregard bounding boxes which have fallen out of image pane   
 bbs_aug = bbs_aug.remove_out_of_image()
 #   clip bounding boxes which are partially outside of image pane
Example #19
0
def normalize_bounding_boxes(inputs, shapes=None):
    # TODO get rid of this deferred import
    from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage

    shapes = _preprocess_shapes(shapes)
    ntype = estimate_bounding_boxes_norm_type(inputs)
    _assert_exactly_n_shapes_partial = functools.partial(
        _assert_exactly_n_shapes,
        from_ntype=ntype,
        to_ntype="List[BoundingBoxesOnImage]",
        shapes=shapes)

    if ntype == "None":
        return None
    elif ntype in ["array[float]", "array[int]", "array[uint]"]:
        _assert_single_array_ndim(inputs, 3, "(N,B,4)", "BoundingBoxesOnImage")
        _assert_single_array_last_dim_exactly(inputs, 4,
                                              "BoundingBoxesOnImage")
        _assert_exactly_n_shapes_partial(n=len(inputs))
        return [
            BoundingBoxesOnImage.from_xyxy_array(attr_i, shape=shape)
            for attr_i, shape in zip(inputs, shapes)
        ]
    elif ntype == "tuple[number,size=4]":
        _assert_exactly_n_shapes_partial(n=1)
        return [
            BoundingBoxesOnImage([
                BoundingBox(
                    x1=inputs[0], y1=inputs[1], x2=inputs[2], y2=inputs[3])
            ],
                                 shape=shapes[0])
        ]
    elif ntype == "BoundingBox":
        _assert_exactly_n_shapes_partial(n=1)
        return [BoundingBoxesOnImage([inputs], shape=shapes[0])]
    elif ntype == "BoundingBoxesOnImage":
        return [inputs]
    elif ntype == "iterable[empty]":
        return None
    elif ntype in [
            "iterable-array[float]", "iterable-array[int]",
            "iterable-array[uint]"
    ]:
        _assert_many_arrays_ndim(inputs, 2, "(B,4)", "BoundingBoxesOnImage")
        _assert_many_arrays_last_dim_exactly(inputs, 4, "BoundingBoxesOnImage")
        _assert_exactly_n_shapes_partial(n=len(inputs))
        return [
            BoundingBoxesOnImage.from_xyxy_array(attr_i, shape=shape)
            for attr_i, shape in zip(inputs, shapes)
        ]
    elif ntype == "iterable-tuple[number,size=4]":
        _assert_exactly_n_shapes_partial(n=1)
        return [
            BoundingBoxesOnImage([
                BoundingBox(x1=x1, y1=y1, x2=x2, y2=y2)
                for x1, y1, x2, y2 in inputs
            ],
                                 shape=shapes[0])
        ]
    elif ntype == "iterable-BoundingBox":
        _assert_exactly_n_shapes_partial(n=1)
        return [BoundingBoxesOnImage(inputs, shape=shapes[0])]
    elif ntype == "iterable-BoundingBoxesOnImage":
        return inputs
    elif ntype == "iterable-iterable[empty]":
        return None
    elif ntype == "iterable-iterable-tuple[number,size=4]":
        _assert_exactly_n_shapes_partial(n=len(inputs))
        return [
            BoundingBoxesOnImage.from_xyxy_array(np.array(attr_i,
                                                          dtype=np.float32),
                                                 shape=shape)
            for attr_i, shape in zip(inputs, shapes)
        ]
    else:
        assert ntype == "iterable-iterable-BoundingBox", (
            "Got unknown normalization type '%s'." % (ntype, ))
        _assert_exactly_n_shapes_partial(n=len(inputs))
        return [
            BoundingBoxesOnImage(attr_i, shape=shape)
            for attr_i, shape in zip(inputs, shapes)
        ]
Example #20
0
def normalize_bounding_boxes(inputs, shapes=None):
    # TODO get rid of this deferred import
    from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage

    shapes = _preprocess_shapes(shapes)
    ntype = estimate_bounding_boxes_norm_type(inputs)
    _assert_exactly_n_shapes_partial = functools.partial(
        _assert_exactly_n_shapes,
        from_ntype=ntype, to_ntype="List[BoundingBoxesOnImage]",
        shapes=shapes)

    if ntype == "None":
        return None
    elif ntype in ["array[float]", "array[int]", "array[uint]"]:
        _assert_single_array_ndim(inputs, 3, "(N,B,4)", "BoundingBoxesOnImage")
        _assert_single_array_last_dim_exactly(inputs, 4, "BoundingBoxesOnImage")
        _assert_exactly_n_shapes_partial(n=len(inputs))
        return [
            BoundingBoxesOnImage.from_xyxy_array(attr_i, shape=shape)
            for attr_i, shape
            in zip(inputs, shapes)
        ]
    elif ntype == "tuple[number,size=4]":
        _assert_exactly_n_shapes_partial(n=1)
        return [
            BoundingBoxesOnImage(
                [BoundingBox(
                    x1=inputs[0], y1=inputs[1],
                    x2=inputs[2], y2=inputs[3])],
                shape=shapes[0])
        ]
    elif ntype == "BoundingBox":
        _assert_exactly_n_shapes_partial(n=1)
        return [BoundingBoxesOnImage([inputs], shape=shapes[0])]
    elif ntype == "BoundingBoxesOnImage":
        return [inputs]
    elif ntype == "iterable[empty]":
        return None
    elif ntype in ["iterable-array[float]",
                   "iterable-array[int]",
                   "iterable-array[uint]"]:
        _assert_many_arrays_ndim(inputs, 2, "(B,4)", "BoundingBoxesOnImage")
        _assert_many_arrays_last_dim_exactly(inputs, 4, "BoundingBoxesOnImage")
        _assert_exactly_n_shapes_partial(n=len(inputs))
        return [
            BoundingBoxesOnImage.from_xyxy_array(attr_i, shape=shape)
            for attr_i, shape
            in zip(inputs, shapes)
        ]
    elif ntype == "iterable-tuple[number,size=4]":
        _assert_exactly_n_shapes_partial(n=1)
        return [
            BoundingBoxesOnImage(
                [BoundingBox(x1=x1, y1=y1, x2=x2, y2=y2)
                 for x1, y1, x2, y2 in inputs],
                shape=shapes[0])
        ]
    elif ntype == "iterable-BoundingBox":
        _assert_exactly_n_shapes_partial(n=1)
        return [BoundingBoxesOnImage(inputs, shape=shapes[0])]
    elif ntype == "iterable-BoundingBoxesOnImage":
        return inputs
    elif ntype == "iterable-iterable[empty]":
        return None
    elif ntype == "iterable-iterable-tuple[number,size=4]":
        _assert_exactly_n_shapes_partial(n=len(inputs))
        return [
            BoundingBoxesOnImage.from_xyxy_array(
                np.array(attr_i, dtype=np.float32),
                shape=shape)
            for attr_i, shape
            in zip(inputs, shapes)
        ]
    else:
        assert ntype == "iterable-iterable-BoundingBox", (
            "Got unknown normalization type '%s'." % (ntype,))
        _assert_exactly_n_shapes_partial(n=len(inputs))
        return [BoundingBoxesOnImage(attr_i, shape=shape)
                for attr_i, shape
                in zip(inputs, shapes)]