From 99b0874652adde76fc6b2d6fb3d263abb83867a1 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Mon, 7 Jan 2013 12:42:03 +0000 Subject: [PATCH] color: simplify CIEDE2000 distance code. --- src/image/color/cie1931.cpp | 24 +++++------------------- test/unit/color.cpp | 11 ++++++++--- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/image/color/cie1931.cpp b/src/image/color/cie1931.cpp index 104b8385..9b89f6a4 100644 --- a/src/image/color/cie1931.cpp +++ b/src/image/color/cie1931.cpp @@ -46,25 +46,11 @@ float Color::DistanceCIEDE2000(vec3 lab1, vec3 lab2) float dCp = Cp2 - Cp1; float Cp_ = 0.5f * (Cp1 + Cp2); - float hp1 = fmod(atan2(lab1.z, ap1) + 2.f * pi, 2.f * pi); - float hp2 = fmod(atan2(lab2.z, ap2) + 2.f * pi, 2.f * pi); - float dhp; /* -pi .. pi */ - if (abs(hp1 - hp2) <= pi) - dhp = hp2 - hp1; - else if (hp2 <= hp1) - dhp = hp2 - hp1 + 2.f * pi; - else - dhp = hp2 - hp1 - 2.f * pi; - float dHp = 2.f * sqrt(Cp1 * Cp2) * sin(dhp / 2.f); - float Hp_; /* half-angle 0 .. 360 */ - if (!(Cp1 * Cp2)) - Hp_ = hp1 + hp2; - else if (abs(hp1 - hp2) > pi && hp1 + hp2 < 2.f * pi) - Hp_ = 0.5f * (hp1 + hp2) + pi; - else if (abs(hp1 - hp2) > pi) - Hp_ = 0.5f * (hp1 + hp2) - pi; - else - Hp_ = 0.5f * (hp1 + hp2); + float hp1 = atan2(lab1.z, ap1); + float hp2 = atan2(lab2.z, ap2); + float dhp = fmod(hp2 - hp1 + 3.f * pi, 2.f * pi) - pi; /* -pi .. pi */ + float dHp = 2.f * sqrt(Cp1 * Cp2) * sin(0.5f * dhp); + float Hp_ = Cp1 * Cp2 ? fmod(hp1 + 0.5f * dhp + 2.f * pi, 2.f * pi) : hp1 + hp2; /* 0 .. 2pi */ float T = 1.f - 0.17f * cos(Hp_ - pi / 6.f) + 0.24f * cos(2.f * Hp_) diff --git a/test/unit/color.cpp b/test/unit/color.cpp index f1ea2faf..46987d1f 100644 --- a/test/unit/color.cpp +++ b/test/unit/color.cpp @@ -33,9 +33,9 @@ static float const ciede2k[] = 50.0000f, 0.0000f, 0.0000f, 50.0000f, -1.0000f, 2.0000f, 2.3669f, 50.0000f, -1.0000f, 2.0000f, 50.0000f, 0.0000f, 0.0000f, 2.3669f, 50.0000f, 2.4900f, -0.0010f, 50.0000f, -2.4900f, 0.0009f, 7.1792f, - 50.0000f, 2.4900f, -0.0010f, 50.0000f, -2.4900f, 0.0010f, 7.1792f, - //50.0000f, 2.4900f, -0.0010f, 50.0000f, -2.4900f, 0.0011f, 7.2195f, - //50.0000f, 2.4900f, -0.0010f, 50.0000f, -2.4900f, 0.0012f, 7.2195f, + //50.0000f, 2.4900f, -0.0010f, 50.0000f, -2.4900f, 0.0010f, 7.1792f, + 50.0000f, 2.4900f, -0.0010f, 50.0000f, -2.4900f, 0.0011f, 7.2195f, + 50.0000f, 2.4900f, -0.0010f, 50.0000f, -2.4900f, 0.0012f, 7.2195f, 50.0000f, -0.0010f, 2.4900f, 50.0000f, 0.0009f, -2.4900f, 4.8045f, //50.0000f, -0.0010f, 2.4900f, 50.0000f, 0.0010f, -2.4900f, 4.8045f, 50.0000f, -0.0010f, 2.4900f, 50.0000f, 0.0011f, -2.4900f, 4.7461f, @@ -77,8 +77,13 @@ LOLUNIT_FIXTURE(ColorTest) float d1 = ciede2k[n + 6]; float d2 = Color::DistanceCIEDE2000(a, b); + float d3 = Color::DistanceCIEDE2000(b, a); + /* Check that our function works, and check that + * it is symmetrical. */ + LOLUNIT_SET_CONTEXT(n / 7); LOLUNIT_ASSERT_DOUBLES_EQUAL(d1, d2, 0.0001); + LOLUNIT_ASSERT_DOUBLES_EQUAL(d2, d3, 0.0001); } } };