C++实现CIEDE2000色差公式

#define _USE_MATH_DEFINES
#include<iostream>
#include<math.h>

using namespace std;

class ColorDifferences
{
public:
	static double delta_E00(double L1, double a1, double b1, double L2, double a2, double b2)
	{
		double E00 = 0;               //CIEDE2000色差E00
		double LL1, LL2, aa1, aa2, bb1, bb2; //声明L' a' b' (1,2)
		double delta_LL, delta_CC, delta_hh, delta_HH;        // 第二部的四个量
		double kL, kC, kH;
		double RT = 0;                //旋转函数RT
		double G = 0;                  //G表示CIELab 颜色空间a轴的调整因子,是彩度的函数.
		double mean_Cab = 0;    //两个样品彩度的算术平均值
		double SL, SC, SH, T;
		//------------------------------------------
		kL = 1;
		kC = 1;
		kH = 1;
		//------------------------------------------
		mean_Cab = (CaiDu(a1, b1) + CaiDu(a2, b2)) / 2;
		double mean_Cab_pow7 = pow(mean_Cab, 7);       //两彩度平均值的7次方
		G = 0.5*(1 - pow(mean_Cab_pow7 / (mean_Cab_pow7 + pow(25, 7)), 0.5));

		LL1 = L1;
		aa1 = a1 * (1 + G);
		bb1 = b1;

		LL2 = L2;
		aa2 = a2 * (1 + G);
		bb2 = b2;

		double CC1, CC2;               //两样本的彩度值
		CC1 = CaiDu(aa1, bb1);
		CC2 = CaiDu(aa2, bb2);
		double hh1, hh2;                  //两样本的色调角
		hh1 = SeDiaoJiao(aa1, bb1);
		hh2 = SeDiaoJiao(aa2, bb2);

		delta_LL = LL1 - LL2;
		delta_CC = CC1 - CC2;
		delta_hh = SeDiaoJiao(aa1, bb1) - SeDiaoJiao(aa2, bb2);
		delta_HH = 2 * sin(M_PI*delta_hh / 360) * pow(CC1 * CC2, 0.5);

		//-------第三步--------------
		//计算公式中的加权函数SL,SC,SH,T
		double mean_LL = (LL1 + LL2) / 2;
		double mean_CC = (CC1 + CC2) / 2;
		double mean_hh = (hh1 + hh2) / 2;

		SL = 1 + 0.015 * pow(mean_LL - 50, 2) / pow(20 + pow(mean_LL - 50, 2), 0.5);
		SC = 1 + 0.045 * mean_CC;
		T = 1 - 0.17 * cos((mean_hh - 30) * M_PI / 180) + 0.24 * cos((2 * mean_hh) * M_PI / 180)
			+ 0.32 * cos((3 * mean_hh + 6) * M_PI / 180) - 0.2 * cos((4 * mean_hh - 63) * M_PI / 180);
		SH = 1 + 0.015 * mean_CC * T;

		//------第四步--------
		//计算公式中的RT
		double mean_CC_pow7 = pow(mean_CC, 7);
		double RC = 2 * pow(mean_CC_pow7 / (mean_CC_pow7 + pow(25, 7)), 0.5);
		double delta_xita = 30 * exp(-pow((mean_hh - 275) / 25, 2));        //△θ 以°为单位
		RT = -sin((2 * delta_xita) * M_PI / 180) * RC;

		double L_item, C_item, H_item;
		L_item = delta_LL / (kL * SL);
		C_item = delta_CC / (kC * SC);
		H_item = delta_HH / (kH * SH);

		E00 = pow(L_item * L_item + C_item * C_item + H_item * H_item + RT * C_item * H_item, 0.5);

		return E00;
	}
	//彩度计算
	static double CaiDu(double a, double b)
	{
		double Cab = 0;
		Cab = pow(a * a + b * b, 0.5);
		return Cab;
	}
	//色调角计算
	static double SeDiaoJiao(double a, double b)
	{
		double h = 0;
		double hab = 0;

		h = (180 / M_PI) * atan(b / a);           //有正有负

		if (a > 0 && b > 0)
		{
			hab = h;
		}
		else if (a < 0 && b>0)
		{
			hab = 180 + h;
		}
		else if (a < 0 && b < 0)
		{
			hab = 180 + h;
		}
		else     //a>0&&b<0
		{
			hab = 360 + h;
		}
		return hab;
	}
};

int main()
{
	double res = ColorDifferences::delta_E00(50, 60, 60, 60, 50, 50);
	cout << res << endl;
	system("pause");
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值