python图片由RGB空间转成LAB空间的实现方式

 更新时间:2023年10月12日 14:56:11   作者:Fly~~  
这篇文章主要介绍了python图片由RGB空间转成LAB空间的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

python图片由RGB空间转成LAB空间

RGB转Lab颜色空间

RGB颜色空间不能直接转换为Lab颜色空间,需要借助XYZ颜色空间,把RGB颜色空间转换到XYZ颜色空间,之后再把XYZ颜色空间转换到Lab颜色空间。

RGB与XYZ颜色空间有如下关系:

其中m如下:

XYZ到LAB的转换公式如下

X_(1,) Y_(1,) Z_(1,)分别是X,Y,X线性归一化之后的值,其中f(x)如下:

python实现

import numpy as np
import cv2
# region 辅助函数
# RGB2XYZ空间的系数矩阵
M = np.array([[0.412453, 0.357580, 0.180423],
              [0.212671, 0.715160, 0.072169],
              [0.019334, 0.119193, 0.950227]])
# im_channel取值范围:[0,1]
def f(im_channel):
    return np.power(im_channel, 1 / 3) if im_channel > 0.008856 else 7.787 * im_channel + 0.137931
def anti_f(im_channel):
    return np.power(im_channel, 3) if im_channel > 0.206893 else (im_channel - 0.137931) / 7.787
# endregion
# region RGB 转 Lab
# 像素值RGB转XYZ空间,pixel格式:(B,G,R)
# 返回XYZ空间下的值
def __rgb2xyz__(pixel):
    b, g, r = pixel[0], pixel[1], pixel[2]
    rgb = np.array([r, g, b])
    # rgb = rgb / 255.0
    # RGB = np.array([gamma(c) for c in rgb])
    XYZ = np.dot(M, rgb.T)
    XYZ = XYZ / 255.0
    return (XYZ[0] / 0.95047, XYZ[1] / 1.0, XYZ[2] / 1.08883)
def __xyz2lab__(xyz):
    """
    XYZ空间转Lab空间
    :param xyz: 像素xyz空间下的值
    :return: 返回Lab空间下的值
    """
    F_XYZ = [f(x) for x in xyz]
    L = 116 * F_XYZ[1] - 16 if xyz[1] > 0.008856 else 903.3 * xyz[1]
    a = 500 * (F_XYZ[0] - F_XYZ[1])
    b = 200 * (F_XYZ[1] - F_XYZ[2])
    return (L, a, b)
def RGB2Lab(pixel):
    """
    RGB空间转Lab空间
    :param pixel: RGB空间像素值,格式:[G,B,R]
    :return: 返回Lab空间下的值
    """
    xyz = __rgb2xyz__(pixel)
    Lab = __xyz2lab__(xyz)
    return Lab
if __name__ == '__main__':
    img = cv2.imread(r'2020_94470.jpg')
    w = img.shape[0]
    h = img.shape[1]
    img_new = np.zeros((w, h, 3))
    lab = np.zeros((w, h, 3))
    for i in range(w):
        for j in range(h):
            Lab = RGB2Lab(img[i, j])
            lab[i, j] = (Lab[0], Lab[1], Lab[2])
        cv2.imwrite(r'00000122_1.jpg', lab)

比较颜色相似度,RGB空间转Lab空间

