Gamma校正原理及实现

G a m m a 校 正 原 理 及 实 现 Gamma校正原理及实现 Gamma

Gamma变换是对输入图像灰度值进行的非线性操作,使输出图像灰度值与输入图像灰度值呈指数关系:

Gamma变换就是用来图像增强,其提升了暗部细节,简单来说就是通过非线性变换,让图像从暴光强度的线性响应变得更接近人眼感受的响应,即将漂白(相机曝光)或过暗(曝光不足)的图片,进行矫正。

即可以总结如下:

gamma>1, 较亮的区域灰度被拉伸,较暗的区域灰度被压缩的更暗,图像整体变暗;
gamma<1, 较亮的区域灰度被压缩,较暗的区域灰度被拉伸的较亮,图像整体变亮;

https://blog.csdn.net/zdaiot/article/details/82833934

在这里插入图片描述

import cv2
#分道计算每个通道的直方图
img0 = cv2.imread('12.jpg')
hist_b = cv2.calcHist([img0],[0],None,[256],[0,256])
hist_g = cv2.calcHist([img0],[1],None,[256],[0,256])
hist_r = cv2.calcHist([img0],[2],None,[256],[0,256])
def gamma_trans(img,gamma):
    #具体做法先归一化到1,然后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)
    #实现映射用的是Opencv的查表函数
    return cv2.LUT(img0,gamma_table)
img0_corrted = gamma_trans(img0, 0.5)
cv2.imshow('img0',img0)
cv2.imshow('gamma_image',img0_corrted)
cv2.imwrite('gamma_image.png',img0_corrted)
#分通道计算Gamma校正后的直方图
hist_b_c =cv2.calcHist([img0_corrted],[0],None,[256],[0,256])
hist_g_c =cv2.calcHist([img0_corrted],[1],None,[256],[0,256])
hist_r_c =cv2.calcHist([img0_corrted],[2],None,[256],[0,256])
fig = plt.figure('gamma')
pix_hists = [[hist_b, hist_g, hist_r],
    [hist_b_c, hist_g_c, hist_r_c]]
pix_vals = range(256)
for sub_plt, pix_hist in zip([121, 122], pix_hists):
    ax = fig.add_subplot(sub_plt, projection='3d')
    for c, z, channel_hist in zip(['b', 'g', 'r'], [20, 10, 0], pix_hist):
          cs = [c] * 256
          ax.bar(pix_vals, channel_hist, zs=z, zdir='y', color=cs, alpha=0.618, edgecolor='none', lw=0)
    ax.set_xlabel('Pixel Values')
    ax.set_xlim([0, 256])
    ax.set_ylabel('Count')
    ax.set_zlabel('Channels')
plt.show()
cv2.waitKey()

### 色调映射与Gamma校正原理 #### 什么是色调映射? 色调映射(Tone Mapping)是指将高动态范围(HDR)图像转换为低动态范围(LDR)图像的过程。这一过程的核心在于如何有效地压缩图像的动态范围,使其适合在标准显示器上呈现,同时尽可能保留原始图像的关键特征和视觉效果[^2]。 由于人眼能够感知非常宽广的动态范围(约 \(10^5\)),而现代显示器通常仅支持较窄的动态范围(如 \(2^8\) 或更高分辨率的颜色表示),因此简单的线性映射无法满足需求。如果采用线性方法,则可能导致全局对比度损失、细节模糊甚至严重失真等问题。为此,色调映射通过复杂的非线性变换实现更优的结果,在保持整体亮度平衡的同时增强局部对比度并突出重要细节[^3]。 #### Gamma校正的作用 Gamma校正是指对图像信号进行幂律变换的操作,其目的是补偿人类视觉系统的非线性响应特性以及显示设备本身的物理属性差异。具体而言: - **历史背景**:最初引入Gamma校正主要是为了适应CRT显示器的工作机制——这些早期屏幕具有固有的非线性输入/输出关系,即电压变化并不直接对应于发光强度的变化;而是遵循某种特定形式的指数函数关系 (\(V_{out} \propto V_{in}^\gamma\)) 。于是通过对源数据施加逆向调整 (de-gamma),使得最终呈现在用户面前的画面更加接近预期目标[^4]。 - **当前意义**:尽管如今大多数新型显示屏已具备较为理想的线性表现能力,但Gamma校正依然被广泛沿用下来,因为它还承担着其他几项关键功能: - 提供更好的主观观感体验; - 减少传输过程中可能发生的量化误差影响; - 维护跨平台一致性等方面的优势[^1]^. #### 在图像处理流程中的角色定位 从整个图像生成至展示链条来看,两者分别扮演不同却互补的角色: - Tone Mapping 主要负责解决从真实世界捕获的大跨度光照条件下的场景信息适配问题; - Gamma Correction 则侧重于针对终端再现环节做出相应优化设置以便获得最佳观看效果. ```python import numpy as np from matplotlib import pyplot as plt def apply_gamma_correction(image, gamma=2.2): """Apply gamma correction to an image.""" corrected_image = ((image / 255)**(1/gamma))*255 return corrected_image.astype(np.uint8) # Example usage with a dummy array representing pixel values between 0 and 255. dummy_img = np.array([range(0,256)]).reshape((1,-1)) corrected_dummy_img = apply_gamma_correction(dummy_img.copy()) plt.figure(figsize=(10,5)) plt.subplot(1,2,1), plt.title('Original Image'), plt.imshow(dummy_img,cmap='gray') plt.xticks([]), plt.yticks([]) plt.subplot(1,2,2), plt.title(f'Corrected Image ($\gamma=${2.2})'), plt.imshow(corrected_dummy_img,cmap='gray') plt.xticks([]), plt.yticks([]); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值