Reputation: 69
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:
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
Upvotes: 1
Views: 948
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:
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.
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