白平衡算法

31

我正在进行一些图像处理,需要一个自动白平衡算法,不会太耗费CPU计算时间。 有任何建议吗?

编辑:如果与效率相关,则将以Java实现它,并使用整数数组作为彩色图像。


一些兔子洞的迹象:https://www.eecs.yorku.ca/~mbrown/ICCV19_Tutorial_MSBrown.pdf - Christoph Rackwitz
5个回答

24

GIMP 显然使用一种非常简单的算法进行自动白平衡。 http://docs.gimp.org/en/gimp-layer-white-balance.html

白平衡命令通过分别拉伸红色、绿色和蓝色通道来自动调整活动图层的颜色。为此,它会丢弃红色、绿色和蓝色直方图两端的像素颜色,这些像素只在图像中占0.05%左右,并尽可能地拉伸剩余范围。结果是,在直方图的外缘非常少出现的像素颜色(如灰尘等)不会与拉伸直方图所用的最小和最大值发生负面影响,相比于“拉伸对比度”。但是,类似于“拉伸对比度”,处理后的图像可能会出现色调变化。

实际上,这里还有一些微调,因为我第一次尝试实现这个工作似乎对大多数照片有效,但其他照片似乎会产生伪影或包含过多的红色、绿色或蓝色 :/


谢谢这个链接。我之前没有看到过。 - Nosredna
也许你可以实现多种算法,然后根据图像的某些特征来尝试确定哪种算法在何时起作用。对于曝光(一种相当类似的问题),现代相机实际上会将图像分割开(而且它们知道焦点和是否使用了闪光灯,正如@Matthias Wandel指出的那样)。制造商已经分析了许多照片的数据库,以了解什么是有效的。我记得第一个这样做的相机是尼康FA和那个时代的其他几个制造商。 - Nosredna
顺便提一下,您可以通过查看相邻像素之间的最大对比度来找到焦点区域。当摄影师使用闪光灯时,聚焦区域通常相对靠近相机,并可能具有一些漂亮的闪光亮点。 - Nosredna
2
为了实现白平衡,您可能更关心对焦区域而不是非对焦区域。因此,您可以将屏幕分成5x5网格,并通过对焦进行“分级”,然后根据其重要性为白平衡算法加权。如果您愿意,我现在可以闭嘴。否则,我可能会一直唠叨下去。 - Nosredna
谢谢Norsredna,实际上我正在用它来进行视频处理(这就是为什么它需要高效),所以Flash不是问题,但我可以通过每10帧重新计算白平衡参数来进行优化,因为光照通常不会经常改变。 :P - Charles Ma

22
一个相对简单的算法是对屏幕上最亮和最暗像素的色调(在HSV或HSL中)进行平均。如果情况紧急,只使用最亮的像素。如果最亮和最暗之间的色调差异太大,则选择亮的像素。如果黑暗接近黑色,则选择亮的像素。
为什么要看暗像素?有时,暗色并不接近黑色,并且提示周围环境光线或雾气。
如果你是一个熟练使用Photoshop的用户,这个算法应该很容易理解。照片中的亮点与物体的基本颜色无关(或者相关性较弱)。它们是灯光颜色的最佳表示,除非图像过度曝光以至于一切都被CCD压倒。
然后,调整所有像素的色调。
你需要快速的RGB到HSV和HSV到RGB函数。(但也许你可以使用LUT或线性插值在像素校正中使用RGB。)
你不希望按平均像素颜色或最受欢迎的颜色处理。这样做会导致混乱。
为了快速找到最亮的颜色(和最暗的颜色),你可以使用RGB,但你应该为绿色、红色和蓝色设置乘数。在RGB监视器上,255绿色比255红色更亮,255红色比255蓝色更亮。我曾经记得这些乘数,但不幸的是,它们已经从我的记忆中消失了。你可能可以在谷歌上找到它们。
在没有亮点的图像中,这种方法会失败。例如,哑光粉刷的墙壁。但我不知道你能做什么。
还有许多改进这个简单算法的方法。你可以对多个亮的像素进行平均,将图像格成网格并从每个单元格中获取明亮和暗淡的像素等。实施算法后,你会发现一些明显的调整方法。

谢谢!我会尝试一下。我还发现了一个非常简单的算法,GIMP 显然用于其自动白平衡,我将对这两个算法进行基准测试,看看哪一个适合我 :) - Charles Ma
1
我本以为大多数照片至少会有一个超白像素(255,255,255) - 特别是在需要更多白平衡帮助的低质量相机上 - 而白色像素实际上对算法没有什么帮助。那么你是否会查看下一个最亮的像素? - Simon East
1
@Simon,你也可以取最轻和最暗的N%像素的平均值。 - Charles Ma
1
你说“调整所有像素的色调”,但我不确定你的意思是什么。一旦我知道最亮的像素在哪里,我该如何调整其他像素的色调? - Matt Ellen
@MattEllen 可能已经晚了,但我认为Nosredna所说的意思是:对于检测到的“白色色调”(r_w,g_w,b_w),所有像素都应该被放大(1/r_w,1/g_w,1/b_w)。 - Dmitri K
请查看Simplest Color Balance的论文和代码,网址为:https://www.ipol.im/pub/art/2011/llmps-scb/article.pdf。这有助于将上述建议放入上下文中。 - RobBW

12

@Charles Ma建议使用Gimp的白平衡算法。在pythonnumpy中,代码如下:

# white balance for every channel independently
def wb(channel, perc = 0.05):
    mi, ma = (np.percentile(channel, perc), np.percentile(channel,100.0-perc))
    channel = np.uint8(np.clip((channel-mi)*255.0/(ma-mi), 0, 255))
    return channel

image = cv2.imread("foo.jpg", 1) # load color
imWB  = np.dstack([wb(channel, 0.05) for channel in cv2.split(img)] )

它快速、简单,并提供相当不错的结果。


3

最近发表的一个算法是颜色分布算法:

D. Cheng, D.K. Prasad 和 M.S. Brown,
“用于色彩恒常性的光源估计:为什么空间域方法有效以及颜色分布的作用”
美国光学学会杂志A 31(5):1049-1058(2014)
DOIPDF

在这篇论文中也提到了Matlab源代码(互联网档案馆)。这是一个简单的算法,可以很容易地进行编程,结果显示它非常快速。

如果您需要更快速和准确的白平衡(颜色恒定性)算法,您应该查看this site。其中有多种算法及其相应的源代码,可能正是您所寻找的。

M Afifi和M S Brown最近的工作非常相关和有用:https://github.com/mahmoudnafifi/WB_sRGB - RobBW

3

白平衡算法很难。即使是数码相机有时也会出错,尽管它们知道很多关于图片的额外信息-例如是否使用了闪光灯和光线水平。

首先,我只会平均红色、绿色和蓝色,并将其用作白平衡点。对其进行限制-保持在钨丝灯、荧光灯和日光范围内。虽然不完美,但当错误发生时,解释起来相对容易。


11
一种常见的尝试是使用白平衡,但这将会把在雪地中的红球变成在青色海洋中的暗淡红球。在我看来,这比没有白平衡效果还要糟糕。 - Nosredna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接