【问题标题】:Calculating distance between two LaB colors Java计算两种 LaB 颜色 Java 之间的距离
【发布时间】:2018-01-30 23:10:03
【问题描述】:

我正在开发一个程序,我试图找到两种 LaB 颜色之间的欧几里德距离。我想知道他们计算两者之间距离的方式是否正确。这是我正在做的事情:

public static void main(String[] args) {

    double[] lab = {58.974604845047, 15.037506818771362, -64.0113115310669}; //blue
    double[] lab1 = {58.701420307159424, 14.014512300491333, -64.46481943130493};//blue

    double distance = euclideanDistance(lab, lab1);
    System.out.println("Lab: " + distance); 

}

private static double euclideanDistance(double[] lab , double []lab1){
    //L = 0 - 100 range
    //A = -86.185 - 98.254 range
    //B = 107.863 - 94.482 range
    double Lmean = (lab[0] + lab1[0]) / 2;
    double L = lab[0] - lab1[0];
    double A = lab[1] - lab1[1];
    double B = lab[2] - lab1[2];
    double weightL = 2 + Lmean /100;
    double weightA = 4.0;
    double weightB = 2 + (107.863 - Lmean) / 100;

    return Math.sqrt(weightL * L * L + weightA * A * A + weightB * B * B);  
}

【问题讨论】:

  • Wikipedia 说:“ ... L*a*b* 中任意两种颜色之间的相对感知差异可以通过将每种颜色视为三维空间中的一个点来近似(用三个组成部分:L*、a*、b*)并取它们之间的欧几里得距离”——因此我认为这就是你想要做的。如果是,那么它应该是两点之间的简单距离,并且有很多关于它们如何工作的描述(供您检查)。
  • 啊好的谢谢@Thomas

标签: java colors euclidean-distance


【解决方案1】:

因此,对于任何想知道两个 Lab 值之间的欧几里得距离之间是否存在细微差别的人来说,没有。如wiki所述

... Lab* 中任意两种颜色之间的相对感知差异可以通过将每种颜色视为三维空间中的一个点(具有三个分量:L、a、b*)并取欧几里得距离来近似他们之间

这个问题的解决方案是这样的。

private  double euclideanDistance(double[] lab , double []lab1){
    double L = lab[0] - lab1[0];
    double A = lab[1] - lab1[1];
    double B = lab[2] - lab1[2];
    return Math.sqrt((L * L) +  (A * A) +  (B * B));    
}

【讨论】:

    【解决方案2】:

    要在Lab 色彩空间中获得更准确的感知距离,您可以使用 CIEDE2000 (CIE Delta E 2000)

    public class CIEDE2000 {
    
    /**
     * Calculate the colour difference value between two colours in lab space.
     * @param L1 first colour's L component
     * @param a1 first colour's a component
     * @param b1 first colour's b component
     * @param L2 second colour's L component
     * @param a2 second colour's a component
     * @param b2 second colour's b component
     * @return the CIE 2000 colour difference
     */
    public static double calculateDeltaE(double L1, double a1, double b1, double L2, double a2, double b2) {
        double Lmean = (L1 + L2) / 2.0;
        double C1 =  Math.sqrt(a1*a1 + b1*b1);
        double C2 =  Math.sqrt(a2*a2 + b2*b2);
        double Cmean = (C1 + C2) / 2.0;
    
        double G =  ( 1 - Math.sqrt( Math.pow(Cmean, 7) / (Math.pow(Cmean, 7) + Math.pow(25, 7)) ) ) / 2; //ok
        double a1prime = a1 * (1 + G);
        double a2prime = a2 * (1 + G);
    
        double C1prime =  Math.sqrt(a1prime*a1prime + b1*b1);
        double C2prime =  Math.sqrt(a2prime*a2prime + b2*b2);
        double Cmeanprime = (C1prime + C2prime) / 2;
    
        double h1prime =  Math.atan2(b1, a1prime) + 2*Math.PI * (Math.atan2(b1, a1prime)<0 ? 1 : 0);
        double h2prime =  Math.atan2(b2, a2prime) + 2*Math.PI * (Math.atan2(b2, a2prime)<0 ? 1 : 0);
        double Hmeanprime =  ((Math.abs(h1prime - h2prime) > Math.PI) ? (h1prime + h2prime + 2*Math.PI) / 2 : (h1prime + h2prime) / 2);
    
        double T =  1.0 - 0.17 * Math.cos(Hmeanprime - Math.PI/6.0) + 0.24 * Math.cos(2*Hmeanprime) + 0.32 * Math.cos(3*Hmeanprime + Math.PI/30) - 0.2 * Math.cos(4*Hmeanprime - 21*Math.PI/60);
    
        double deltahprime =  ((Math.abs(h1prime - h2prime) <= Math.PI) ? h2prime - h1prime : (h2prime <= h1prime) ? h2prime - h1prime + 2*Math.PI : h2prime - h1prime - 2*Math.PI);
    
        double deltaLprime = L2 - L1;
        double deltaCprime = C2prime - C1prime;
        double deltaHprime =  2.0 * Math.sqrt(C1prime*C2prime) * Math.sin(deltahprime / 2.0);
        double SL =  1.0 + ( (0.015*(Lmean - 50)*(Lmean - 50)) / (Math.sqrt( 20 + (Lmean - 50)*(Lmean - 50) )) );
        double SC =  1.0 + 0.045 * Cmeanprime;
        double SH =  1.0 + 0.015 * Cmeanprime * T;
    
        double deltaTheta =  (30 * Math.PI / 180) * Math.exp(-((180/Math.PI*Hmeanprime-275)/25)*((180/Math.PI*Hmeanprime-275)/25));
        double RC =  (2 * Math.sqrt(Math.pow(Cmeanprime, 7) / (Math.pow(Cmeanprime, 7) + Math.pow(25, 7))));
        double RT =  (-RC * Math.sin(2 * deltaTheta));
    
        double KL = 1;
        double KC = 1;
        double KH = 1;
    
        double deltaE = Math.sqrt(
                ((deltaLprime/(KL*SL)) * (deltaLprime/(KL*SL))) +
                ((deltaCprime/(KC*SC)) * (deltaCprime/(KC*SC))) +
                ((deltaHprime/(KH*SH)) * (deltaHprime/(KH*SH))) +
                (RT * (deltaCprime/(KC*SC)) * (deltaHprime/(KH*SH)))
                );
    
        return deltaE;
    }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-11-14
      • 1970-01-01
      • 2013-08-02
      • 2010-10-30
      • 1970-01-01
      • 2020-08-05
      • 2011-04-23
      相关资源
      最近更新 更多