色彩空间转换与色差计算算法

本文详细探讨了色彩空间,包括色域和颜色模型的概念,如sRGB、Adobe RGB等。接着阐述了色彩空间转换的重要性,并介绍了几种转换方法。此外,文章深入讨论了色差计算的不同算法,如δC、δE CIE、δE 1994和δE 2000,特别强调了δE 2000在匹配人眼感知方面的优势。附带提供了色彩转换计算脚本。
摘要由CSDN通过智能技术生成

一、色彩空间

1.1 色域

先明确一个概念:色域描述的是颜色的范围,比如:在这个色域里,最红的红到底有多红?

常见的色域都以下面的马蹄图为基础的,这是一个不规则形状的图形,三个端点分别是红色、绿色和蓝色。

不同的色域通常是这个范围的子集,比如:我们常听说的sRGB、NTSC、P3、Adobe RGB、2020、CMYK等。

在这里插入图片描述

这些不同的色域由不同行业、不同的组织、不同的时间定义的。这些色域有重合区域,同样也有不重合区域,如下图所示。

1.2 颜色模型

同样先明确颜色模型的概念:颜色模型定义的是从哪些维度来描述一个颜色。

颜色模型是不同的描述颜色的方法,比如:Lab、RGB、HSL、HSV等,这些不同的色彩模型由不同的专家提出。通过这些模型,能够直观的、以向量的方式把颜色唯一的表示出来。
在这里插入图片描述
在这里插入图片描述

之所以有着多么的颜色模型,可能是因为有两个原因:

  • 各个大师对颜色的理解不同:就像元素周期表也有不同的版本一样;
  • 不同行业对颜色的应用不同:
  • 显示器:是自发光物体,而且本身就以RGB为发光原理;
  • 广播电视:需要兼容黑白和彩色信号,所以以亮度和色度来描述颜色,来达到新旧设备的兼容性,使用YCbCr信号;
  • 印刷行业:印刷品需要反射光来显色,是利用的减色原理,所以使用的是CMY模型;
  • 视频文件:视频压缩需要删除冗余信号,所以使用Yuv模型;
  • ……

二、色彩空间转换

色彩空间转换这个概念针对的是:不同颜色表示方法之间的互相转换,就像角度和弧度的换算,其实说的是一回事。
在这里插入图片描述

这一块的具体计算方法我直接放到文章最后了,因为这一块的难度比较低,但是占太多位置了。

三、色差计算

色差描述的是两个颜色之间的差异,这个同样有不同的算法。

按照我的认知δE 2000应该是最新、最受认可的算法了,它不仅体现出了颜色之间的差异,还根据人眼的感知特性对算法做了修正,让计算结果与人的感知更加匹配。
在这里插入图片描述

3.1 δC

Delta C* = sqrt( ( CIE-a*2 ^ 2 ) + ( CIE-b*2 ^ 2 ) ) - sqrt( ( CIE-a*1 ^ 2 ) + ( CIE-b*1 ^ 2 ) )

可以看出δC的计算方法是很简单粗暴的,就直接取均方值了,且去掉了亮度信息。

3.2 δE CIE

Delta E* = sqrt( ( ( CIE-L*1 - CIE-L*2 ) ^ 2 )+ ( ( CIE-a*1 - CIE-a*2 ) ^ 2 ) + ( ( CIE-b*1 - CIE-b*2 ) ^ 2 ) )

δE CIE的计算方法与上面的类型,但是增加了亮度信息。

这里补充一下关于亮度的个人理解:颜色中的“亮度”描述的是颜色本身的明度信息,显示器的“亮度”描述的是显示器背光灯的发光强度。这两者理论上应该是互相独立的,以LCD型显示器为例:

  • 颜色的亮度:完全取决于显示器R、G、B三个子像素的颜色,而这三个子像素的颜色完全取决于子像素背后的液晶偏转程度和RGB的CF颜色;
  • 显示器的亮度:完全取决于显示器背光模组灯珠的亮度、导光板和其他各层对光的透过率。
    在这里插入图片描述

所以,这两个亮度描述的是2个维度的事,但是从实际观感来看,好像还是会有主观感受上的差异。

3.3 δE 1994

δE1994和2000的计算方法会稍微复杂一些,因为会涉及到一些权重系数,下面是ColorMath的官方Python实现方法。

import numpy
from colormath import color_diff_matrix

def _get_lab_color1_vector(color):
    """
    Converts an LabColor into a NumPy vector.

    :param LabColor color:
    :rtype: numpy.ndarray
    """
    if not color.__class__.__name__ == 'LabColor':
        raise ValueError(
            "Delta E functions can only be used with two LabColor objects.")
    return numpy.array([color.lab_l, color.lab_a, color.lab_b])


