def evaluating_main():
    preds_fnames = os.listdir(evaluating_config.preds_dir)
    label_fnames = os.listdir(evaluating_config.label_dir)
    n_class = len(NAME_MAP[evaluating_config.dataset_name])

    if evaluating_config.mode == "global":
        mat = np.zeros((n_class, n_class))

        for preds_fname, label_fname in tqdm(zip(preds_fnames, label_fnames)):
            print(preds_fname, label_fname)
            preds = load_image(os.path.join(evaluating_config.preds_dir, preds_fname), is_gray=True)
            h, w, _ = preds.shape
            label = load_image(os.path.join(evaluating_config.label_dir, label_fname), is_gray=True, target_size=(h, w))
            _mat = confusion_matrix(label.reshape(-1), preds.reshape(-1), labels=np.arange(n_class))
            mat = mat + _mat
        if evaluating_config.ignore_0:
            mat = mat[1:, 1:]
        avg_metric = compute_global_metrics(mat)

    elif evaluating_config.mode == "per_image":
        avg_metric = {"accuracies_per_class": np.zeros(n_class), "macro_accuracy": 0., "micro_accuracy": 0.,
         "precisions_per_class": np.zeros(n_class), "precision": 0.,
         "recalls_per_class": np.zeros(n_class), "recall": 0.,
         "f1s_pre_class": np.zeros(n_class), "f1": 0.,
         "ious_per_class": np.zeros(n_class), "miou": 0.}
        count = {"accuracies_per_class": np.zeros(n_class), "macro_accuracy": 0, "micro_accuracy": 0,
                 "precisions_per_class": np.zeros(n_class), "precision": 0,
                 "recalls_per_class": np.zeros(n_class), "recall": 0,
                 "f1s_pre_class": np.zeros(n_class), "f1": 0,
                 "ious_per_class": np.zeros(n_class), "miou": 0}
        for preds_fname, label_fname in zip(preds_fnames, label_fnames):
            preds = load_image(os.path.join(evaluating_config.preds_dir, preds_fname), is_gray=True)
            h, w, _ = preds.shape
            label = load_image(os.path.join(evaluating_config.label_dir, label_fname), is_gray=True, target_size=(h, w))

            metric = compute_metrics_per_image(label, preds, n_class)
            for key in metric:
                if not np.isscalar(metric[key]):
                    for i in range(len(metric[key])):
                        if not np.isnan(metric[key][i]):
                            avg_metric[key][i] = avg_metric[key][i] + metric[key][i]
                            count[key][i] += 1
                else:
                    avg_metric[key] = avg_metric[key] + metric[key]
                    count[key] += 1

        for key in avg_metric:
            if not np.isscalar(avg_metric[key]):
                for i in range(len(avg_metric[key])):
                    if not np.isnan(avg_metric[key][i]):
                        avg_metric[key][i] = avg_metric[key][i] / count[key][i]
            else:
                avg_metric[key] = avg_metric[key] / count[key]
    else:
        raise ValueError("Invalid 'mode': %s. Expected to be 'global' or 'per_image'!" % evaluating_config.mode)

    for key in avg_metric:
        print('{:^20s}{}'.format(key, avg_metric[key]))
    return avg_metric
