使用Grayworld假设自动进行白平衡 [英] Automatic White Balancing with Grayworld assumption
问题描述
我一直在尝试实现以下提供的白平衡算法: https://pippin.gimp.org/image-processing/chapter-automaticadjustments. html
I have been trying to implement the white balancing algorithms provided by: https://pippin.gimp.org/image-processing/chapter-automaticadjustments.html
我已经使用python和opencv来实现它们.我无法产生与网站相同的结果.
I have used python and opencv to implement them. I am unable to produce the same results as in the website.
例如,在Grayworld假设中,我使用以下代码:
In grayworld assumption, for example, i use the following code:
import cv2 as cv
import numpy as np
def show(final):
print 'display'
cv.imshow("Temple", final)
cv.waitKey(0)
cv.destroyAllWindows()
def saveimg(final):
print 'saving'
cv.imwrite("result.jpg", final)
# Insert any filename with path
img = cv.imread("grayworld_assumption_0.png")
res = img
final = cv.cvtColor(res, cv.COLOR_BGR2LAB)
avg_a = -np.average(final[:,:,1])
avg_b = -np.average(final[:,:,2])
for x in range(final.shape[0]):
for y in range(final.shape[1]):
l,a,b = final[x][y]
shift_a = avg_a * (l/100.0) * 1.1
shift_b = avg_b * (l/100.0) * 1.1
final[x][y][1] = a + shift_a
final[x][y][2] = b + shift_b
final = cv.cvtColor(final, cv.COLOR_LAB2BGR)
final = np.hstack((res, final))
show(final)
saveimg(final)
我正在得到结果
而不是
我要去哪里错了?
推荐答案
The document you are implementing is not aware of CV internal conventions for LAB definition in case of 8-bit color depth.
尤其是:
L: L / 100 * 255
A: A + 128
B: B + 128
我相信这样做是为了提高准确性,因为这样一来,就可以完全使用unsigned int8
精度来实现发光度,同时为整个数组保持一致的无符号数据类型.
I believe this is done for improved accuracy, because then one could use unsigned int8
precision in full for the luminosity while keeping a consistent unsigned data type for the whole array.
下面的代码(改编自您的代码)应该可以正常工作.
请注意,这里和那里有一些小的修复( EDIT ,包括将有趣的代码包装在函数中),但实际的 sauce 在嵌套的for
循环内.
The code below, adapted from yours should work.
Note that there are some minor fixes here and there (EDIT including wrapping up the interesting code in a function), but the actual sauce is within the nested for
loop.
from __future__ import (
division, absolute_import, print_function, unicode_literals)
import cv2 as cv
import numpy as np
def show(final):
print('display')
cv.imshow('Temple', final)
cv.waitKey(0)
cv.destroyAllWindows()
# Insert any filename with path
img = cv.imread('grayworld_assumption_0.png')
def white_balance_loops(img):
result = cv.cvtColor(img, cv.COLOR_BGR2LAB)
avg_a = np.average(result[:, :, 1])
avg_b = np.average(result[:, :, 2])
for x in range(result.shape[0]):
for y in range(result.shape[1]):
l, a, b = result[x, y, :]
# fix for CV correction
l *= 100 / 255.0
result[x, y, 1] = a - ((avg_a - 128) * (l / 100.0) * 1.1)
result[x, y, 2] = b - ((avg_b - 128) * (l / 100.0) * 1.1)
result = cv.cvtColor(result, cv.COLOR_LAB2BGR)
return result
final = np.hstack((img, white_balance_loops(img)))
show(final)
cv.imwrite('result.jpg', final)
相同的结果,但通过避免循环可以获得更快的性能:
The same result, but with much faster performances can be obtained by avoiding loops:
def white_balance(img):
result = cv.cvtColor(img, cv.COLOR_BGR2LAB)
avg_a = np.average(result[:, :, 1])
avg_b = np.average(result[:, :, 2])
result[:, :, 1] = result[:, :, 1] - ((avg_a - 128) * (result[:, :, 0] / 255.0) * 1.1)
result[:, :, 2] = result[:, :, 2] - ((avg_b - 128) * (result[:, :, 0] / 255.0) * 1.1)
result = cv.cvtColor(result, cv.COLOR_LAB2BGR)
return result
显然可以得到相同的结果:
which obviously gives the same result:
print(np.all(white_balance(img) == white_balance_loops(img)))
True
但时机非常不同:
%timeit white_balance(img)
100 loops, best of 3: 2 ms per loop
%timeit white_balance_loops(img)
1 loop, best of 3: 529 ms per loop
这篇关于使用Grayworld假设自动进行白平衡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!