Skip to content
This repository has been archived by the owner on Nov 16, 2023. It is now read-only.

PR to fix #342 #347

Merged
merged 22 commits into from
Jun 9, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions cv_lib/cv_lib/event_handlers/tensorboard_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ def _transform_image(output_tensor):
return torchvision.utils.make_grid(output_tensor, normalize=True, scale_each=True)


def _transform_pred(output_tensor):
def _transform_pred(output_tensor, n_classes):
output_tensor = output_tensor.squeeze().cpu().numpy()
decoded = decode_segmap(output_tensor)
decoded = decode_segmap(output_tensor, n_classes)
return torchvision.utils.make_grid(np_to_tb(decoded), normalize=False, scale_each=False)


Expand Down Expand Up @@ -111,5 +111,5 @@ def log_results(engine, evaluator, summary_writer, n_classes, stage):
y_pred[mask == 255] = 255

summary_writer.add_image(f"{stage}/Image", _transform_image(image), epoch)
summary_writer.add_image(f"{stage}/Mask", _transform_pred(mask), epoch)
summary_writer.add_image(f"{stage}/Pred", _transform_pred(y_pred), epoch)
summary_writer.add_image(f"{stage}/Mask", _transform_pred(mask, n_classes), epoch)
summary_writer.add_image(f"{stage}/Pred", _transform_pred(y_pred, n_classes), epoch)
21 changes: 12 additions & 9 deletions cv_lib/cv_lib/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@
from matplotlib import pyplot as plt


def normalize(array):
def normalize(array, MIN, MAX):
"""
Normalizes a segmentation mask array to be in [0,1] range
for use with PIL.Image
Normalizes a segmentation image array by the global range of the data,
MIN and MAX, for use with PIL.Image
"""
min = array.min()
return (array - min) / (array.max() - min)

den = MAX - MIN
if den==0:
den += np.finfo(float).eps
return (array - MIN) / den


def mask_to_disk(mask, fname, n_classes, cmap_name="rainbow"):
Expand All @@ -30,15 +33,15 @@ def mask_to_disk(mask, fname, n_classes, cmap_name="rainbow"):
Image.fromarray(cmap(mask / n_classes, bytes=True)).save(fname)


def image_to_disk(mask, fname, cmap_name="seismic"):
def image_to_disk(image, fname, MIN, MAX, cmap_name="seismic"):
"""
write segmentation image to disk using a particular colormap
"""
cmap = plt.get_cmap(cmap_name)
Image.fromarray(cmap(normalize(mask), bytes=True)).save(fname)
Image.fromarray(cmap(normalize(image, MIN, MAX), bytes=True)).save(fname)


