在使用cv2读取图片后,格式自动为uint8格式,但是这种格式在进行加法计算时:自动取模运算
比如一个点RGB为(90,90,90):
sum = R+G+B # sum本来为270,但是取模运算,sum=270%256 = 14
这就导致结果异常,应当写为:
sum = int(R)+int(G)+int(B)
以下是闲聊以及跳过这些坑的全局完美反射白平衡源代码:
感谢偏色检测与白平衡算法提供的思路,这里作为轻微改动。
无论什么白平衡方法都会受到全局的制约,如果有一种方式能够提炼出白色区域(也就是摄影中灰卡,白卡等方法)这样的白平衡效果会更好,下左图第一张为原图,下左图第二张为通过右图红色框所示的白色区域进行白平衡再扩展至全图的效果,下左图第三张为全图白平衡
全局完美反射白平衡源码:
def white_balance_2(img_input):
'''
完美反射白平衡
STEP 1:计算每个像素的R\G\B之和
STEP 2:按R+G+B值的大小计算出其前Ratio%的值作为参考点的的阈值T
STEP 3:对图像中的每个点,计算其中R+G+B值大于T的所有点的R\G\B分量的累积和的平均值
STEP 4:对每个点将像素量化到[0,255]之间
依赖ratio值选取而且对亮度最大区域不是白色的图像效果不佳。
:param img: cv2.imread读取的图片数据
:return: 返回的白平衡结果图片数据
'''
img = img_input.copy()
b, g, r = cv.split(img)
m, n, t = img.shape
sum_ = np.zeros(b.shape)
for i in range(m):
for j in range(n):
sum_[i][j] = int(b[i][j]) + int(g[i][j]) + int(r[i][j])
hists, bins = np.histogram(sum_.flatten(), 766, [0, 766])
Y = 765
num, key = 0, 0
ratio = 0.01
while Y >= 0:
num += hists[Y]
if num > m * n * ratio / 100:
key = Y
break
Y = Y - 1
sum_b, sum_g, sum_r = 0, 0, 0
time = 0
for i in range(m):
for j in range(n):
if sum_[i][j] >= key:
sum_b += int(b[i][j])
sum_g += int(g[i][j])
sum_r += int(r[i][j])
time = time + 1
avg_b = sum_b / time
avg_g = sum_g / time
avg_r = sum_r / time
maxvalue = float(np.max(img))
for i in range(m):
for j in range(n):
b = int(img[i][j][0]) * maxvalue / int(avg_b)
g = int(img[i][j][1]) * maxvalue / int(avg_g)
r = int(img[i][j][2]) * maxvalue / int(avg_r)
if b > 255:
b = 255
if b < 0:
b = 0
if g > 255:
g = 255
if g < 0:
g = 0
if r > 255:
r = 255
if r < 0:
r = 0
img[i][j][0] = b
img[i][j][1] = g
img[i][j][2] = r
return img