CIE颜色空间LCh、Lab、XYZ-sRGB介绍与转换关系(包含源码)

news2024/12/23 8:46:50

项目场景:

提示:在颜色科学中,LCh和Lab是比较常用的

LCh是由MATLAB计算出的数据,但是我所需要在Qt的q3dsurface绘制出这个切面,看了Qt官方Examples,墨西哥草帽算法的3D模型就是由XYZ组成的。所以我需要LCh->Lab->XYZ,这三步的转换。


LCh、Lab、XYZ概念

  • LCh
    CIELCh颜色空间用于描述颜色的亮度、色度和色相。
    CIELCh颜色空间相比CIELAB颜色空间更加直观,它以极坐标形式表示颜色属性,更适合描述颜色的外观特征和感知属性。
    Lightness(L)指的是颜色的明暗程度或亮度级别。它表示颜色相对于中性灰色的明暗程度,取值范围通常为0到100。较低的亮度值接近黑色,较高的亮度值接近白色。
    Chroma(C)表示颜色的饱和度或色彩的强度。它衡量的是颜色相对于中性灰色的纯度或饱和度。较低的色度值表示颜色较暗或接近灰色,而较高的色度值表示颜色鲜艳、饱和度较高。
    Hue表示色相(h),取值范围为0到360度,表示颜色在色轮上的位置。

  • Lab
    CIELAB颜色空间是通过对人眼对不同光谱刺激的感知进行数学建模而得到的。
    L表示亮度(Lightness),取值范围为0到100,表示从黑到白的亮度级别。
    a表示颜色在红绿轴上的位置,取值范围为-128到+127,其中负值表示绿色,正值表示红色。
    b表示颜色在黄蓝轴上的位置,取值范围为-128到+127,其中负值表示蓝色,正值表示黄色。

  • XYZ
    X表示颜色在红-绿轴上的位置。
    Y表示颜色在亮度轴上的位置。
    Z表示颜色在黄-蓝轴上的位置。


LCh转Lab

  1. 获取LCh颜色空间中的L、Chroma和Hue分量的值。
  2. 计算Lab颜色空间中的a和b分量,可以使用以下公式:a = Chroma * cos(Hue),b = Chroma * sin(Hue)。
  3. 最终的Lab颜色空间中的分量为L、a和b。

CIELab颜色空间中的三个分量对应于3D坐标空间中的以下轴
L(亮度):对应于Y轴,表示颜色的明暗程度。
a(红绿):对应于X轴,表示颜色在红色和绿色之间的位置。
b(黄蓝):对应于Z轴,表示颜色在黄色和蓝色之间的位置。

#include <cmath>

void LChToLab(double L, double Chroma, double Hue, double& Lab_L, double& Lab_a, double& Lab_b)
{
    Lab_a = Chroma * std::cos(Hue);
    Lab_b = Chroma * std::sin(Hue);
    Lab_L = L;
}

L表示LCh颜色空间中的亮度分量,Chroma表示色度分量,Hue表示色相分量。通过调用该函数并传入LCh颜色的分量值,即可获得对应的Lab颜色空间中的L、a和b分量的值


Lab转XYZ

  1. 获取Lab颜色空间中的L、a和b分量的值。
  2. 将Lab中的L、a和b分量进行逆变换,得到对应的线性RGB颜色空间中的R、G和B分量。这可以通过使用Lab到XYZ转换矩阵来实现。
  3. 将线性RGB颜色空间中的R、G和B分量进行非线性校正,以获得标准化的RGB值。
  4. 将标准化的RGB值转换为XYZ颜色空间中的X、Y和Z分量,也可以通过使用RGB到XYZ转换矩阵来实现。
  5. 再转成sRGB。
