LAB to Delta E conversion in R

[This article was first published on Data Analysis in R, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

The post LAB to Delta E conversion in R appeared first on finnstats.

If you are interested to learn more about data science, you can find more articles here finnstats.

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)
}

Machine Learning Impact on your day-to-day life! »

If you are interested to learn more about data science, you can find more articles here finnstats.

The post LAB to Delta E conversion in R appeared first on finnstats.

To leave a comment for the author, please follow the link and comment on their blog: Data Analysis in R.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)