Image size

Can Fastai v1 library handle rectangular images for training?

2 Likes

what you mean? Rectangular or not is not a matter of the fastai library is a matter of the model you use/develop. You certainly can use rectangular images. The only problem is when you want to have rectangular images of different sizes due to the need to do operations in batch.

@fredguth, I believe the get_data function only takes 1 positional argument which forces a square? I was wondering whether a new function takes 2 so one could pass height and width?

You can pass a tuple for size, not just an int. Of course all your images will be resized to it to be collated in batches.

1 Like

I have a dataset of all 50x900 (height x width) images. I tried sz=(50,900) but it gives me an error. Am I doing it wrong?

What error does it give you?

I did sz = (50,940) and I got TypeError: unsupported operand type(s) for /: ‘tuple’ and ‘int’

Getting the same error. Didn’t work for me either.

Anybody trained on rectangular images?

tfms = tfms_from_model(arch, sz_lr, tfm_y=TfmType.PIXEL,     aug_tfms=aug_tfms, sz_y=sz_hr)
datasets = ImageData.get_ds(MatchedFilesDataset, (trn_x,trn_y), (val_x,val_y), tfms, path=PATH_TRN)
md = ImageData(PATH, datasets, bs, num_workers=16, classes=None)

it seems one cannot create a dataset object without a tfms object and a tfms_from_model takes a mandatory second parameter of size, to which it crops the image making it square.

Any workaround to this?

Thanks,

The code you show above is for fastai 0.7.

any such example from newer version that would work with rectangular images?

i found this example but it also seem to restrict the image to a squared size of 32.

tfms = ([pad(padding=4), crop(size=32, row_pct=(0,1), col_pct=(0,1)),
    flip_lr(p=0.5)], [])
data = data_from_imagefolder('data/cifar10', valid='test',
    ds_tfms=tfms, tfms=cifar_norm)
learn = Learner(data, wrn_22(), metrics=accuracy).to_fp16()
learn.fit_one_cycle(25, wd=0.4)

If you look at the docs you’ll see that size can be a tuple.

thanks, will check that out.

I am trying to load my data. i have a images folder and a labels folder which contains npz files to be loaded via a function load_label which works fine.

labels_ls = list(map(load_label, train_listB[:5]))
tfms = get_transforms(do_flip=False)
data = ImageDataBunch.from_lists(dirpathB+"train_data/images/", train_f_listB[:5], labels=labels_ls, ds_tfms=tfms, size=(728,1024))

train_f_listB is a list containing training image file names. and dirpathB+“train_data/images/” contains those images.

the last line gives an error:
any idea whats wrong that i am doing here?

many thanks

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-46-82ae4630b209> in <module>()
  1 labels_ls = list(map(load_label, train_listB[:5]))
  2 tfms = get_transforms(do_flip=False)
----> 3 data = ImageDataBunch.from_lists(dirpathB+"train_data/images/", train_f_listB[:5], labels=labels_ls, ds_tfms=tfms, size=(728,1024))
  4 
  5 

/usr/local/lib/python3.6/dist-packages/fastai/vision/data.py in from_lists(cls, path, fnames, labels, valid_pct, **kwargs)
139     def from_lists(cls, path:PathOrStr, fnames:FilePathList, labels:Collection[str], valid_pct:float=0.2, **kwargs):
140         "Create from list of `fnames` in `path`."
--> 141         src = ImageItemList(fnames, path=path).random_split_by_pct(valid_pct).label_from_list(labels)
142         return cls.create_from_ll(src, **kwargs)
143 

/usr/local/lib/python3.6/dist-packages/fastai/data_block.py in _inner(*args, **kwargs)
391             self.valid = fv(*args, **kwargs)
392             self.__class__ = LabelLists
--> 393             self.process()
394             return self
395         return _inner

/usr/local/lib/python3.6/dist-packages/fastai/data_block.py in process(self)
438         "Process the inner datasets."
439         xp,yp = self.get_processors()
--> 440         for i,ds in enumerate(self.lists): ds.process(xp, yp, filter_missing_y=i==0)
441         return self
442 

/usr/local/lib/python3.6/dist-packages/fastai/data_block.py in process(self, xp, yp, filter_missing_y)
563     def process(self, xp=None, yp=None, filter_missing_y:bool=False):
564         "Launch the processing on `self.x` and `self.y` with `xp` and `yp`."
--> 565         self.y.process(yp)
566         if filter_missing_y and (getattr(self.x, 'filter_missing_y', None)):
567             filt = array([o is None for o in self.y])

/usr/local/lib/python3.6/dist-packages/fastai/data_block.py in process(self, processor)
 66         if processor is not None: self.processor = processor
 67         self.processor = listify(self.processor)
---> 68         for p in self.processor: p.process(self)
 69         return self
 70 

/usr/local/lib/python3.6/dist-packages/fastai/data_block.py in process(self, ds)
281 
282     def process(self, ds):
--> 283         if self.classes is None: self.create_classes(self.generate_classes(ds.items))
284         ds.classes = self.classes
285         ds.c2i = self.c2i

/usr/local/lib/python3.6/dist-packages/fastai/data_block.py in generate_classes(self, items)
325         "Generate classes from `items` by taking the sorted unique values."
326         classes = set()
--> 327         for c in items: classes = classes.union(set(c))
328         classes = list(classes)
329         classes.sort()

TypeError: unhashable type: 'numpy.ndarray'

well, it seems i need to create my own data set for this.

https://docs.fast.ai/data_block.html

Hi…
It is able to take the tuple. But it dsnt honors the tuple ,still does square resize

I see you filed an issue, will look at it later today.

I am currently working on https://www.kaggle.com/c/severstal-steel-defect-detection/ which comes with rectangular data. and I am able to load this properly using size parameter that takes a tuple.

data = ImageDataBunch.from_df(path/‘train_images’, df_cleaned, ds_tfms=tfms, size=(16, 128)).normalize(imagenet_stats)