Augmentor icon indicating copy to clipboard operation
Augmentor copied to clipboard

Operations.Distort result in type _E datatype for the image!

Open morawi opened this issue 5 years ago • 7 comments

Why the result after distortion is not stored in an 8 bit channel?

I did not manage to convert it back to the range [0,1] or [0,255].

I used image.convert('L'), but I am still having errors.

Oh, and I am using PyTorch.

Thx.

morawi avatar Aug 27 '18 18:08 morawi

Hi @morawi, I've been away from my office for a few weeks so apologies for the delay.

Not sure exactly what you mean here, are you talking about the images that have been returned from the pipeline? What error do you get when you try to convert using image.convert('L')?

mdbloice avatar Sep 06 '18 08:09 mdbloice

Hi @mdbloice there was something that resulted in this type _E datatype when I used image.convert('L') ! Not sure if it was my mistake? Apparently, my input image was binary and the Augmentor resulted in a gray level image. To revert the image back to binary format, I used image = image > image.mean() , but here's the full code for convenience.

def __call__(self, image):        
        
        image = self.transform(image) # This is where the Augmentor takes effect
        if type(image)==list: # I only have one image, but the Augmentor returns a list of images
            image = image[0]
        image = np.array(image)  
        image = image > image.mean() # Thresholding the image to binary 
        image = image.astype('float32') # float32 to get the image ready for the GPU
        image = image.reshape(image.shape[0], image.shape[1], 1) # I need to restructure the image this way
        tsfm = transforms.ToPILImage() # now, convert the image back to PIL
        image = tsfm(image)   
        return image

morawi avatar Sep 06 '18 12:09 morawi

Hi @morawi Ok I am gonna have to check that out in more detail and get back to you. Could you also send me the error message that is thrown?

mdbloice avatar Sep 07 '18 10:09 mdbloice

Well @mdbloice,
it is a bit confusing to go back to the original code, as I have done a lot of changes to the code, also I am using git control, it'll take some time for me to figure out what and where was the error. Nonetheless, I have tried to skip the thresholding method above and use convert('L') and, surprisingly, everything was fine. However, the thresholding of convert('L') was not as good as my method shown above. Here's the code:

def __call__(self, image):        
       
       image = self.transform(image)
       if type(image)==list:
           image = image[0]
#        image = np.array(image) #, dtype='float32') #for some reason augmentor returns a list  
#        image = image > image.mean()
#        image = image.astype('float32')
#        image = image.reshape(image.shape[0], image.shape[1], 1)
#        tsfm = transforms.ToPILImage()
#        image = tsfm(image)  
       image = image.convert('L')
          
       return image

Augmentor used is: the_augmentor = TheAugmentor(probability=1, grid_width=8, grid_height=3, magnitude=8) ... passed to the TheAugmentor class to run self.p.random_distortion(probability, grid_width, grid_height, magnitude)

Here's the image I got with convert('L') gold 1

The image I got with my method is: gold 2

For convenience, here's the original image gold 3

morawi avatar Sep 07 '18 11:09 morawi

Hi @morawi right OK, well if this works for you now that's good, I will take a look at it when I get the chance and see where maybe this error might have been happening, so thanks for pointing it out. For now though I guess as there is no concrete error I can work with I will just have to leave this issue as is and try and get back to it one time...

mdbloice avatar Sep 07 '18 11:09 mdbloice

Oh, I have just remembered that I was using this function to convert the image to binary image = image.point(lambda p: int(p < some_threshold_value) ) and not convert('L')

def __call__(self, image):        
        
        image = self.transform(image)
        if type(image)==list:
            image = image[0]

#        image = image > image.mean()
#        image = image.astype('float32')
#        image = image.reshape(image.shape[0], image.shape[1], 1)
#        tsfm = transforms.ToPILImage()
#        image = tsfm(image)   
        image = image.point(lambda p: int(p < .5) )
        return image

Running the above point transform I have managed to re-generate the error:

File "./anaconda3/lib/python3.6/site-packages/torchvision-0.2.1-py3.6.egg/torchvision/transforms/transforms.py", line 49, in __call__
  img = t(img)

File "./data_transformations.py", line 146, in __call__
  image = image.point(lambda p: int(p < .5) )

File "./anaconda3/lib/python3.6/site-packages/PIL/Image.py", line 1486, in point
  scale, offset = _getscaleoffset(lut)

File "./anaconda3/lib/python3.6/site-packages/PIL/Image.py", line 484, in _getscaleoffset
  data = expr(_E(stub)).data

File "./scripts/data_transformations.py", line 146, in <lambda>
  image = image.point(lambda p: int(p < .5) )

TypeError: '<' not supported between instances of '_E' and 'float'

morawi avatar Sep 07 '18 11:09 morawi

I really do not know what the not supported between instances of '_E' error is supposed to mean. Aside from it being a type mismatch.

In the Augmentor package's code itself, in the Operations module, I use this code:

image.point(lambda x: 0 if x < self.threshold else 255, '1')

See: https://github.com/mdbloice/Augmentor/blob/master/Augmentor/Operations.py#L254-L259

Maybe try something like that. M.

mdbloice avatar Sep 07 '18 11:09 mdbloice