import numpy as np
from colormath.color_objects import LabColor, sRGBColor
from colormath.color_conversions import convert_color
from colormath.color_diff import delta_e_cie2000
np.set_printoptions(np.inf)
class Color(object):
    def __init__(self, color_file = 'color_list.txt'):
        self.color_name_en = []
        self.color_name_zh = []
        self.color_HEX = []
        self.color_RGB = []
        self.color_Lab = []
        self.readColorFile(color_file)
    def readColorFile(self, color_file):
        with open(color_file, 'r', encoding='utf-8') as f:
            colors = f.readlines()
        for color in colors:
            lc = color.split('\t')
            self.color_name_en.append(lc[0].strip())
            self.color_name_zh.append(lc[1].strip())
            self.color_HEX.append(lc[2].strip())
            rgb = lc[3].strip().split(',')
            rgb = [int(v) for v in rgb]
            self.color_RGB.append(rgb)
        self.rgbToLab()
    def rgbToLab(self):
        for rgb in self.color_RGB:
            srgb = sRGBColor(*rgb)
            lab = convert_color(srgb, LabColor)
            self.color_Lab.append(lab)
    def getMinCIE2000Distance(self, rgb):
        srgb = sRGBColor(*rgb)
        tlab = convert_color(srgb, LabColor)
        min_index = -1
        min_delta_e = np.inf
        for idx, lab in enumerate(self.color_Lab):
            delta_e = delta_e_cie2000(tlab, lab)
            if delta_e < min_delta_e:
                min_delta_e = delta_e
                min_index = idx
        return min_delta_e, min_index
    def calculateRGBDistance(self, rgb=(0,0,0)):
        array_rgb = np.array(self.color_RGB)
        print(array_rgb)
        print(array_rgb.shape)
        temp1_rgb = (rgb - array_rgb) / 255
        temp2_rgb = temp1_rgb[:,0]*temp1_rgb[:,0] + temp1_rgb[:,1]*temp1_rgb[:,1] + temp1_rgb[:,2]*temp1_rgb[:,2]
    def __getitem__(self, index):
        info = f"英文代码 : {self.color_name_en[index]}\n"
        info += f"形象颜色 : {self.color_name_zh[index]}\n"
        info += f"HEX格式 : {self.color_HEX[index]}\n"
        info += f"RGB格式 : {self.color_RGB[index]}\n"
        info += f"Lab格式 : {self.color_Lab[index]}\n\n"
        return info
    def __len__(self):
        assert len(self.color_name_en) == len(self.color_name_zh)
        assert len(self.color_name_en) == len(self.color_HEX)
        assert len(self.color_name_en) == len(self.color_RGB)
        return len(self.color_name_en)
if __name__ == '__main__':
    c = Color()
    rgb = (123, 145, 111)
    delta_e, index = c.getMinCIE2000Distance(rgb)
    print(delta_e, index)
    print(c[index])

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • python数据结构之链表的实例讲解

    python数据结构之链表的实例讲解

    下面小编就为大家带来一篇python数据结构之链表的实例讲解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • 使用pandas实现连续数据的离散化处理方式(分箱操作)

    使用pandas实现连续数据的离散化处理方式(分箱操作)

    今天小编就为大家分享一篇使用pandas实现连续数据的离散化处理方式(分箱操作),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • Python NumPy教程之数组的创建详解

    Python NumPy教程之数组的创建详解

    这篇文章主要为大家详细介绍了Python NumPy中数组的创建方式,文中的示例代码讲解详细,对我们学习Python有一定帮助,需要的可以参考一下
    2022-08-08
  • 详解Python 4.0 预计推出的新功能

    详解Python 4.0 预计推出的新功能

    这篇文章主要介绍了详解Python 4.0 预计推出的新功能,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-07-07
  • python从PDF中提取数据的示例

    python从PDF中提取数据的示例

    这篇文章主要介绍了python从PDF中提取数据的示例,帮助大家提高办公效率,感兴趣的朋友可以了解下
    2020-10-10
  • 基于pygame实现童年掌机打砖块游戏

    基于pygame实现童年掌机打砖块游戏

    这篇文章主要为大家详细介绍了基于pygame实现童年掌机打砖块游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • python抓取搜狗微信公众号文章

    python抓取搜狗微信公众号文章

    这篇文章主要为大家详细介绍了python抓取搜狗微信公众号文章,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-04-04
  • python排序的方法实例总结

    python排序的方法实例总结

    在本篇文章里小编给大家整理的是一篇关于python排序的方法实例总结内容,有兴趣的朋友们可以学习下。
    2021-04-04
  • Python使用re模块正则提取字符串中括号内的内容示例

    Python使用re模块正则提取字符串中括号内的内容示例

    这篇文章主要介绍了Python使用re模块正则提取字符串中括号内的内容,结合实例形式分析了Python使用re模块进行针对括号内容的正则匹配操作,并简单解释了相关修正符与正则语句的用法,需要的朋友可以参考下
    2018-06-06
  • 为python设置socket代理的方法

    为python设置socket代理的方法

    这篇文章主要介绍了为python设置socket代理的方法,需要的朋友可以参考下
    2015-01-01

最新评论