Esempio n. 2
0
def convert_color_to_index(src_path,
                           color_mapping,
                           src_color_mode='rgb',
                           dst_path=None,
                           plot=False,
                           names=None):
    """ convert a colorful label image to a gray (1-channel) image
        (positive index from 1~n, 0 represents background.
        If there is no background classes, there will still be 0 values)
    :param src_path: string
        path of source label image, rgb/gray color mode
    :param dst_path: string
        path of destination label image, gray color mode, index from 0 to n (n is the number of non-background classes)
    :param src_color_mode: string, "rgb" or "gray", default "rgb"
        color mode of the source label image
    :param color_mapping: list or array, default None
        a list like [0, 255], [[1, 59, 3], [56, 0, 0]]
    :param plor: bool, default False
        whether to plot comparison
    :param names: list.

    :return: None
    """
    if color_mapping is None:
        raise ValueError('Invalid color mapping: None. Expected not None!')
    if src_color_mode == 'rgb':
        label_color = load_image(src_path, is_gray=False).astype(np.uint8)
    elif src_color_mode == 'gray':
        label_color = load_image(src_path, is_gray=True).astype(np.uint8)
    else:
        raise ValueError(
            'Invalid src_color_mode: {}. Expected "rgb" or "gray"!'.format(
                src_color_mode))

    label_index = color_to_index(label_color, color_mapping, to_sparse=True)
    if np.max(label_index) >= len(color_mapping):
        raise ValueError('max value is large than: {}:{}'.format(
            len(color_mapping) + 1, np.max(label_index)))

    if dst_path:
        save_to_image(label_index, dst_path)

    if plot:
        if names is None:
            names = ['class_{}'.format(i) for i in range(len(color_mapping))]
        if label_color.shape[-1] == 1:
            label_color = label_color[:, :, 0]
        plot_image_label(label_color,
                         label_index,
                         0,
                         len(color_mapping) - 1,
                         names,
                         overlay=False)
Esempio n. 3
0
def predict_per_image(model,
                      image_path,
                      image_width=256,
                      image_height=256,
                      to_prob=False,
                      plot=False,
                      dataset_name="voc"):
    """ predict per image, with no spatial reference
    """
    # load image
    image = load_image(image_path,
                       is_gray=False,
                       value_scale=1,
                       target_size=(image_height, image_width),
                       use_gdal=False)
    # predict
    pred = model.predict(np.expand_dims(image, axis=0))[0]

    if to_prob:
        return pred
    else:
        # save to labels and render with colours
        label = np.argmax(pred, axis=-1)
        if plot:
            plot_segmentation(image / 255.0, label, COLOR_MAP[dataset_name],
                              NAME_MAP[dataset_name])
        return label
Esempio n. 4
0
def convert_index_to_color(src_path,
                           color_mapping,
                           dst_path=None,
                           plot=False,
                           names=None):
    """ recover label index to colorful image
    :param src_path: string, path of source label image, gray colored.
    :param color_mapping: list. for example [0, 255], or [[52, 33, 24], [60, 95, 87]].
    :param dst_path: string, path of destination image, default None
    :param plot: bool, whether to plot.

    :return: None
    """
    if color_mapping is None:
        raise ValueError('Invalid color mapping: None. Expected not None!')
    label_index = load_image(src_path, is_gray=True).astype(np.uint8)[:, :, 0]
    label_color = index_to_color(label_array=label_index,
                                 color_mapping=color_mapping).astype(np.uint8)

    if dst_path is not None:
        save_to_image(label_color, dst_path)
    if plot:
        grid_spec = gridspec.GridSpec(1, 3, width_ratios=[6, 6, 1])

        plt.subplot(grid_spec[0])
        plt.imshow(label_index, vmin=0, vmax=len(color_mapping) - 1)
        plt.axis('off')
        plt.title('label index')

        plt.subplot(grid_spec[1])
        if label_color.ndim == 3:
            label_color = label_color / 255
        plt.imshow(label_color)
        plt.axis('off')
        plt.title('colorful label')

        ax = plt.subplot(grid_spec[2])
        if names is None:
            names = ['class_{}'.format(i) for i in range(len(color_mapping))]
        FULL_LABEL_MAP = np.arange(len(names)).reshape(len(names), 1)
        FULL_COLOR_MAP = index_to_color(FULL_LABEL_MAP, color_mapping)
        unique_labels = np.unique(label_index)
        plt.imshow(FULL_COLOR_MAP[unique_labels].astype(np.uint8),
                   interpolation='nearest')
        ax.yaxis.tick_right()
        plt.yticks(range(len(unique_labels)), np.asarray(names)[unique_labels])
        plt.xticks([], [])
        ax.tick_params(width=0.0)
        plt.grid('off')

        plt.show()