void LabToXYZ(double Lab_L, double Lab_a, double Lab_b, double& XYZ_X, double& XYZ_Y, double& XYZ_Z)
{
    // Lab到XYZ转换矩阵
    double Xr = 0.95047;
    double Yr = 1.00000;
    double Zr = 1.08883;

    double fy = (Lab_L + 16.0) / 116.0;
    double fx = fy + (Lab_a / 500.0);
    double fz = fy - (Lab_b / 200.0);

    double xr = (std::pow(fx, 3.0) > 0.008856) ? std::pow(fx, 3.0) : ((fx - 16.0 / 116.0) / 7.787);
    double yr = (Lab_L > (903.3 * 0.008856)) ? std::pow((Lab_L + 16.0) / 116.0, 3.0) : (Lab_L / 903.3);
    double zr = (std::pow(fz, 3.0) > 0.008856) ? std::pow(fz, 3.0) : ((fz - 16.0 / 116.0) / 7.787);

    XYZ_X = xr * Xr;
    XYZ_Y = yr * Yr;
    XYZ_Z = zr * Zr;
}

在函数中,Lab_L、Lab_a和Lab_b分别表示Lab颜色空间中的L、a和b分量的值。通过调用该函数并传入Lab颜色的分量值,即可获得对应的XYZ颜色空间中的X、Y和Z分量的值。请注意,示例中的转换矩阵参数(Xr、Yr和Zr)是用于D65标准光源的参数,你可以根据需要调整它们以适应不同的光源。

Demo

#include <iostream>
#include <vector>
#include <cmath>

struct Lab {
    int L;
    int a;
    int b;
};

struct XYZ {
    int X;
    int Y;
    int Z;
};

XYZ convertLabtoXYZ(const Lab& lab)
{
    double L = lab.L / 100.0;
    double a = (lab.a - 128) / 127.0;
    double b = (lab.b - 128) / 127.0;

    double X = 0.95047 * pow(((L + 0.16) / 1.16), 3.0);
    double Y = 1.00000 * pow(((L + 0.16) / 1.16), 3.0);
    double Z = 1.08883 * pow(((L + 0.16) / 1.16), 3.0);

    X = X + (0.43607 * a) - (0.39894 * b);
    Y = Y - (0.00003 * a) + (0.03951 * b);
    Z = Z + (0.00816 * a) + (0.01388 * b);

    XYZ xyz;
    xyz.X = static_cast<int>(X * 100);
    xyz.Y = static_cast<int>(Y * 100);
    xyz.Z = static_cast<int>(Z * 100);

    return xyz;
}

int main()
{
    // 示例使用
    int N = 3;
    std::vector<Lab> labValues(N);
    std::vector<XYZ> xyzValues(N);

    // 假设输入的LAB值
    labValues[0] = {50, 0, 0};
    labValues[1] = {75, 30, -40};
    labValues[2] = {90, -10, 20};

    // 将每个LAB值转换为XYZ值
    for (int i = 0; i < N; ++i) {
        xyzValues[i] = convertLabtoXYZ(labValues[i]);
    }

    // 打印转换后的XYZ值
    for (int i = 0; i < N; ++i) {
        XYZ xyz = xyzValues[i];
        std::cout << "Lab: L=" << labValues[i].L << ", a=" << labValues[i].a << ", b=" << labValues[i].b
                  << " -> XYZ: X=" << xyz.X << ", Y=" << xyz.Y << ", Z=" << xyz.Z << std::endl;
    }

    return 0;
}

这边举了3组数据进行计算。
在这里插入图片描述
完结撒花,球球一件三联噢,这真的对我很重要
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/543901.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何让“ChatGPT自己写出好的Prompt的“脚本在这里

写个好的Prompt太费力了 在网上&#xff0c;你可能会看到很多人告诉你如何写Prompt&#xff0c;需要遵循各种规则&#xff0c;扮演不同的角色&#xff0c;任务明确、要求详细&#xff0c;还需要不断迭代优化。写一个出色的Prompt需要投入大量的时间和精力。甚至有一些公开的Pr…

风靡 B 站的《看漫画学 Python》到底是什么来头?

