首页 > 编程语言 >一种基于DeltaE(CIE 1976)的找色算法

一种基于DeltaE(CIE 1976)的找色算法

时间:2023-06-30 16:24:20浏览次数:40  
标签:const CIE 1976 找色 float uint8 param fY 256

// QuickFinder.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#define _USE_MATH_DEFINES
#include <cmath>
#include <ctime>

unsigned char buf[1080][1920][3];

const float param_13 = 1.0f / 3.0f;
const float param_16116 = 16.0f / 116.0f;
const float Xn = 0.950456f;
const float Yn = 1.0f;
const float Zn = 1.088754f;

inline float gamma(float x)
{
	return x > 0.04045 ? powf((x+0.055f) / 1.055f, 2.4f) : (x / 12.92);
}

float bL[256][256][256];
float ba[256][256][256];
float bb[256][256][256];

inline void RGB2Lab(uint8_t R, uint8_t G, uint8_t B, float &L, float &a, float &b)
{
	float RR = gamma(R / 255.0);
	float GG = gamma(G / 255.0);
	float BB = gamma(B / 255.0);

	float X,Y,Z,fX, fY, fZ;

	X = 0.4124564f * RR + 0.3575761f * GG + 0.1804375f * BB;
	Y = 0.2126729f * RR + 0.7151522f * GG + 0.0721750f * BB;
	Z = 0.0193339f * RR + 0.1191920f * GG + 0.9503041f * BB;

	X /= (Xn);
	Y /= (Yn);
	Z /= (Zn);

	if (Y > 0.008856f)
		fY = pow(Y, param_13);
	else
		fY = 7.787f * Y + param_16116;

	if (X > 0.008856f)
		fX = pow(X, param_13);
	else
		fX = 7.787f * X + param_16116;

	if (Z > 0.008856)
		fZ = pow(Z, param_13);
	else
		fZ = 7.787f * Z + param_16116;

	L = 116.0f * fY - 16.0f;
	L = L > 0.0f ? L : 0.0f;
	a = 500.0f * (fX - fY);
	b = 200.0f * (fY - fZ);
}

void initTable()
{
	for (int r = 0; r < 256; r++)
		for (int g = 0; g < 256; g++)
			for (int b = 0; b < 256; b++)
				RGB2Lab(r, g, b, bL[r][g][b], ba[r][g][b], bb[r][g][b]);
}

inline void TableRGB2Lab(uint8_t R, uint8_t G, uint8_t B, float& L, float& a, float& b)
{
	L = bL[R][G][B];
	a = ba[R][G][B];
	b = bb[R][G][B];
}

//计算颜色之间的Delta E
//<= 1.0:人眼无法感知差异
//1 - 2:仔细观察可以感知差异
//2 - 10:随意一看便可以感知差异
//11 - 49:色彩的相似程度大于相反程度
//100:色彩完全失真

//CIE 1976
inline float DeltaE(float L1,float a1,float b1, float L2, float a2, float b2)
{
	float deltaL = L1 - L2;
	float deltaA = a1 - a2;
	float deltaB =b1 - b2;
	return sqrt(deltaL * deltaL + deltaA * deltaA + deltaB * deltaB);
}


