1

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

윤건우
  • 59
  • 5
  • 1
    Can you explain this line: ```img[:,:,0] = np.clip(img[:,:,0],0, 179)``` ? This should be the hue value, which you are clipping at 179 degrees, so you're setting any cyan, blue, or magenta hues to green? – makayla Dec 11 '19 at 15:14
  • @makayla hue is normalized to [0..180) in opencv – MSpiller Dec 11 '19 at 15:33
  • Oh okay I see, thanks. – makayla Dec 11 '19 at 15:34
  • 1
    Could you please clarify a) what is the actual question, b) why you choose to do geometric alterations in HSV colourspace, c) where/how you load and save the image. Thank you. – Mark Setchell Dec 11 '19 at 16:21
  • HSV is a poor choice here, because hue is angular (it wraps around). Let's assume hue is in range [0,180). Let's say you have two hues - slightly orange red (H=5) and slighly purple red (H=175). The expected average hue of those two would be pure red (0). In actuality, you'll get the result of 90, which is cyan -- complete opposite. You would need to use transformations which account for this property of hue. OpenCV, AFAIK, doesn't provide those. – Dan Mašek Dec 11 '19 at 18:45

1 Answers1

2

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.

makayla
  • 331
  • 1
  • 5