Bootstrap

gamma: CE Brightness-Distorted Images by Improved Adaptive Gamma Correction(2017)(附python)

Contrast Enhancement of Brightness-Distorted Images by Improved Adaptive Gamma Correction (2017)

Gang Cao1*, Lihui Huang1
, Huawei Tian2
, Xianglin Huang3
, Yongbin Wang1
, Ruicong Zhi4
code:https://github.com/leowang7/iagcwd/tree/master
paper: https://arxiv.org/pdf/1709.04427

1.介绍 Efficient contrast enhancement with adaptive gamma correction

S.-C. Huang, F.-C. Cheng, and Y.-S. Chiu

首先计算累积直方图c,gamma = 1-c
在这里插入图片描述

然后 apply gamma:

在这里插入图片描述

通过以上可知 gamma和累积直方图有关系。因此对直方图进行不同程度的平滑可以得到不同的累积直方图, 如下图b: alpha=0.5,1,1.5时的累积直方图的变化

在这里插入图片描述

梳理一下主要步骤:
对YUV的Y 或者 hsv的v 通道处理
1)首先计算直方图p
2) 然后根据公式2计算 pw, normalized后的 pw’=pw/pw.sum(), 这里有参数alpha可调
3) 然后计算累积直方图c, 和 gamma=1-c
4) 最后apply gamma

但是上面的方法有2个缺陷:
1是对于过亮的图像处理不好
2是对于过暗的图像:the image distortion may be incurred in bright regions due to the improper setting of rather low gamma values for large pixel intensities, 也就是在明亮区域,由于在像素值大的pixel会被设置过低的伽马值,可能会导致图像失真

2.作者提出2个方案改进上述方法,主要框架:

在这里插入图片描述

2.1 亮度判断

t = (mean - 0.5) / 0.5
表示图像均值与0.5的差距, 如果差距在 tao范围内则认为图像亮度是恰当的,不做改变。

2.2 对于过亮图像

在这里插入图片描述

2.3 对于过暗图像

在这里插入图片描述

3.复现结果展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
没有达到原文的效果,不知道哪里的错误。

下面附上代码:利用原论文中的图片截屏处理后得不到原文中类似的效果,欢迎大家分析指正


"""
Contrast Enhancement of Brightness-Distorted Images by Improved Adaptive Gamma Correction
Gang Cao1*, Lihui Huang1
, Huawei Tian2
, Xianglin Huang3
, Yongbin Wang1
, Ruicong Zhi4

其他版本code:https://github.com/leowang7/iagcwd
"""
import cv2
import matplotlib.pyplot as plt
import numpy as np


def agc0(Y, alpha, truncated):
    # 直方图
    p = cv2.calcHist(Y, [0], None, [256], [0, 256])
    # 直方图smooth
    #plt.figure()
    #plt.plot(np.arange(len(p)), p, )
    #plt.show()

    pmax = np.max(p)
    pmin = np.min(p)
    pw = ((p - pmin) / (pmax - pmin)) ** alpha
    pw = pw * pmax

    #plt.figure()
    #plt.plot(np.arange(len(p)), pw, )
    #plt.show()

    # 直方图norm
    pw_norm = pw / pw.sum()
    #plt.figure()
    #plt.plot( np.arange(len(pw_norm)), pw_norm,'b-',)
    #plt.show()

    # 累积直方图和gamma
    c = pw_norm.cumsum()
    print(c.max(), c.sum())

    #plt.figure()
    #plt.plot(np.arange(len(c)), c, 'b-', np.arange(len(c)), p.cumsum()/p.sum(), 'r-',)
    #plt.show()
    
    gamma = 1 - c
    #print('gamma:', gamma)
    #plt.figure()
    #plt.plot(np.arange(len(gamma)), gamma,'+', np.arange(len(gamma)), c,'g-',)
    #plt.show()
    if truncated:
        gamma = np.maximum(0.5, gamma)
    # apply gamma
    ret = np.round(Y.max() * ((Y / Y.max()) ** gamma[Y]))
    ret = ret.clip(0, 255).astype(np.uint8)
    return ret

def improved_agc(img):
    """
    :param img: uint8 bgr
    :param alpha:
    :return:
    """
    # Extract intensity component of the image
    YCrCb = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
    Y = YCrCb[:, :, 0]

    #Y = cv2.blur(Y, (5, 5))
    # Determine whether image is bright or dimmed
    threshold = 0.2
    t = (np.mean(Y) - 112) / 112

    if t < -threshold: # dimmed
        print('dimmed image ', t)
        ret = agc0(Y, 0.75, True)
    elif t > threshold*0.5: # bright
        print('bright image ', t)
        print(Y.dtype)
        Y_neg = 255 - Y
        print(Y_neg.dtype)
        ret = agc0(Y_neg, 0.25, False)
        ret = 255 - ret
    else:
        ret = Y
    YCrCb[:, :, 0] = ret
    img_output = cv2.cvtColor(YCrCb, cv2.COLOR_YCrCb2BGR)
    return img_output

if __name__ == "__main__":


    file = r'D:\dataset\Snipaste_2024-11-22_10-46-42.png'
    # file = r'D:\dataset\Snipaste_2024-11-21_17-13-55.png'
    # file = r'D:\dataset\Snipaste_2024-11-22_09-54-26.png'
    # file = r'D:\dataset\Snipaste_2024-11-22_09-56-01.png'

    file = r'D:\dataset\Snipaste_2024-11-21_17-14-25.png'
    img = cv2.imread(file, 1)

    ret = improved_agc(img)

    plt.figure()
    plt.subplot(121)
    plt.imshow(img[... ,::-1])
    plt.subplot(122)
    plt.imshow(ret[... ,::-1])
    plt.show()
;