学习 Python 的小伙伴大部分应该都知道《看漫画学 Python&#xff1a;有趣、有料、好玩、好用&#xff08;全彩版&#xff09;》这本书&#xff01; 毕竟&#xff0c;如果在 B 站搜索“漫画 Python”等相关关键词&#xff0c;会看到整个页面都是和这本书相关的视频…… 郑重声…

2023世界旅游经济趋势报告发布,中国旅游日期间博冠8K发起慢直播一日游活动

一、2023世界旅游经济趋势报告重点解读 &#xff08;1&#xff09;全球旅游恢复至疫情前六至八成 近日&#xff0c;世界旅游城市联合会和中国社会科学院旅游研究中心联合发布了《世界旅游经济趋势报告&#xff08;2023》&#xff0c;指出2022年全球旅游总人次达到95.7亿人次&…

谷歌扩展开发v3版本,自动请求接口

背景&#xff1a;pc端项目要是1个小时不动不请求&#xff0c;token会过期&#xff0c;写个插件每隔一段时间自动取请求一个接口&#xff0c;让token不过期过程&#xff1a;在刚开始写的时候 网上大部分是 谷歌扩展开发v2版本的做法&#xff0c;先是把官方文档看了一下&#xff…

计算机论文写作规范

什么是顶会 顶级会议一般是,在业界(本领域本方向)受到广泛的承认,影响力较大的会议。一方面一般顶级专家、学者都倾向于将paper投到这些 会议;另一方面这些会议的论文代表了该领域的目前很优秀、有重大意义的进展。"顶级会议"的投稿竞争压力一般都很大,属于在经典 p…

【k8s】Jenkins实现Java应用CI、CD实践 【二】【待写】

一、运行Jenkins流水线流程思路&#xff1a; 场景1&#xff1a;常规java应用&#xff0c;使用jenkins pipeline 交付到Kubernetes集群中1、准备好java代码、Dockerfile、 deploy. yaml资源清单文件CI阶段: 1、获取代码 2、漏洞扫描 3、检测漏洞扫描结果&#xff0c;如果正常则…

MySQL8.0卸载、安装和使用(一)

1、MySQL数据库的卸载 有小伙伴在学MySQL的时候总是出现各种问题&#xff0c;MySQL的安装都会出现许多问题&#xff0c;今天以MySQL8.0作为示范&#xff0c;需要注意的问题和正确的使用方式。因为MySQL是系统软件&#xff0c;相对复杂&#xff0c;因此先讲卸载。 步骤一&#x…

病毒丨文件夹病毒

作者丨黑蛋 一、基本信息 文件名称 880753802c3e6f4b5269062d4e76200c66e3a71e2118702e24d2b32c19dddfd2 文件类型(Magic) PE32 executable (GUI) Intel 80386, for MS Windows 文件大小 479.50KB SHA256 880753802c3e6f4b5269062d4e76200c66e3a71e2118702e24d2b32c19dddfd2 …

青龙面板使用教程,以及安装

1. 青龙面板使用教程&#xff0c;以及安装 首先青龙面板是在docker里面的&#xff0c;我们要安装一个docker 我这里只有debian 11 安装的教程 如何在debian11上安装docker - 知乎 这个文章不错了&#xff0c;按命令执行就好了&#xff0c;其他操作系统的。去网上搜索安…

Unity - BRP - PP后效导致 Camera.targetTexture 被换掉,graphicsFormat 不对问题

文章目录 环境目的原因问题解决方法 环境 Unity : 国际版2020.3.37f1 Pipeline : BRP Packages: Post Processing 3.0.3 目的 BRP 虽然是 官方放弃更新的 渲染管线&#xff0c;但是有些项目仍然会使用到&#xff0c;有一些踩过的坑&#xff0c;该记录的还是记录一下&#xff…

Python爬虫入门 - 通过茅台脚本讲些爬虫知识,应用和价值

