윤건우
윤건우

Reputation: 69

Image color looks broken when being converted from BGR to HSV and back again

I have been trying to do data augmentation for image detection using deep learning framework.
I'm using Opencv3.3 in Python.

My framework is:

  1. Convert BGR to HSV
  2. Image transformation like (rotation, scaling, shearing, translation)
  3. Convert HSV to BGR

The original image is this first one and the result is the following after.
Seeing below, there is some stain onto the red bottle.

I did randomly sample within [-10, 10] for Hue, within [-80, 80] for saturation, and within [-40, 40] for value.
Additionally, following this link, I set my code like this.


class RandomHSV(object):
   def __init__(self, hue = None, saturation = None, brightness = None):
        if hue:
            self.hue = hue 
        else:
            self.hue = 0

        if saturation:
            self.saturation = saturation 
        else:
            self.saturation = 0

        if brightness:
            self.brightness = brightness
        else:
            self.brightness = 0



        if type(self.hue) != tuple:
            self.hue = (-self.hue, self.hue)

        if type(self.saturation) != tuple:
            self.saturation = (-self.saturation, self.saturation)

        if type(brightness) != tuple:
            self.brightness = (-self.brightness, self.brightness)

    def __call__(self, img, bboxes):

        hue = random.randint(*self.hue)
        saturation = random.randint(*self.saturation)
        brightness = random.randint(*self.brightness)

        img = img.astype(int)

        a = np.array([hue, saturation, brightness]).astype(int)
        img += np.reshape(a, (1,1,3))

        img = np.clip(img, 0, 255)
        img[:,:,0] = np.clip(img[:,:,0],0, 179)

        img = img.astype(np.uint8)



        return img, bboxes



enter image description here enter image description here

Upvotes: 1

Views: 948

Answers (1)

makayla
makayla

Reputation: 341

It looks like openCV RGB to HSV does not have the values we're expecting. I took your image and converted it to HSV and looked at the ranges of each channel. Using np.max(imageHSV[:,:,c]) and np.min(imageHSV[:,:,c]) on each channel, I saw that Hue appears to be ranged between 0 and 360, while Saturation and Value are both scaled between 0 and 1. Using your clipping method on your image:

img = np.clip(img, 0, 255)
img[:,:,0] = np.clip(img[:,:,0],0, 179)

and then converting back to RGB, I got this result: bad HSV conversion

I tried instead clipping between 0 and 360 (hue), and 0 and 1 (saturation and value) like this:

imageHSV = cv2.cvtColor(image,cv2.COLOR_RGB2HSV)

imageHSV[:,:,1] = np.clip(imageHSV[:,:,1], 0.0, 1.0)
imageHSV[:,:,2] = np.clip(imageHSV[:,:,2], 0.0, 1.0)
imageHSV[:,:,0] = np.clip(imageHSV[:,:,0],0.0, 360.0)

Then I converted back to RGB and this was the result. good HSV conversion

edit - The HSV output is dependent on what type of data you feed into the converter, see this documentation. My image had ranges of (0-360, 0-1, 0-1) for (H, S, and V) because of how I passed it into cv2.cvtColor. Check your data you're passing into the RGB2HSV convert function and check the output to see if you have the ranges you want to clip to. I still think it may be a data type or data clipping issue.

Upvotes: 2

Related Questions