白平衡的作用和目的
由于水下拍摄图像时,光在水里的散射会造成色彩的丢失,导致拍摄到的图
片整体呈绿色或者蓝色,故采用白平衡消除散射带来的色差。白平衡的目的是使白色的物体在任何颜色的光照下面都为白色,由于人眼具有高灵敏度,这对于人眼不难办到,只要不超过特定限制,光源就会自动变为白色。但是对照相机来说,则不一样。照相机使用图像胶片和传感器来记录光源的颜色,白色物体使用光源的颜色。
白平衡实施过程
将图像的 R、G、B 三个通道的灰度值拉伸,映射到[0,255]范围内,起到去色偏的效果。假设在图像的三个通道中,图像中白色的点用 255 表示,黑色的点用 0 表示,其他像素点使用(Ax+b)映射函数映射到(0,255)。也许很多图像中原本的灰度值已经在[0,255]范围内,因此本文让图像中一定比例高亮度的像素让它为 255,一定比例低亮度的像素让它为 0。具体的实现过程为:
1.排序。对图像的灰度值进行排序。
2.选取部分区域像素。从排列好的像素数组中选取一定比例高亮度和低亮度
的像素,并记录好选取位置处的像素灰度值 Imin 和 Imax。
3.像素填充。根据上一步得出的 Imin 和 Imax,将图像中小于等于 Imin 的像素灰度值都设置为 0,大于等于 Imax 的像素灰度值都设置为 255。
4. 像 素 映 射 。 将 图 像 中 处 于 (Imin,Imax) 之 间 的 像 素 通 过 函 数 : f(x) =(I(x)-Imin)×255 /(Imax-Imin)映射到[0,255]之间,完成对原始图像中所有像素值的修正。
具体的像素值映射公式如下:
运行程序
import cv2
import numpy as np
def white_balance(image):
balanced_image = np.zeros_like(image) # 创建一个与输入图像相同大小的空白图像
# 对每个颜色通道进行白平衡处理
for i in range(3):
# 1. 排序
sorted_gray_values = np.sort(image[:, :, i].flatten())
# 2. 选取部分区域像素
total_pixels = image.shape[0] * image.shape[1]
low_pixels = int(total_pixels * 0.1) # 选取比例低亮度的像素个数
high_pixels = int(total_pixels * 0.1) # 选取比例高亮度的像素个数
Imin = sorted_gray_values[low_pixels] # 最低亮度像素的灰度值
Imax = sorted_gray_values[-high_pixels] # 最高亮度像素的灰度值
# 3. 像素填充
balanced_channel = np.where(image[:, :, i] <= Imin, 0, image[:, :, i]) # 小于等于 Imin 的像素设为 0
balanced_channel = np.where(balanced_channel >= Imax, 255, balanced_channel) # 大于等于 Imax 的像素设为 255
# 4. 像素映射
balanced_channel = ((balanced_channel - Imin) * 255 / (Imax - Imin)).clip(0, 255)
# 将处理后的通道赋值给空白图像的对应通道
balanced_image[:, :, i] = balanced_channel
return balanced_image
# 读取图像
image = cv2.imread('ok4.jpg').astype(np.float32) / 255.0
# 进行白平衡处理
balanced_image = white_balance(image).astype(np.uint8)
# 显示处理前后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Balanced Image', balanced_image)
cv2.waitKey(0)
cv2.destroyAllWindows()