伽马变换

伽马变换主要用于图像的校正,将灰度过高 或者 灰度过低的图片进行修正,增强对比度。变换公式就是对原图像上每一个像素值做乘积运算:

伽马变换对图像的修正作用其实就是通过增强低灰度或高灰度的细节实现的,从伽马曲线可以直观理解:

 

一句话解释:其实就是说,在人眼看来,亮度并不是线性变化的(对深色更敏感),所以需要做一个映射,来让人眼感觉色彩是均匀变化的。这个映射就是所谓的gamma校正。

我们看下面这张图,左边在亮度上其实是均匀变化的,但是在我们人眼看来,深色数量远多于亮色。通过一个非线性校正后(右图),我们人眼看来就是均匀变化的了。这也就是gamma校正的目的

 

实际测出来人眼需要的gamma值是2.2 

如上图所示,为函数 f ( I ) = I γ的曲线表示:

当γ < 1 时,为图中上方的虚线曲线,图中γ = 1 / 2.2

当γ = 1 时,为图中间的直线,也就是f ( I ) = I 

当γ > 1 时, 为图中下方的曲线实线,图中γ = 2.2 

当γ ! = 1时,会将对I进行非线性的变换,对0,1两端的变换最小,对中间的变换最大。如果把图像0-255像素值,归一化到0-1, 带入进来,通过该变换,则可达到一定的效果:

1)当γ < 1 时,图像中最亮(1)或者最暗(0)的像素保持不变,整体亮度会发生提升,像素值中间的部分效果最明显,用来处理比较暗的图片非常好

2)当γ > 1 时,图像中最亮(1)或者最暗(0)的像素保持不变,整体亮度会发生降低,像素值中间的部分效果最明显,用来处理比较亮的图片非常好

最后x255即可

demo1

import numpy as np

def imadjust(img, in_range=[0, 1], out_range=[0, 1], gamma=1):
    # 默认参数和matlab中的默认参数相同

    low_in, high_in = in_range[0], in_range[1]
    low_out, high_out = out_range[0], out_range[1]
    # 百分比截断
    p1, p99 = np.percentile(img, (1, 99))
    img_out = np.clip(img, p1, p99)

    # 映射 参考https://stackoverflow.com/questions/39767612/what-is-the-equivalent-of-matlabs-imadjust-in-python
    img_out = (((img_out - low_in) / (high_in - low_in)) ** gamma) * (high_out - low_out) + low_out

    return img_out

demo2

import cv2
import numpy as np
import math
import os

def gamma_trans(img, gamma):  # gamma函数处理
    gamma_table = [np.power(x / 255.0, gamma) * 255.0 for x in range(256)]  # 建立映射表
    gamma_table = np.round(np.array(gamma_table)).astype(np.uint8)  # 颜色值为整数
    return cv2.LUT(img, gamma_table)  # 图片颜色查表。另外可以根据光强(颜色)均匀化原则设计自适应算法。

def nothing(x):
    pass

data_base_dir = r'./1'  # 输入文件夹的路径
outfile_dir = r'./2'  # 输出文件夹的路径

list = os.listdir(data_base_dir)
list.sort()
list2 = os.listdir(outfile_dir)
list2.sort()
for file in list:  # 遍历目标文件夹图片
    read_img_name = data_base_dir + '/' + file.strip()  # 取图片完整路径
    image = cv2.imread(read_img_name)  # 读入图片
    img_gray = cv2.imread(read_img_name, 0)  # 灰度图读取,用于计算gamma值

    mean = np.mean(img_gray)
    gamma_val = math.log10(0.5) / math.log10(mean / 255)  # 公式计算gamma

    image_gamma_correct = gamma_trans(image, gamma_val)  # gamma变换

    out_img_name = outfile_dir + '/' + file.strip()
    cv2.imwrite(out_img_name, image_gamma_correct)
    print("The photo which is processed is {}".format(file))
    

r = 1/2.2 效果如下图

 

 

 

 

 

 

参考资料:

https://blog.csdn.net/qq_43426078/article/details/124035614  【图像处理】gamma校正

https://zhuanlan.zhihu.com/p/267000923  OpenCV Gamma校正

https://blog.csdn.net/kkae8643150/article/details/114078037  图像处理算法之Gamma校正

https://www.cnblogs.com/ImageVision/archive/2012/04/16/2452671.html  人脸光照调整之Gamma校正    对 gamma 算法进行了改进 

http://t.zoukankan.com/ybqjymy-p-13801650.html  OpenCV 图像增强(方法:伽马变换)