LAB to Delta E conversion in R
LAB to Delta E conversion in R, First we need to understand what is Delta E. The “distance” between two colours is represented by a single integer called delta-E.
It’s alluring to just contrast the euclidean distance between an RGB’s red, green, and blue components.
Unfortunately for us, rgb doesn’t correspond to how we truly sense colour. It was designed for the convenience of use with electrical equipment.
How to Choose Appropriate Clustering Method for Your Dataset
The results of testing this method rapidly show that they are erratic and frequently drastically different from what is expected for seemingly “identical” hues.
People who are far wiser already developed numerous methods to determine the apparent difference in hue over the years.
LAB to Delta E conversion in R
You can make use ColorNameR package, however, we encountered some issues in the recent version, so we are referring direct functions to generate DelaE values.
library(ColorNameR) cie76(lab_color1, lab_color2) #lab_color1 A vector with three components corresponding to a Lab value. #lab_color2 A vector with three components corresponding to another Lab value
CIE76
The most widely used technique is called CIE 1976, or simply CIE76.
How to Apply AI to Small Data Sets? »
The secret to using this technique, which makes use of the aforementioned euclidean distance, is to switch to the CIE*Lab colour space first.
However, both the CIE*Lab colour space and Cie76 delta-e have their critics, so we advise conducting your own research to determine which approach is best for you.
cie76 <- function(lab_color1, lab_color2) { diff <- lab_color1 - lab_color2 base::sqrt(sum(diff^2)) }
CIE94
library(ColorNameR) cie94( lab_color1, lab_color2, k_L = 1, k_C = 1, k_H = 1, K1 = 0.045, K2 = 0.015, symmetric = FALSE ) #lab_color1 A vector with three components corresponding to a Lab value. #lab_color2 A vector with three components corresponding to another Lab value. #k_L Weighting factor for the L component. #k_C Weighting factor for the C component. #k_H Weighting factor for the H component. #K1 Application dependent weighting factor. #K2 Application dependent weighting factor. #symmetric If TRUE, use the symmetric version of the formula
Cie94 specifically targets the paint & coatings sector. It incorporates a commercial element that gives the forumla varied weights for applications in graphic arts and textiles.
It is comparable to Cie76, however Lch colour space and the aforementioned commercial aspect are its two main foundations.
Assess Performance of the Classification Model »
cie94 <- function(lab_color1, lab_color2, k_L=1, k_C=1, k_H=1, K1=0.045, K2=0.015, symmetric=FALSE) { L1 <- lab_color1[1] a1 <- lab_color1[2] b1 <- lab_color1[3] L2 <- lab_color2[1] a2 <- lab_color2[2] b2 <- lab_color2[3] delta_L <- L1 - L2 C1 <- base::sqrt(a1^2 + b1^2) C2 <- base::sqrt(a2^2 + b2^2) delta_C <- C1 - C2 delta_a <- a1 - a2 delta_b <- b1 - b2 delta_H <- base::sqrt(delta_a^2 + delta_b^2 - delta_C^2) S_L <- 1 S_C <- 1 + K1 * base::ifelse(symmetric, base::sqrt(C1 * C2), C1) S_H <- 1 + K2 * base::ifelse(symmetric, base::sqrt(C1 * C2), C1) term1 <- delta_L / (k_L * S_L) term2 <- delta_C / (k_C * S_C) term3 <- delta_H / (k_H * S_H) base::sqrt(term1^2 + term2^2 + term3^2) }
CIE DE2000
In 2000, the CIE added 5 modifications to CIE94 in order to further improve it.
added a hue term to improve the homogeneity of the pixel colour
- Making up for neutral colours
- Making up for lightness
- Making up for chroma
- Making up for hue
library(ColorNameR) ciede2000(lab_color1, lab_color2, k_L = 1, k_C = 1, k_H = 1) #lab_color1 A vector with three components corresponding to a Lab value. #lab_color2 A vector with three components corresponding to another Lab value. #k_L Weighting factor for the L component. #k_C Weighting factor for the C component. #k_H Weighting factor for the H component.
ciede2000 <- function(lab_color1, lab_color2, k_L=1, k_C=1, k_H=1) { L1 <- lab_color1[1] a1 <- lab_color1[2] b1 <- lab_color1[3] L2 <- lab_color2[1] a2 <- lab_color2[2] b2 <- lab_color2[3] C1 <- base::sqrt(a1^2 + b1^2) C2 <- base::sqrt(a2^2 + b2^2) C_bar <- (C1 + C2) / 2 G <- (1 - base::sqrt(C_bar^7 / (C_bar^7 + 25^7))) / 2 a1p <- (1 + G) * a1 a2p <- (1 + G) * a2 C1p <- base::sqrt(a1p^2 + b1^2) C2p <- base::sqrt(a2p^2 + b2^2) h1p <- base::atan2(b1, a1p) %% (2*base::pi) h2p <- base::atan2(b2, a2p) %% (2*base::pi) delta_Lp <- L2 - L1 delta_Cp <- C2p - C1p delta_hp <- base::ifelse(C1p * C2p != 0, base::ifelse(base::abs(h2p - h1p) <= base::pi, h2p - h1p, h2p - h1p + base::sign(h1p - h2p) * 2 * base::pi), 0) delta_Hp <- 2 * base::sqrt(C1p * C2p) * base::sin(delta_hp / 2) Lp_bar <- (L1 + L2) / 2 Cp_bar <- (C1p + C2p) / 2 hp_bar <- base::ifelse(C1p * C2p != 0, base::ifelse(base::abs(h2p - h1p) <= base::pi, (h1p + h2p) / 2, -(h1p + h2p + base::sign(2 * base::pi - h1p - h2p) * 2 * base::pi) / ), h1p + h2p) deg2rad <- base::pi / 180 rad2deg <- 1 / deg2rad Tp <- (1 - 0.17 * base::cos(hp_bar - 30 * deg2rad) + 0.24 * base::cos(2 * hp_bar) + 0.32 * base::cos(3 * hp_bar + 6 * deg2rad) - 0.20 * base::cos(4 * hp_bar - 63 * deg2rad)) delta_theta <- 30 * deg2rad * base::exp(- ((hp_bar * rad2deg - 275) / 25)^2) R_C <- 2 * base::sqrt(Cp_bar^7 / (Cp_bar^7 + 25^7)) S_L <- 1 + ((0.015 * (Lp_bar - 50)^2) / base::sqrt(20 + (Lp_bar - 50)^2)) S_C <- 1 + 0.045 * Cp_bar S_H <- 1 + 0.015 * Cp_bar * Tp R_T <- - base::sin(2 * delta_theta) * R_C term1 <- delta_Lp / (k_L * S_L) term2 <- delta_Cp / (k_C * S_C) term3 <- delta_Hp / (k_H * S_H) term4 <- R_T * term2 * term3 base::sqrt(term1^2 + term2^2 + term3^2 + term4) }