前言 前段时间抢茅台脚本非常火&#xff0c;它是 Python 脚本&#xff0c;加上刚好最近在学习 Python&#xff0c;我们准备通过这个脚本&#xff0c;来加深学习 Python。 抢茅台的脚本其实属于爬虫脚本的一类&#xff0c;它实现了模拟登陆&#xff0c;模拟访问并抓取数据。于…

chatgpt api调用方法指南

文章目录 python调用chatgpt api的方法获取api可以调用的模型各种任务代码示例文本分类任务文本生成&#xff08;补全&#xff09;任务多轮对话任务 机器翻译任务文本摘要任务信息抽取任务 本文主要介绍使用python调用chatgpt api的方法&#xff0c;并提供一些任务的代码样例&a…

2023年认证杯C题超详细思路配有实现代码

2023年认证杯初步解题思路 后续会更新思路对应的实现代码 问题一思路 数据预处理&#xff1a;首先&#xff0c;根据描述&#xff0c;你已经有了心电波形的功率谱密度数据。你可以将频率范围从0 Hz到180 Hz分成361个频率间隔为0.5 Hz的数据点。确保数据格式正确&#xff0c;并…

chatgpt赋能Python-python2虚拟环境

Python2虚拟环境——加强你的编程能力 Python是一种广泛应用于Web开发&#xff0c;数据科学和机器学习等领域的编程语言。但是&#xff0c;由于不同的应用程序需要使用不同的Python库和版本&#xff0c;因此在不同的项目之间切换时可能会出现问题。 Python虚拟环境可以帮助您解…

八股总结(五)java基础、集合、并发、JVM

文章目录 接口、类与继承java中创建对象有哪几种方式&#xff1f; 和equal区别是什么&#xff1f;hashCode()为什么重写equals方法必须重写hashcode方法?String为什么设计成不可变的&#xff1f;String&#xff0c;StringBuffer&#xff0c;StringBuilder的区别是什么&#xf…

2023年改版第七版PMBOK后的PMP到底考什么?出题依据是什么?

2023年改版第七版PMBOK后的PMP到底考什么&#xff1f;出题依据是什么&#xff1f; 自从PMBOK&#xff08;Project Management Body of Knowledge&#xff09;第一版于1987年发布以来&#xff0c;它已成为项目管理领域的标准参考。PMBOK指南是Project Management Institute&…

Python画图设置坐标轴数字的千位分隔符

目录 导入必要的库创建图形并设置坐标轴设置坐标轴的千位分隔符完整代码效果图 当使用Python进行绘图时&#xff0c;可以使用 Matplotlib库来设置坐标轴上的数字的千位分隔符。下面是一个完整的教程&#xff0c;其中包含代码示例。 导入必要的库 在开始编写代码之前&#xff…

Java学习平台系统的设计与实现

背景 本次设计任务是要设计一个学习平台&#xff0c;通过这个系统能够满足学习信息的管理及学生和教师的学习管理功能。系统的主要功能包括首页&#xff0c;个人中心&#xff0c;学生管理&#xff0c;教师管理&#xff0c;课程信息管理&#xff0c;类型管理&#xff0c;作业信…

使用sqoop从Hive导出数据到MySQL

1、启动hadoop&#xff1a;start-all.sh。 2、启动mysql&#xff1a;support-files/mysql.server start。 3、启动hive&#xff1a;hive。 4、在hive中创建表。 &#xff08;学生信息&#xff1a;学号xh&#xff0c;姓名xm&#xff09;xsxx&#xff1a; create table bigda…

streamlit魔法使用

正常在学习一个新框架之前&#xff0c; 肯定要先调研下这个框架究竟能做些什么事吧&#xff1f; 但对于 streamlit 来说&#xff0c;请你相信我&#xff0c;这是一个你可以无脑去学习的框架&#xff0c;我之所以这么说&#xff0c;是因为我相信终有一天&#xff0c;你一定能用…