I’d like to apply a custom transformation to image data and train a network to undo it. I plan to use a given image as its own output, and apply my transformation on the input side.
One ugly way to implement this would be to subclass ImageItemList
for the input and override .get
, applying my transformation to Image.data
before returning it. I’d rather learn to do this kind of thing the right way.
It seems easy enough to make a function into a transform (mytfm = Transform(func)
), but now how does the transform get in the queue? I tried calling get_transforms
, appending my transform to each list, and then passing those lists to an ImagedataBunch
instantiation method (from_folder
), but .apply_tfms(mytfm)
fails whenever I try to work with a datapoint, due to the expectation that mytfm
has a .tfm
attribute, which suggests im.apply_tfms
expects a RandTransform
or some other similar wrapper as input (even though the argument tfms
is typed as TfmList
which includes callables).
I also tried calling DataBunch.add_tfm
with the same result – it wants a Transform
wrapped so that it has a .tfm
attribute.
The next step would be to wrap my function in a RandTransform
, but this still seems wrong, since my transformation is deterministic and not designed for data augmentation, it’s pre-processing for the input data.
Another fix would be to create a generic wrapper with the required attribute, but it seems strange that such a thing doesn’t already exist? Maybe I’m overlooking it, but I would have expected RandTransform
to be a subclass of the generic wrapper class.
I’m also looking at all the .process
methods in data_block
, but I think these use instances of PreProcessor
, which as I understand get applied at the ImageItemList.items
level, which in my case is an array of Path objects - the Image
object only gets loaded when used.
What is the usual way of working with a custom transform?