How to compute the Delta E between two images

情到浓时终转凉″ 提交于 2020-07-15 07:54:26

问题


I'm currently trying to determine the color difference between our output image and a painting of Monet with Python using OpenCV.

With my research I've seen that Delta E is the best for determining color difference. I've tried using extracting the BGR Channels of the two images and then taking the mean "Blue" "Green" and "Red" color used to use for computing the difference of each color channel.

output_chans = cv2.split(image)
monet_chans = cv2.split(best_painting)
colors = ("Blue", "Green", "Red")

for (output_chan, monet_chan, color) in zip(output_chans, monet_chans, colors):
    output_mean = np.mean(output_chan)
    monet_mean = np.mean(monet_chan)

    color1_rgb = None
    color2_rgb = None

    if color == "Blue":
            color1_rgb = sRGBColor(0.0, 0.0, output_mean)
            color2_rgb = sRGBColor(0.0, 0.0, monet_mean)
    elif color == "Green":
            color1_rgb = sRGBColor(0.0, output_mean, 0.0);
            color2_rgb = sRGBColor(0.0, monet_mean, 0.0);
    elif color == "Red":
            color1_rgb = sRGBColor(output_mean, 0.0, 0.0);
            color2_rgb = sRGBColor(monet_mean, 0.0, 0.0);

    # Convert from RGB to Lab Color Space
    color1_lab = convert_color(color1_rgb, LabColor);

    # Convert from RGB to Lab Color Space
    color2_lab = convert_color(color2_rgb, LabColor);

    # Find the color difference
    delta_e = delta_e_cie2000(color1_lab, color2_lab);

    print("Delta E of the Mean of %s Channel: %f" % (color, delta_e))

I receive an output of for the color difference for each color channel, however my professor suggests that I may be doing Delta E wrong as I'm supposed to only get one value for the color difference of the entire image instead of one value for each three color channels. In this case is there an alternative method or a correct method of of calculating the Delta E of our two images?

This is a link to a sample of our test image: https://imgur.com/a/KToggFS

And a link to a sample of the paintings: https://imgur.com/a/vi1SFax


回答1:


you seem to be using the colormath library which does the math nicely, but is very slow. the colour-science package uses numpy to vectorise operations and get an answer in much less time

the cv2 library you're using has simple versions of some of the transformations you need, e.g. you can get most of the way doing:

import cv2

image1_rgb = cv2.imread('image1.jpeg')
image2_rgb = cv2.imread('image2.jpeg')

image1_lab = cv2.cvtColor(image1_rgb, cv2.COLOR_RGB2Lab)
image2_lab = cv2.cvtColor(image2_rgb, cv2.COLOR_RGB2Lab)

but note that you'll probably get better results if you convert to floats first:

image_lab = cv2.cvtColor(image_rgb.astype(np.float32) / 255, cv2.COLOR_RGB2Lab)

and then just use color-science for the final call to delta_E() for each pixel (but note these are all vectorised, so you just give it the array of everything and it does it all efficiently at once):

import colour

delta_E = colour.delta_E(image1_lab, image2_lab)

and then you'll probably want the mean of this over the whole image:

np.mean(delta_E)

but median, quantiles, or a plotting the distribution would give you more information

note that if you care about color spaces and need more control over the transform from RGB to Lab you get a lot more control with colour-science, with the rough template looking like:

image_lab = colour.XYZ_to_Lab(colour.sRGB_to_XYZ(image_srgb))

and there are lots of options about how to do this transform along the way, see docs for colour.XYZ_to_Lab and colour.XYZ_to_Lab.



来源:https://stackoverflow.com/questions/57224007/how-to-compute-the-delta-e-between-two-images

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!