python - 具有灰色世界假设的自动白平衡

标签 python opencv numpy image-processing

我一直在尝试实现以下提供的白平衡算法: https://pippin.gimp.org/image-processing/chapter-automaticadjustments.html

我已经使用 python 和 opencv 来实现它们。我无法生成与网站中相同的结果。

例如,在灰色世界假设中,我使用以下代码:

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)

我得到了结果

代替

我哪里错了?

最佳答案

您正在实现的文档不了解 LAB definition 的 CV 内部约定在 8 位颜色深度的情况下。

特别是:

L: L / 100 * 255
A: A + 128
B: B + 128

我相信这样做是为了提高准确性,因为这样就可以完全使用 unsigned int8 精度来表示亮度,同时为整个数组保持一致的无符号数据类型。

下面的代码改编自您的代码应该可以工作。 请注意,这里和那里有一些小的修复(编辑,包括将有趣的代码包装在一个函数中),但实际的调味料在嵌套的for 循环。

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)

编辑:

相同的结果,但通过避免循环可以获得更快的性能:

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

这显然给出了相同的结果:

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

关于python - 具有灰色世界假设的自动白平衡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46390779/

相关文章:

python - 如何从 POST 变量保存文件数据并将其加载回 Python Django 中的响应?

opencv - 在Haar级联训练中numPos可以为负数吗

java - 如何解决 "java.lang.UnsatisfiedLinkError: Can' t find dependent libraries"without System32?

python - 理解 Python 中的 Axis

python - 如何在 powershell 中搜索字符串并删除该行?

python - 当列包含字符串值时 pandas DataFrame.sum 的奇怪行为

opencv - 在OpenCV中自动选择最佳的JPEG压缩?

python - 按百分位数对 python 字典进行排名

Python:非常慢的执行循环

python - 快速 Python/Numpy 频率严重性分布模拟