def generate_dataset_scan(image_paths,
                          label_paths,
                          dst_dir='./training',
                          stride=256,
                          img_h=256,
                          img_w=256,
                          label_is_gray=True,
                          use_gdal=False):
    # Assuming that the source images are remote sensing images, and the label images are images with 1 or 3 bands.
    # check source directories and create directories to store sample images and gts
    if not os.path.exists('{}/image'.format(dst_dir)):
        os.mkdir('{}/image'.format(dst_dir))
    if not os.path.exists('{}/label'.format(dst_dir)):
        os.mkdir('{}/label'.format(dst_dir))

    for image_path, label_path in zip(image_paths, label_paths):
        image = load_image(image_path, is_gray=False, use_gdal=use_gdal)
        label = load_image(label_path,
                           is_gray=label_is_gray,
                           use_gdal=use_gdal)
        image_height, image_width, _ = image.shape
        image_tag = os.path.basename(image_path).split('.')[0]
        print('%s: sampling from [%s]...' %
              (datetime.datetime.now().strftime('%y-%m-%d %H:%M:%S'),
               image_path))
        # if the source image/label is too small, pad it with zeros
        if image_height < img_h:
            image = np.pad(image,
                           ((0, img_h - image_height + 1), (0, 0), (0, 0)),
                           mode='constant',
                           constant_values=0)
            label = np.pad(label,
                           ((0, img_h - image_height + 1), (0, 0), (0, 0)),
                           mode='constant',
                           constant_values=0)
        if image_width < img_w:
            image = np.pad(image,
                           ((0, 0), (0, img_w - image_width + 1), (0, 0)),
                           mode='constant',
                           constant_values=0)
            label = np.pad(label,
                           ((0, 0), (0, img_w - image_width + 1), (0, 0)),
                           mode='constant',
                           constant_values=0)

        l_count = 1
        for _row in range(0, image_height, stride):
            for _col in range(0, image_width, stride):
                src_roi = image[_row:_row + img_h, _col:_col + img_w]
                label_roi = label[_row:_row + img_h, _col:_col + img_w]
                if src_roi.shape[0] != img_h or src_roi.shape[1] != img_w:
                    continue

                if src_roi.shape[0] != img_h or src_roi.shape[
                        1] != img_w or label_roi.shape[
                            0] != img_h or label_roi.shape[1] != img_w:
                    continue
                # save sample images
                if not use_gdal:
                    save_to_image(
                        src_roi.astype(np.uint8),
                        '{}/image/{}_{}.png'.format(dst_dir, image_tag,
                                                    l_count))
                    save_to_image(
                        label_roi.astype(np.uint8),
                        '{}/label/{}_{}.png'.format(dst_dir, image_tag,
                                                    l_count))
                else:
                    save_to_image_gdal(
                        src_roi,
                        '{}/image/{}_{}.tif'.format(dst_dir, image_tag,
                                                    l_count))
                    save_to_image_gdal(
                        label_roi,
                        '{}/label/{}_{}.tif'.format(dst_dir, image_tag,
                                                    l_count))
                l_count += 1