def decode_segmap(label_mask, colormap_name="rainbow"):
def decode_segmap(label_mask, n_classes, colormap_name="rainbow"):
"""
Decode segmentation class labels into a colour image
Args:
Expand All @@ -51,7 +54,7 @@ def decode_segmap(label_mask, colormap_name="rainbow"):
cmap = plt.get_cmap(colormap_name)
# loop over the batch
for i in range(label_mask.shape[0]):
im = Image.fromarray(cmap(normalize(label_mask[i, :, :]), bytes=True)).convert("RGB")
im = Image.fromarray(cmap((label_mask[i, :, :] / n_classes), bytes=True)).convert("RGB")
out[i, :, :, :] = np.array(im).swapaxes(0, 2).swapaxes(1, 2)

return out
Expand Down
7 changes: 4 additions & 3 deletions experiments/interpretation/dutchf3_patch/local/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ def _patch_label_2d(
):
"""Processes a whole section
"""


img = torch.squeeze(img)
h, w = img.shape[-2], img.shape[-1] # height and width

Expand Down Expand Up @@ -234,14 +236,14 @@ def _patch_label_2d(
path_prefix = f"{outdir}/{batch_indexes[i][0]}_{batch_indexes[i][1]}"
model_output = model_output.detach().cpu()
# save image:
image_to_disk(np.array(batch[i, 0, :, :]), path_prefix + "_img.png")
image_to_disk(np.array(batch[i, 0, :, :]), path_prefix + "_img.png", float(img.min()), float(img.max()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to use the max and min values here from the config file?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you mean now, or in the next attempt to address the "global MIN and MAX" next sprint? Currently we don't have MIN and MAX defined in the cofing, I reverted those changes!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay that makes sense.. sorry if I misunderstood.

# dump model prediction:
mask_to_disk(model_output[i, :, :, :].argmax(dim=0).numpy(), path_prefix + "_pred.png", num_classes)
# dump model confidence values
for nclass in range(num_classes):
image_to_disk(
model_output[i, nclass, :, :].numpy(), path_prefix + f"_class_{nclass}_conf.png",
)
model_output[i, nclass, :, :].numpy().min(), model_output[i, nclass, :, :].numpy().max())

# crop the output_p in the middle
output = output_p[:, :, ps:-ps, ps:-ps]
Expand Down Expand Up @@ -288,7 +290,6 @@ def _evaluate_split(
for i, (images, labels) in enumerate(test_loader):
logger.info(f"split: {split}, section: {i}")
total_iteration = total_iteration + 1

outputs = _patch_label_2d(
model,
images,
Expand Down
20 changes: 10 additions & 10 deletions interpretation/deepseismic_interpretation/dutchf3/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def __getitem__(self, index):
outdir = f"debug/sectionLoader_{self.split}_raw"
generate_path(outdir)
path_prefix = f"{outdir}/index_{index}_section_{section_name}"
image_to_disk(im, path_prefix + "_img.png")
image_to_disk(im, path_prefix + "_img.png", self.seismic.min(), self.seismic.max())
mask_to_disk(lbl, path_prefix + "_lbl.png", self.n_classes)

if self.augmentations is not None:
Expand All @@ -169,7 +169,7 @@ def __getitem__(self, index):
outdir = f"debug/sectionLoader_{self.split}_{'aug' if self.augmentations is not None else 'noaug'}"
generate_path(outdir)
path_prefix = f"{outdir}/index_{index}_section_{section_name}"
image_to_disk(np.array(im[0]), path_prefix + "_img.png")
image_to_disk(np.array(im[0]), path_prefix + "_img.png", self.seismic.min(), self.seismic.max())
mask_to_disk(np.array(lbl[0]), path_prefix + "_lbl.png", self.n_classes)

return im, lbl
Expand Down Expand Up @@ -411,7 +411,7 @@ def __getitem__(self, index):
generate_path(outdir)
# this needs to take the first dimension of image (no depth) but lbl only has 1 dim
path_prefix = f"{outdir}/index_{index}_section_{section_name}"
image_to_disk(im[0, :, :], path_prefix + "_img.png")
image_to_disk(im[0, :, :], path_prefix + "_img.png", self.seismic.min(), self.seismic.max())
mask_to_disk(lbl, path_prefix + "_lbl.png", self.n_classes)

if self.augmentations is not None:
Expand All @@ -430,7 +430,7 @@ def __getitem__(self, index):
)
generate_path(outdir)
path_prefix = f"{outdir}/index_{index}_section_{section_name}"
image_to_disk(np.array(im[0, :, :]), path_prefix + "_img.png")
image_to_disk(np.array(im[0, :, :]), path_prefix + "_img.png", self.seismic.min(), self.seismic.max())
mask_to_disk(np.array(lbl[0, :, :]), path_prefix + "_lbl.png", self.n_classes)

return im, lbl
Expand Down Expand Up @@ -500,7 +500,7 @@ def __getitem__(self, index):
outdir = f"debug/patchLoader_{self.split}_raw"
generate_path(outdir)
path_prefix = f"{outdir}/index_{index}_section_{patch_name}"
image_to_disk(im, path_prefix + "_img.png")
image_to_disk(im, path_prefix + "_img.png", self.seismic.min(), self.seismic.max())
mask_to_disk(lbl, path_prefix + "_lbl.png", self.n_classes)

if self.augmentations is not None:
Expand All @@ -512,7 +512,7 @@ def __getitem__(self, index):
outdir = f"patchLoader_{self.split}_{'aug' if self.augmentations is not None else 'noaug'}"
generate_path(outdir)
path_prefix = f"{outdir}/{index}"
image_to_disk(im, path_prefix + "_img.png")
image_to_disk(im, path_prefix + "_img.png", self.seismic.min(), self.seismic.max())
mask_to_disk(lbl, path_prefix + "_lbl.png", self.n_classes)

if self.is_transform:
Expand All @@ -523,7 +523,7 @@ def __getitem__(self, index):
outdir = f"debug/patchLoader_{self.split}_{'aug' if self.augmentations is not None else 'noaug'}"
generate_path(outdir)
path_prefix = f"{outdir}/index_{index}_section_{patch_name}"
image_to_disk(np.array(im[0, :, :]), path_prefix + "_img.png")
image_to_disk(np.array(im[0, :, :]), path_prefix + "_img.png", self.seismic.min(), self.seismic.max())
mask_to_disk(np.array(lbl[0, :, :]), path_prefix + "_lbl.png", self.n_classes)

return im, lbl
Expand Down Expand Up @@ -769,7 +769,7 @@ def __getitem__(self, index):
outdir = f"debug/patchLoaderWithSectionDepth_{self.split}_raw"
generate_path(outdir)
path_prefix = f"{outdir}/index_{index}_section_{patch_name}"
image_to_disk(im[0, :, :], path_prefix + "_img.png")
image_to_disk(im[0, :, :], path_prefix + "_img.png", self.seismic.min(), self.seismic.max())
mask_to_disk(lbl, path_prefix + "_lbl.png", self.n_classes)

if self.augmentations is not None:
Expand All @@ -783,7 +783,7 @@ def __getitem__(self, index):
outdir = f"patchLoaderWithSectionDepth_{self.split}_{'aug' if self.augmentations is not None else 'noaug'}"
generate_path(outdir)
path_prefix = f"{outdir}/{index}"
image_to_disk(im[0, :, :], path_prefix + "_img.png")
image_to_disk(im[0, :, :], path_prefix + "_img.png", self.seismic.min(), self.seismic.max())
mask_to_disk(lbl, path_prefix + "_lbl.png", self.n_classes)

if self.is_transform:
Expand All @@ -796,7 +796,7 @@ def __getitem__(self, index):
)
generate_path(outdir)
path_prefix = f"{outdir}/index_{index}_section_{patch_name}"
image_to_disk(np.array(im[0, :, :]), path_prefix + "_img.png")
image_to_disk(np.array(im[0, :, :]), path_prefix + "_img.png", self.seismic.min(), self.seismic.max())
mask_to_disk(np.array(lbl[0, :, :]), path_prefix + "_lbl.png", self.n_classes)

return im, lbl
Expand Down