Hi I have an ImageSegmentation task where my input images come from disk (thus from_folder can be used, but images are in dcom format). Yet, segmentation masks (only two classes, i.e. area of interest and everything else) is inlined into the csv file.
Therefore, it looked to me like I need to override regular loading of images in order to support .dcm files, and also I need to override getting of labels to access a column of pandas dataframe. After some time of internet searches, I have come up with this:
fastai.vision.data.open_image = open_dcm_image
class SegLabelList(SegmentationLabelList):
def open(self, fn): return open_mask_image(fn)
class SegItemList(SegmentationItemList):
_label_cls = SegLabelList
This way I have my own functions open_dcm_image to load dcom images, and open_mask_image to load masks. Then I do this:
item_list = (SegItemList
.from_folder(dir_data_train, extensions=['.dcm'], recurse=True)
.split_by_rand_pct(valid_pct=0.2, seed=7)
.label_from_func(lambda x : str(x), classes=[0, 1]))
data = (item_list
.transform(get_transforms(), size=image_training_size, tfm_y=True)
.databunch(bs=batch_size)
.normalize(imagenet_stats))
data.show_batch(rows=3, figsize=(5, 5))
And everything seems to work. The batch is shown with some images having masks.
But, when I create a learner and run fit_one_cycle() I end up with the following error:
RuntimeError: Expected object of scalar type Long but got scalar type Float for argument #2 'target'
Probably, this is somehow connected to the fact that both my custom functions end with this line:
return Image(pil2tensor(x, dtype=np.float32).div_(255))
But, why then the network is expecting Long in the target?