def generate_dataset_random(image_paths,
                            label_paths,
                            dst_dir='./training',
                            image_num_per_tile=10,
                            img_h=256,
                            img_w=256,
                            label_is_gray=True,
                            use_gdal=False):
    # Assuming that the source images are common images with 3 bands, and the label images are images with 1 or 3 bands.
    # check source directories and create directories to store sample images and gts
    if not os.path.exists('{}/image'.format(dst_dir)):
        os.mkdir('{}/image'.format(dst_dir))
    if not os.path.exists('{}/label'.format(dst_dir)):
        os.mkdir('{}/label'.format(dst_dir))

    # number of samples for each image
    for image_path, label_path in zip(image_paths, label_paths):
        image = load_image(image_path, is_gray=False, use_gdal=use_gdal)
        label = load_image(label_path,
                           is_gray=label_is_gray,
                           use_gdal=use_gdal)
        image_height, image_width, _ = image.shape
        image_tag = os.path.basename(image_path).split('.')[0]
        print('%s: sampling from [%s]...' %
              (datetime.datetime.now().strftime('%y-%m-%d %H:%M:%S'),
               image_path))
        # if the source image/label is too small, pad it with zeros
        if image_height < img_h:
            image = np.pad(image,
                           ((0, img_h - image_height + 1), (0, 0), (0, 0)),
                           mode='constant',
                           constant_values=0)
            label = np.pad(label,
                           ((0, img_h - image_height + 1), (0, 0), (0, 0)),
                           mode='constant',
                           constant_values=0)
        if image_width < img_w:
            image = np.pad(image,
                           ((0, 0), (0, img_w - image_width + 1), (0, 0)),
                           mode='constant',
                           constant_values=0)
            label = np.pad(label,
                           ((0, 0), (0, img_w - image_width + 1), (0, 0)),
                           mode='constant',
                           constant_values=0)

        l_count = 0
        while l_count < image_num_per_tile:
            #  randomly select a x and y for the upper left pixel
            x = np.random.randint(0, image.shape[1] - img_w + 1)
            y = np.random.randint(0, image.shape[0] - img_h + 1)
            src_roi = image[y:y + img_h, x:x + img_w]
            label_roi = label[y:y + img_h, x:x + img_w]

            if src_roi.shape[0] != img_h or src_roi.shape[
                    1] != img_w or label_roi.shape[
                        0] != img_h or label_roi.shape[1] != img_w:
                continue
            if not use_gdal:
                save_to_image(
                    src_roi.astype(np.uint8),
                    '{}/image/{}_{}.png'.format(dst_dir, image_tag, l_count))
                save_to_image(
                    label_roi.astype(np.uint8),
                    '{}/label/{}_{}.png'.format(dst_dir, image_tag, l_count))
            else:
                save_to_image_gdal(
                    src_roi,
                    '{}/image/{}_{}.tif'.format(dst_dir, image_tag, l_count))
                save_to_image_gdal(
                    label_roi,
                    '{}/label/{}_{}.tif'.format(dst_dir, image_tag, l_count))
            l_count += 1
Esempio n. 7
0
def generate_dataset_random(image_paths,
                            label_paths,
                            dst_dir="./training",
                            image_num_per_tile=10,
                            augmentations=[],
                            img_h=256,
                            img_w=256,
                            label_is_gray=True,
                            use_gdal=False):
    # Assuming that the source images are common images with 3 bands, and the label images are images with 1 or 3 bands.
    """
    create data sets for training and validation
    :param image_num_per_tile: sample number per tile
    :param mode: 'original' or 'augment'
    :return: None
    """
    # check source directories and create directories to store sample images and gts
    if not os.path.exists("{}/image".format(dst_dir)):
        os.mkdir("{}/image".format(dst_dir))
    if not os.path.exists("{}/label".format(dst_dir)):
        os.mkdir("{}/label".format(dst_dir))

    # number of samples for each image
    for image_path, label_path in zip(image_paths, label_paths):
        image = load_image(image_path, is_gray=False, use_gdal=use_gdal)
        label = load_image(label_path,
                           is_gray=label_is_gray,
                           use_gdal=use_gdal)
        image_height, image_width, _ = image.shape
        image_tag = os.path.basename(image_path).split(".")[0]
        print("%s: sampling from [%s] [%s]..." %
              (datetime.datetime.now().strftime("%y-%m-%d %H:%M:%S"),
               image_path, label_path))
        # if the source image/label is too small, pad it with zeros
        if image_height < img_h:
            image = np.pad(image,
                           ((0, img_h - image_height + 1), (0, 0), (0, 0)),
                           mode="constant",
                           constant_values=0)
            label = np.pad(label,
                           ((0, img_h - image_height + 1), (0, 0), (0, 0)),
                           mode="constant",
                           constant_values=0)
        if image_width < img_w:
            image = np.pad(image,
                           ((0, 0), (0, img_w - image_width + 1), (0, 0)),
                           mode="constant",
                           constant_values=0)
            label = np.pad(label,
                           ((0, 0), (0, img_w - image_width + 1), (0, 0)),
                           mode="constant",
                           constant_values=0)

        l_count = 0
        while l_count < image_num_per_tile:
            #  randomly select a x and y for the upper left pixel
            x = np.random.randint(0, image.shape[1] - img_w + 1)
            y = np.random.randint(0, image.shape[0] - img_h + 1)
            src_roi = image[y:y + img_h, x:x + img_w]
            label_roi = label[y:y + img_h, x:x + img_w]
            if src_roi.shape[0] != img_h or src_roi.shape[1] != img_w:
                continue
            # data augmentation
            if len(augmentations) > 0:
                src_roi, label_roi = data_augment(src_roi, label_roi,
                                                  augmentations, img_h, img_w)

            if src_roi.shape[0] != img_h or src_roi.shape[
                    1] != img_w or label_roi.shape[
                        0] != img_h or label_roi.shape[1] != img_w:
                continue
            if not use_gdal:
                save_to_image(
                    src_roi.astype(np.uint8),
                    '{}/image/{}_{}.png'.format(dst_dir, image_tag, l_count))
                save_to_image(
                    label_roi.astype(np.uint8),
                    '{}/label/{}_{}.png'.format(dst_dir, image_tag, l_count))
            else:
                save_to_image_gdal(
                    src_roi,
                    '{}/image/{}_{}.tif'.format(dst_dir, image_tag, l_count))
                save_to_image_gdal(
                    label_roi,
                    '{}/label/{}_{}.tif'.format(dst_dir, image_tag, l_count))
            l_count += 1
