AWB(Auto White Banlance)——自动白平衡

AWB(Auto White Banlance)——自动白平衡产生原因方法代码GW灰度世界白平衡算法灰度世界算法(GrayWorld)是以灰度世界假设为基础的,该假设认为对于一幅有着大量色彩变化的图像,R、G、B三个分量的平均值趋于同一个灰度K。$$Rgain=k/Ravg$$$$Ggain=k/Gavg$$$$Bg

大家好,欢迎来到IT知识分享网。

产生原因

image

方法

image
image
image
image

代码

GW灰度世界白平衡算法

灰度世界算法(Gray World)是以灰度世界假设为基础的,该假设认为对于一幅有着大量色彩变化的图像, R、 G、 B 三个分量的平均值趋于同一个灰度K。
$$Rgain = k / Ravg $$
$$Ggain = k / Gavg $$
$$Bgain = k / Bavg $$
然后通过k值来求各个通达的增益。

  1. 直接给定为固定值, 取其各通道最大值的一半,即取为127或128;
  2. 令 K = (Raver+Gaver+Baver)/3,其中Raver,Gaver,Baver分别表示红、 绿、 蓝三个通道的平均值。
    算法的第二步是分别计算各通道的增益:
    $$k = (Bavg + Gavg + Ravg)/3$$
  3. 设定G通道不变,让R和B通道往G通道上靠,即:
    $$Rgain = Rave / Gave$$
    $$Bgain = Bave / Gave$$
    新的像素的绿色通道不变,红色和蓝色通道通过绿色通道来求
import cv2 as cv
import numpy as np

src = cv.imread('test.jpg')

# 求出各个颜色分量的平均值
b_avg = np.mean(src[:, :, 0])
g_avg = np.mean(src[:, :, 1])
r_avg = np.mean(src[:, :, 2])
# 求出灰度世界的灰度值
k = (b_avg + g_avg + r_avg)/3
# 求出各个颜色分量的增益
b_gain = k / b_avg
g_gain = k / g_avg
r_gain = k / r_avg

# 定义一个新的矩阵存放变换后的图像
src1 = np.zeros(src.shape)
src1[:, :, 0] = src[:, :, 0] * b_gain
src1[:, :, 1] = src[:, :, 1] * g_gain
src1[:, :, 2] = src[:, :, 2] * r_gain

# 计算后类型为浮点数,需要类型转换
src1 = src1.astype(np.uint8)

# 拼接两张图片,便于观察
img = np.hstack([src, src1])
cv.namedWindow('input_image', cv.WINDOW_AUTOSIZE)
cv.imshow('input_image', img)
cv.waitKey(0)
cv.destroyAllWindows()

PR完全反射白平衡算法

图像中最亮的点为白点,那么各个通道的最大值应该趋近白色,可是设定一个K值,如255,那么图像中最两点的值应该趋于255,这样就可以计算出各通道的增益:
$$Rgain = k / Rmax $$
$$Ggain = k / Gmax $$
$$Bgain = k / Bmax $$

import cv2 as cv
import numpy as np

src = cv.imread('test.jpg')

# 求出各个颜色分量的增益
b_gain = 255 / np.max(src[:, :, 0])
g_gain = 255 / np.max(src[:, :, 1])
r_gain = 255 / np.max(src[:, :, 2])

# 定义一个新的矩阵存放变换后的图像
src1 = np.zeros(src.shape)
src1[:, :, 0] = src[:, :, 0] * b_gain
src1[:, :, 1] = src[:, :, 1] * g_gain
src1[:, :, 2] = src[:, :, 2] * r_gain

# 计算后类型为浮点数,需要类型转换
src1 = src1.astype(np.uint8)

# 拼接两张图片,便于观察
img = np.hstack([src, src1])
cv.namedWindow('input_image', cv.WINDOW_AUTOSIZE)
cv.imshow('input_image', img)
cv.waitKey(0)
cv.destroyAllWindows()

通过GW和PR两种算法的正交组合,从而保留两者的优点,具体的算法公式如下:
$$ Kave = (Rave + Gave + Bave) / 3 $$
$$ Kmax = (Rmax + Gmax + Bmax) / 3$$
$$ u * Rave^2 + v * Rave = Kave $$
$$ u * Rmax^2 + v* Rmax = Kmax $$
这是R通道的算法公式,求出u和v然后通过以下公式换算出新的值:
$$Rnew = u * Rorg ^ 2 + v * Rorg$$

import cv2 as cv
import numpy as np

src0 = cv.imread('..//images//NikonD5200_0001_G_AS.png')
src = src0.astype(np.uint16)    # 调整一下数据类型,防止算术运算溢出

# 求出各个颜色分量的平均值
b_ave = np.mean(src[:, :, 0])
g_ave = np.mean(src[:, :, 1])
r_ave = np.mean(src[:, :, 2])

# 各个颜色分量的最大值
b_max = np.max(src[:, :, 0])
g_max = np.max(src[:, :, 1])
r_max = np.max(src[:, :, 2])

# 根据QCGP公式求出系数
k_ave = (b_ave + g_ave + r_ave)/3
k_max = (b_max + g_max + r_max)/3
k_matrix = np.mat([[k_ave], [k_max]])

# 通过矩阵求出B通道的转换矩阵,并计算出新图的B通道
b_coefficient_matrix = np.mat([[b_ave * b_ave, b_ave],
                               [b_max * b_max, b_max]])
b_conversion_matrix = b_coefficient_matrix.I * k_matrix

b = (src[:, :, 0]).transpose()
bb = (src[:, :, 0] * src[:, :, 0]).transpose()
b = np.stack((bb, b), axis=0).transpose()
b_des = np.dot(b, np.array(b_conversion_matrix))
b_des = b_des.astype(np.uint8).reshape([280, 471])

# 通过矩阵求出G通道的转换矩阵,并计算出新图的G通道
g_coefficient_matrix = np.mat([[g_ave * g_ave, g_ave],
                               [g_max * g_max, g_max]])
g_conversion_matrix = g_coefficient_matrix.I * k_matrix

g = (src[:, :, 1]).transpose()
gg = (src[:, :, 1] * src[:, :, 1]).transpose()
g = np.stack((gg, g), axis=0).transpose()
g_des = np.dot(g, np.array(g_conversion_matrix))
g_des = g_des.astype(np.uint8).reshape([280, 471])

# 通过矩阵求出R通道的转换矩阵,并计算出新图的R通道
r_coefficient_matrix = np.mat([[r_ave * r_ave, r_ave],
                               [r_max * r_max, r_max]])
r_conversion_matrix = r_coefficient_matrix.I * k_matrix

r = (src[:, :, 2]).transpose()
rr = (src[:, :, 2] * src[:, :, 2]).transpose()
r = np.stack((rr, r), axis=0).transpose()
r_des = np.dot(r, np.array(r_conversion_matrix))
r_des = r_des.astype(np.uint8).reshape([280, 471])

# 用一个新的矩阵接受新的图片,注意数据类型要和原图一致
src1 = np.zeros(src.shape).astype(np.uint8)
src1[:, :, 0] = b_des
src1[:, :, 1] = g_des
src1[:, :, 2] = r_des

# 显示图片
img = np.hstack([src0, src1])
cv.namedWindow("AWB", cv.WINDOW_AUTOSIZE)
cv.imshow("AWB", img)
cv.waitKey(0)
cv.destroyAllWindows()

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/33368.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信