jbohnslav / opencv_transforms

OpenCV implementation of Torchvision's image augmentations
MIT License
377 stars 46 forks source link

OpenCV implementations of adjust_hue and adjust_saturation #3

Open cleardusk opened 5 years ago

cleardusk commented 5 years ago

Great repo. But it seems that adjust_hue and adjust_saturation functions are exactly the PIL implementations (PyTorch official implementations). I wonder are there OpenCV implementations for these two functions, since the adjust_hue is rather slow, and adjust_saturation is a little slow when compared with adjust_contrast and adjust_brightness functions.

In my testing cases, given one 224x224x3 input, adjust_contrast takes about 188 µs, adjust_saturation takes about 2.33 ms, and adjust_hue takes about 6.99 ms.

jbohnslav commented 5 years ago

You're correct! I tried to be clever with contrast and brightness, using cv2.LUT for speed. I couldn't think of a faster way. However, I'll work on this now.

jbohnslav commented 5 years ago

I've done a quick check, and the way in which PIL and OpenCV calculate HSV from RGB images is quite different. This will make a 1->1 conversion between adjust_hue in PIL and OpenCV not possible.

image

cleardusk commented 5 years ago

I also found that RGB -> HSV conversion differs in PIL and OpenCV, the 1->1 conversion maybe impossible without modifying/re-writing OpenCV source code.

I wrote a testing script for hue and saturation adjusting simultaneously, the results are different from PIL, but may it work if not regarding PIL implementation as the standard?

P.S. cv2.cvtColor(img, cv2.COLOR_BGR2HSV) performs OK in my tesing cased. cvt function below takes about 4.72 ms with 224x224x3 input.

def cvt(img, hue_factor=0, saturation_factor=0):
    img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    table_hue = np.array([i + 255 * hue_factor for i in range(0, 256)]).clip(0, 255).astype('uint8')
    table_saturation = np.array([i * saturation_factor for i in range(0, 256)]).clip(0, 255).astype('uint8')
    img_hsv[:,:,0] = cv2.LUT(img_hsv[:,:,0], table_hue)
    img_hsv[:,:,1] = cv2.LUT(img_hsv[:,:,1], table_saturation)
    img_ret = cv2.cvtColor(img_hsv, cv2.COLOR_HSV2RGB)
    return img_ret
yxchng commented 5 years ago

@jbohnslav What is the state of adjust_hue and adjust_saturation? Is it going to always use Pillow or is there plan to rewrite it in OpenCV?

@cleardusk Does your function give the same result as the Pillow's version?

yxchng commented 5 years ago

@cleardusk I tried your solution and it is not as good as Pillow's version. It gives a lot of bad artifacts like this:

Screenshot from 2019-07-05 09-46-02