Esempio n. 8
0
def predict_stride(model,
                   image_path,
                   patch_height=256,
                   patch_width=256,
                   stride=None,
                   to_prob=False,
                   plot=False,
                   geo=False,
                   dataset_name="voc"):
    """ predict labels of a large image, usually for remote sensing HSR tiles
        or for images that size are not consistent with the required input size.
    :param model: Keras Model instance
    :param image_path: string, path of input image.
    :param patch_height: int, default 256.
    :param patch_width: int, default 256.
    :param stride: int, default None.
    :param to_prob: bool, whether to return probability.
    :param plot: bool, whether to plot.
    :param geo: bool, whether to load geo images.
    :param: bool, whether to plot.
    :param dataset_name: string.

    :return: probability or color of prediction.
    """
    # load the image
    image = load_image(image_path,
                       is_gray=False,
                       value_scale=1.0,
                       use_gdal=geo)

    h, w, c = image.shape
    if stride is None:
        stride = w // 4
    # padding with 0
    padding_h = int(np.ceil(h / stride) * stride)
    padding_w = int(np.ceil(w / stride) * stride)
    padding_img = np.zeros((padding_h, padding_w, c), dtype=np.float16)
    padding_img[:h, :w] = image

    colour_mapping = COLOR_MAP[dataset_name]
    n_class = len(colour_mapping)
    mask_probas = np.zeros((padding_h, padding_w, n_class), dtype=np.float16)
    mask_counts = np.zeros_like(mask_probas, dtype=np.uint8)
    for i in range(padding_h // stride):
        for j in range(padding_w // stride):
            _image = padding_img[i * stride:i * stride + patch_height,
                                 j * stride:j * stride + patch_width]
            _h, _w, _c = _image.shape
            if _h != patch_height or _w != patch_width:
                continue
            pred = model.predict(np.expand_dims(_image, axis=0), verbose=2)[0]

            mask_probas[i * stride:i * stride + patch_height,
                        j * stride:j * stride + patch_width] += pred
            mask_counts[i * stride:i * stride + patch_height,
                        j * stride:j * stride + patch_width] += 1

    mask_probas[:h, :w] = mask_probas[:h, :w] / mask_counts[:h, :w]
    if to_prob:
        return mask_probas[:h, :w]
    else:
        # save image labels
        label = np.argmax(mask_probas[:h, :w], axis=-1)
        if plot:
            plot_segmentation(image / 255.0, label, COLOR_MAP[dataset_name],
                              NAME_MAP[dataset_name])
        return label