Loading RAW image files into ImageBlock

Hey guys,

Problem: How to load image files of *.RAW format into ImageBlock?

Suggested solution:

Looking at: (Data.py)

# Cell
def ImageBlock(cls=PILImage):
    "A `TransformBlock` for images of `cls`"
    return TransformBlock(type_tfms=cls.create, batch_tfms=IntToFloatTensor)

What if I can create another cls that is based on rawpy API?

So far it looks like that PIL API supports mostly *.JPG format.

This issue is followed by this issue:

Defining your own image class would be the right solution.
The following suggestion could work:


def load_raw_image(fn):
    "Open and load a raw image with rawpy"
    # your function to load a raw image from fn/Path here
    # return a numpy array `arr` 
    return arr


class RawpyImage(PILBase):
    @classmethod
    def create(cls, fn:(Path,str), **kwargs)->None:
        "Open a raw image from path `fn`"
        arr = load_raw_image(fn)
        return cls(Image.fromarray(arr))

Make sure the format of the np.array generated in load_raw_image is either uint8 (integer values between 0 and 255) or float32 (float values between 0 and 1).

1 Like

Thanks man! Sounds great.

Make sure the format of the np.array generated in load_raw_image is either uint8 (integer values between 0 and 255) or float32 (float values between 0 and 1).

JPG has about 8 bits for each pixel, so there are at most 256 different values. But RAW files have about 16 bits for each pixel, so there are at most 65536 different values. So would I need uint16, isn’t it?

In theory, yes, but IIRC, uint16 cannot be transformed to a PILImage instance. I had those problems when reading DICOM files, which are also 16 bit. Going with float values, rescaled to values between 0 and 1 might be easier.

So if I get it right, I should unpack the image file into a matrix, then divide every pixel by 65536, then convert it into np.array of the datatype of float32?

Yes. This should work.

1 Like