int main()
{
	int  st = clock();

	initTable();

	printf("Init Table %d\n", clock() - st);

	for (int i = 0; i < 1080; i++)
	{
		for (int j = 0; j < 1920; j++)
			buf[i][j][0] = rand() % 256, buf[i][j][1] = rand() % 256, buf[i][j][2] = rand() % 256;
	}

	unsigned char target[] = { 23,23,23 };
	float tL, ta, tb;
	RGB2Lab(target[2], target[1], target[0], tL, ta, tb);

	int count = 0;

	 st = clock();

	for (int i = 0; i < 1080; i++)
	{
		for (int j = 0; j < 1920; j++)
		{
			float L=0, a=0, b=0;
			TableRGB2Lab(buf[i][j][2], buf[i][j][1], buf[i][j][0], L, a, b);
			if (DeltaE(L, a, b, tL, ta, tb) < 2)
				count++;
		}
	}

	printf("%d", clock() - st);
	printf("\nret: %d", count);
	return 0;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

在i9 13900HX上取得 1080P 58ms的成绩,主要是读取table过慢

标签:const,CIE,1976,找色,float,uint8,param,fY,256
From: https://www.cnblogs.com/Icys/p/DeltaE.html

相关文章

  • 华为认证 | 数通HCIE烂大街了?真相是……
    当然没有!对于从事网络相关行业的人来说,HCIE证书是一个对自身实力很好的证明,能够帮你获得升职加薪。01为什么很多人考HCIE数通HCIE考试难度很高,不管是哪个方向,都不会烂大街的,现在的招聘市场上,HCIE仍是供不应求的状态。数通作为基础方向,市场需求量还是蛮大的,相较于其他方向而言,数通......
  • 明德扬FPGA核心板Xilnx开发Lattice光纤7K325T410T光纤PCIE口DDR3
                   ......
  • 明德扬FPGA核心板Xilnx开发Lattice光纤7K325T410T光纤PCIE口DDR3
    ......
  • PCI与PCIE区别和速度比较
    您是否对PCI和PCIe感到困惑?如果你不知道如何区分它们,你可以阅读这篇文章,从功能、外观、速度和兼容性4个方面解释了它们的区别。什么是PCI和PCIExpress?在计算机中,如果不同的设备想要交换数据,它们必须通过某个通道(即总线)进行交换。总线是用于在计算机的各个功能部件之......
  • CF1393E2 Twilight and Ancient Scroll
    显然有一个\(|S|\log|S|\)的dp做法,但是瓶颈在给字符串排序。也就是真正的瓶颈在于求lcp。AFewSuns给出了一种不需要科技的做法,orz。第一个排序的部分,令\(t_{i,j}\)代表第\(i\)个字符串去掉第\(j\)个字符后的字符串,要给所有\(t_{i,j}\)排序。注意到相同颜色段是可......
  • CF321C Ciel the Commander 题解 点分治
    题目链接:http://codeforces.com/problemset/problem/321/C解题思路:点分治模板题。每次找到重心给他分配一个字符,分治往下走的时候分配的字符ASCII码\(+1\)即可。示例程序:#include<bits/stdc++.h>usingnamespacestd;constintmaxn=1e5+5;vector<int>g[maxn];i......
  • Could not load file or assembly 'XXX' or one of its dependencies.
    今天我在用VS2010的时候,突然蓝屏,然后一个WEB程序执行就会报怪异的问题:Couldnotloadfileorassembly'XXX'oroneofitsdependencies.而且其他WEBProject不报任何错误。这个WEB程序我正在做调试,害得的一直以为这个程序出问题了。其实是VS2010的缓存文件除了问题。只需要:删除......
  • pcie reset系列之 内核框架
    FLR是pcireset的一种。关于FLR的寄存器操作比较简单,相关的寄存器有:配置空间里devicecap里的FLRcapabilitybit,这个表示设备是否支持FLR。配置空间里devicecontrol里的BCR_FLRbit,写这个bit可以触发FLR。调用函数检测是否支持FLR:/*drivers/pci/pci.c*/pcie_has_......
  • 【Coursera学习笔记】 Executive Data Science(A Crash Course in Data Science)
    文章目录1.Whatisstatisticsgoodfor?1.1Statistics2.Whatismachinelearning?2.1Twomainactivitiesofmachinelearning2.2SomecharacteristicsofML3.WhatisSoftwareEngineeringforDataScience?3.1TypesofSoftware4.TheStructureofaDataScience......
  • PCIe问题举例: Enable SR-IOV导致资源分配失败
    资源分配问题分析过程:1.在shell下和OS都能复制到现象;2.测试CRBBIOS,发现CRBBIOS在shell下没有复制到现象,在OS下复制到现象;3.比较AoqinBIOS和CRBBIOS,发现在setup里面把PCIeSR-IOVdisable,shell下就能正常分配到Region0/2的资源;----看来跟PCIeSR-IOV功能有关4.Region0/2的......