使用Grayworld假设自动进行白平衡 [英] Automatic White Balancing with Grayworld assumption

查看:232
本文介绍了使用Grayworld假设自动进行白平衡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试实现以下提供的白平衡算法: 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