def _get_lab_color2_matrix(color):
    """
    Converts an LabColor into a NumPy matrix.

    :param LabColor color:
    :rtype: numpy.ndarray
    """
    if not color.__class__.__name__ == 'LabColor':
        raise ValueError(
            "Delta E functions can only be used with two LabColor objects.")
    return numpy.array([(color.lab_l, color.lab_a, color.lab_b)])


# noinspection PyPep8Naming
def delta_e_cie1976(color1, color2):
    """
    Calculates the Delta E (CIE1976) of two colors.
    """
    color1_vector = _get_lab_color1_vector(color1)
    color2_matrix = _get_lab_color2_matrix(color2)
    delta_e = color_diff_matrix.delta_e_cie1976(color1_vector, color2_matrix)[0]
    return numpy.asscalar(delta_e)

# noinspection PyPep8Naming
def delta_e_cie1994(color1, color2, K_L=1, K_C=1, K_H=1, K_1=0.045, K_2=0.015):
    """
    Calculates the Delta E (CIE1994) of two colors.

    K_l:
      0.045 graphic arts
      0.048 textiles
    K_2:
      0.015 graphic arts
      0.014 textiles
    K_L:
      1 default
      2 textiles
    """
    color1_vector = _get_lab_color1_vector(color1)
    color2_matrix = _get_lab_color2_matrix(color2)
    delta_e = color_diff_matrix.delta_e_cie1994(
        color1_vector, color2_matrix, K_L=K_L, K_C=K_C, K_H=K_H, K_1=K_1, K_2=K_2)[0]
    return numpy.asscalar(delta_e)

# noinspection PyPep8Naming
def delta_e_cie2000(color1, color2, Kl=1, Kc=1, Kh=1):
    """
    Calculates the Delta E (CIE2000) of two colors.
    """
    color1_vector = _get_lab_color1_vector(color1)
    color2_matrix = _get_lab_color2_matrix(color2)
    delta_e = color_diff_matrix.delta_e_cie2000(
        color1_vector, color2_matrix, Kl=Kl, Kc=Kc, Kh=Kh)[0]
    return numpy.asscalar(delta_e)



# noinspection PyPep8Naming
[docs]def delta_e_cmc(color1, color2, pl=2, pc=1):
    """
    Calculates the Delta E (CMC) of two colors.

    CMC values
      Acceptability: pl=2, pc=1
      Perceptability: pl=1, pc=1
    """
    color1_vector = _get_lab_color1_vector(color1)
    color2_matrix = _get_lab_color2_matrix(color2)
    delta_e = color_diff_matrix.delta_e_cmc(
        color1_vector, color2_matrix, pl=pl, pc=pc)[0]
    return numpy.asscalar(delta_e)

3.4 δE 2000

在δE 2000的计算过程中,有WHT-L、WHT-C、WHT-H三个权重参数的设置。

下面的Python实现是我根据EasyRGB上的脚本进行改动实现的。

import math
# 第一个颜色的Lab值
CIE_L1, CIE_a1, CIE_b1 = 60, 5
  • 7
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RGB空间转换为HSV色彩空间算法如下: 1. 首先,找出RGB三个分量中的最大值和最小值,分别记为max和min。 2. 计算亮度值V,即V = max(R, G, B)。 3. 计算饱和度值S,即S = (max - min) / max。注意,如果max为0,则饱和度为0。 4. 计算色调值H,根据RGB分量的关系进行判断: - 如果max和min相等,则色调H为0。 - 如果max等于R且G大于等于B,则H = (G - B) / (max - min) * 60。 - 如果max等于R且G小于B,则H = (G - B) / (max - min) * 60 + 360。 - 如果max等于G,则H = (B - R) / (max - min) * 60 + 120。 - 如果max等于B,则H = (R - G) / (max - min) * 60 + 240。 注意,如果计算得到的H小于0,则H = H + 360。 这样就完成了RGB空间到HSV色彩空间转换。HSV色彩空间是一种直观的颜色模型,其中色调表示主色,饱和度表示颜色的鲜艳程度,亮度表示颜色的明亮程度。这种转换可以在图像编辑工具中广泛应用,如Photoshop等。 #### 引用[.reference_title] - *1* [RGB与HSV颜色空间转换](https://blog.csdn.net/xiaoyafang123/article/details/113029986)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [数字图像处理与Python实现-颜色空间转换-RGB颜色空间与HSV颜色空间转换](https://blog.csdn.net/wujuxKkoolerter/article/details/107169605)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值