33

CLAHE is Contrast Limited Adaptive Histogram Equalization and a source in C can be found at http://tog.acm.org/resources/GraphicsGems/gemsiv/clahe.c

So far I have only seen some examples/tutorials about applying CLAHE on grayscale images so is it possible to apply CLAHE on color images (such as RGB 3 channles images)? If yes, how?

Mickey Shine
  • 12,187
  • 25
  • 96
  • 148
  • 1
    not possible directly. maybe convert to LAB or HSV, apply clahe on L and convert back. and you can use it from [opencv](http://answers.opencv.org/question/12024/use-of-clahe/), too. – berak Jul 29 '14 at 05:05
  • @berak thanks and your comment could be an answer – Mickey Shine Jul 29 '14 at 06:04
  • 5
    possible duplicate of [simple illumination correction in images openCV c++](http://stackoverflow.com/questions/24341114/simple-illumination-correction-in-images-opencv-c) – Bull Jul 29 '14 at 06:09
  • ^^ yes, B. that's where i got the idea. – berak Jul 29 '14 at 06:10
  • This link will help you https://stackoverflow.com/questions/24341114/simple-illumination-correction-in-images-opencv-c – gameon67 Nov 22 '18 at 02:07

3 Answers3

59

Conversion of RGB to LAB(L for lightness and a and b for the color opponents green–red and blue–yellow) will do the work. Apply CLAHE to the converted image in LAB format to only Lightness component and convert back the image to RGB. Here is the snippet.

bgr = cv2.imread(image_path)

lab = cv2.cvtColor(bgr, cv2.COLOR_BGR2LAB)

lab_planes = cv2.split(lab)

clahe = cv2.createCLAHE(clipLimit=2.0,tileGridSize=(gridsize,gridsize))

lab_planes[0] = clahe.apply(lab_planes[0])

lab = cv2.merge(lab_planes)

bgr = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)

bgr is the final RGB image obtained after applying CLAHE.

rinkert
  • 6,593
  • 2
  • 12
  • 31
Nikhil V M
  • 700
  • 6
  • 8
  • 8
    `cv2.split` isn't required as OpenCV in Python uses NumPy arrays. Once you create the CLAHE object, just do `lab[...,0] = clahe.apply(lab[...,0])`. You can also remove `cv2.merge` – rayryeng Jul 03 '19 at 04:02
  • This method sometimes gives bad results. See point 4 of https://stackoverflow.com/questions/56905592/optimize-the-contrast-brightness-or-histogram-equalization-of-a-color-photo-of. Would you have any idea @NikhilVM? – Basj Jul 06 '19 at 08:30
  • @Basj One has to try varying the parameters `clipLimit` and `tileGridSize`. In the question linked above, the OP has used grid size of 100. – Jeru Luke May 07 '22 at 18:59
4
img = cv2.imread(img_path, cv2.IMREAD_COLOR)
img = cv2.cvtColor(img, cv2.COLOR_RGB2Lab)

#configure CLAHE
clahe = cv2.createCLAHE(clipLimit=10,tileGridSize=(8,8))

#0 to 'L' channel, 1 to 'a' channel, and 2 to 'b' channel
img[:,:,0] = clahe.apply(img[:,:,0])

img = cv2.cvtColor(img, cv2.COLOR_Lab2RGB)

cv2.imshow("image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
1

this for c#, apply clahe for rgb images.

    private static Image<Bgr, byte> appy_CLAHE( Image<Bgr, byte> imgIn , int clipLimit=2, int tileSize=25)
    {
        var imglabcol = new Image<Lab, byte>(imgIn.Size);
        var imgoutL = new Image<Gray, byte>(imgIn.Size);  

        var imgoutBGR = new Image<Bgr, byte>(imgIn.Size);  

        //clahe filter must be applied on luminance channel or grayscale image
        CvInvoke.CvtColor(imgIn, imglabcol, ColorConversion.Bgr2Lab, 0); 

        CvInvoke.CLAHE(imglabcol[0], clipLimit, new Size(tileSize, tileSize), imgoutL);
        imglabcol[0] = imgoutL; // write clahe results on Lum channel into image

        CvInvoke.CvtColor(imglabcol, imgoutBGR, ColorConversion.Lab2Bgr, 0);

        return imgoutBGR;
    }
bh_earth0
  • 2,537
  • 22
  • 24