Automatic White Balancing with Grayworld assumption

后端 未结 1 1512
广开言路
广开言路 2020-12-16 04:50

I have been trying to implement the white balancing algorithms provided by: https://pippin.gimp.org/image-processing/chapter-automaticadjustments.html

I have used py

相关标签:
1条回答
  • 2020-12-16 04:54

    The document you are implementing is not aware of CV internal conventions for LAB definition in case of 8-bit color depth.

    In particular:

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

    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.

    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)
    

    EDIT:

    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
    

    but with very different timings:

    %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
    
    0 讨论(0)
提交回复
热议问题