When calling the
open_mask function, it requires mask image to have the pixels labeled as a mask be 255. This is due to the
_div(255) in the return statement of the
open_mask function, which means that any value below 255 would be smaller than 0. Followed by the
.data property of
ImageMask which returns a
long type which will round everything down to 0.
Is this intended or am I missing something? As most of the time when masks are saved they are labeled as 0 as background, and 1 as foreground. Moreover, what if there are multiple classes in the mask file, even if the mask is multiplied by 255 it still wouldn’t work.
We had to pick a convention, so for now, the
open_mask function expects masks with pixels are 0. or 1. in floats / 0 or 255 in ints. If you have another type of masks, you should either overwrite the function or save them to correspond to that type.
Note that for multiple labels, the mask passed to
ImageMask should have multiple channels.
Actually 255 for ints isn’t what I intended. I might have messed something up
Just pushed a change to
SegmentationDataset. It now expects masks with zeros, ones, twos etc… and if it’s zeros and 255s we can set div=True to make the divide happen.
It looks like the recent change
div=True has stopped my 255 masks from working. Is there a new way to tell the
SegmentationDataset that my binary masks are 255/0 or should I make them 1/0 at source?
I removed those parameters because you can now change the mask opener completely
So you should change the attribute
mask_opener of your
See here to do it on all your datasets at once with the data block API.
Edit: something now breaks in my custom loss function that i will have to track down, but that’s likely my problem.
I ran into a somewhat related issue. I didn’t know where to log it so I’ll just put it here. When calling
.save() on a mask which is a
ImageSegment object, there is no concrete implementation so it falls back to the
.save() implementation defined for the
Image object. This is problematic because in the
.save() method, the pixel values are all multiplied by a factor of 255 scaling the class values which for some cases will result in lost class values when subsequently calling
open_mask() on a saved mask.
I ran into this issue and thought I’d put it here but a quick fix would be to add an implementation of the
.save() method inside
ImageSegment which would do something like this without transforming the pixel values:
def save_mask(mask, fn:PathOrStr):
"Save the image to `fn`."
x = image2np(mask.data).astype(np.uint8)