본문 바로가기
Image Processing (Python)

Contrast Limited Adaptive Histogram Equalization (CLAHE)

by HanByol Jang 2021. 12. 14.
728x90

함수 설명

앞선 포스팅에서 histogram의 분포를 균등하게 만들어줘 contrast를 개선시키는 Histogram Equalization에 대해 설명을 했습니다.

https://hanstar4.tistory.com/34

 

Histogram Equalization (히스토그램 균일화)

함수 설명 이미지의 픽셀값 분포가 특정값에 몰여있다면 그 부분에 대해 눈으로 구별하기 어렵고 이를 contrast가 낮다고 표현합니다. 반면에 픽셀값 분포가 촘촘히 몰려있지 않고 골고루 분포해

hanstar4.tistory.com

하지만 밝은 부분과 어두운 부분이 섞여 있는 이미지 전체에 균일화를 적용하면, 오히려 각 부분의 contrast가 감소할 위험이 있습니다.

Histogram Equalization 적용 전후

위 그림을 보면 모든 영역을 균일하게 적용하다보니 오히려 경계가 깨져 quality가 떨어지는 것을 볼 수 있습니다.

이를 해결하기 위해 이미지를 패치형태로 쪼개 패치안에서 균일화를 적용하는 방식을 적용했습니다.

 

그런데 패치는 작은 영역이다보니 너무 밝거나, 너무 어두운 몇개의 pixel이 큰 영향을 끼칠 수 있습니다. 이를 보완하기 위해 contrast limit라는 파라미터를 설정해, 이 값을 넘어가는 경우 해당 pixel들을 재조정하는 작업을 진행합니다.

CLAHE 적용 전후

위 그림을 보면 경계를 유지하면서 어두운 곳, 밝은 곳 모두 잘 보이도록 바뀌는 것을 볼 수 있습니다.

 

참조 : https://opencv-python.readthedocs.io/en/latest/doc/20.imageHistogramEqualization/imageHistogramEqualization.html


코드 설명

python OpenCV 라이브러리를 사용하였습니다.

 

clahe = cv2.createCLAHE(clipLimit, tileGridSize)
output = clahe.apply(src)

 

1) src : 바꾸고 싶은 source 이미지

2) clipLimit : contrast 제한 경계 값

3) tileGridSize : 패치 사이즈


예제

Histogram을 균일하게 만들어주는 예제입니다.

Color 이미지의 경우 YCrCb로 변환후 밝기에 해당하는 Y에 함수 적용후 다시 RGB 이미지로 변환시켜줍니다.

import cv2
import matplotlib.pyplot as plt
from skimage import io


# main function
def histogram_clahe(image):
    clahe = cv2.createCLAHE(clipLimit=4, tileGridSize=(11, 11))
    # Color image
    if len(image.shape) == 3:
        ycrcb_array = cv2.cvtColor(image, cv2.COLOR_RGB2YCrCb)
        y, cr, cb = cv2.split(ycrcb_array)
        merge_array = cv2.merge([clahe.apply(y), cr, cb])
        output = cv2.cvtColor(merge_array, cv2.COLOR_YCrCb2RGB)
    # Gray image
    else:
        output = clahe.apply(image)
    return output

def histogram_equal(image):
    # Color image
    if len(image.shape) == 3:
        ycrcb_array = cv2.cvtColor(image, cv2.COLOR_RGB2YCrCb)
        y, cr, cb = cv2.split(ycrcb_array)
        merge_array = cv2.merge([cv2.equalizeHist(y), cr, cb])
        output = cv2.cvtColor(merge_array, cv2.COLOR_YCrCb2RGB)
    # Gray image
    else:
        output = cv2.equalizeHist(image)
    return output

# Image Load
image = io.imread('dark.jpg')

# Clahe
output1 = histogram_clahe(image)
# Equalization
output2 = histogram_equal(image)

# gray image
gray_img = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
# Clahe
output3 = histogram_clahe(gray_img)
# Equalization
output4 = histogram_equal(gray_img)

# view
plt.subplot(2,3,1)
plt.title('Color Original')
plt.axis('off')
plt.imshow(image)

plt.subplot(2,3,2)
plt.title('CLAHE')
plt.axis('off')
plt.imshow(output1)

plt.subplot(2,3,3)
plt.title('Equalization')
plt.axis('off')
plt.imshow(output2)

plt.subplot(2,3,4)
plt.title('Gray Original')
plt.axis('off')
plt.imshow(gray_img, cmap='gray')

plt.subplot(2,3,5)
plt.title('CLAHE')
plt.axis('off')
plt.imshow(output3, cmap='gray')

plt.subplot(2,3,6)
plt.title('Equalization')
plt.axis('off')
plt.imshow(output4, cmap='gray')
plt.show()

Histogram Equalization과 비교하여 CLAHE가 어둡고 밝은 영역에 대해 자연스럽게 균일화를 시키는 것을 볼 수 있습니다.

728x90

'Image Processing (Python)' 카테고리의 다른 글

Histogram Equalization (히스토그램 균일화)  (0) 2021.12.06
Edge Detection (윤곽선 검출)  (0) 2021.12.01
Rotate (회전)  (0) 2021.11.24
Denoising (non-local)  (0) 2021.11.23
Color Space Change (색공간 변경)  (0) 2021.11.22

댓글