2015-01-02 3 views
-1

Я следил за рекомендациями, как описано here, но когда приложение для Android ищет изображение, сделанное в хорошо освещенной комнате, и пытается сопоставить каждый цвет с самым близким основным цветом (черный, красный, синий , зеленый и т. д.), большинство цветов связаны с черным. Я понятия не имею, почему это происходит, и я потратил 3 часа на изучение моего кода, чтобы узнать, где этот недостаток. Может ли кто-нибудь предложить, где моя ошибка? Вот мой код:Цвет - Поиск ближайшего цвета

public double getMinEValue(int color1, int color2) { 
    double result_value = 0; 
    double[] color1_values = getColorValues(color1); 
    double[] color2_values = getColorValues(color2); 
    double delta_L = color1_values[0] - color2_values[0]; 
    double delta_C = Math.sqrt(Math.pow(color1_values[1], 2)+Math.pow(color1_values[2], 2))-Math.sqrt(Math.pow(color2_values[1], 2)+Math.pow(color2_values[2], 2)); 
    double delta_a = color1_values[1]-color2_values[1]; 
    double delta_b = color1_values[2]-color2_values[2]; 
    double delta_H = Math.sqrt(Math.pow(delta_a, 2)+Math.pow(delta_b, 2)+Math.pow(delta_C, 2)); 
    double k_1 = 0.045; double k_2 = 0.015; 
    double s_c = 1+k_1*Math.sqrt(Math.pow(color1_values[1], 2)+Math.pow(color1_values[2], 2)); 
    double s_h = 1+k_2*Math.sqrt(Math.pow(color1_values[1], 2)+Math.pow(color1_values[2], 2)); 
    result_value = Math.sqrt(Math.pow(delta_L, 2)+Math.pow((delta_C/s_c), 2)+Math.pow((delta_H/s_h), 2)); 
    return result_value; 
} 

public double[] getColorValues(int color1) { 
    double[] return_value = new double[3]; 
    double r = Color.red(color1)/255; 
    double g = Color.green(color1)/255; 
    double b = Color.blue(color1)/255; 
    double r_linear = makeLinear(r) * 100; 
    double g_linear = makeLinear(g) * 100; 
    double b_linear = makeLinear(b) * 100; 
    double[][] matrix = {{0.4124, 0.3576, 0.1805}, {0.2126, 0.7152, 0.0722}, {0.0193, 0.1192, 0.9508}}; 
    double[] linear_matrix = {r_linear, g_linear, b_linear}; 
    double[] result_matrix = new double[3]; 
    result_matrix = multiplyMatrices(matrix, linear_matrix); 
    //double X_n = 109.85; double Y_n = 100.00; double Z_n = 35.58; // Illuminant A 
    double X_n = 95.047; double Y_n = 100.00; double Z_n = 108.883; // D65 
    double L_star = 116*f(result_matrix[1]/Y_n)-16; 
    double a_star = 500*(f(result_matrix[0]/X_n)-f(result_matrix[1]/Y_n)); 
    double b_star = 200*(f(result_matrix[1]/Y_n)-f(result_matrix[2]/Z_n)); 
    return_value[0] = L_star; return_value[1] = a_star; return_value[2] = b_star; 
    return return_value; 
} 

private double f(double t) { 
    double return_value; 
    if (Double.compare(t, Math.pow((6/29), 3)) > 0) { 
     return_value = Math.pow(t, (1/3)); 
    } else { 
     return_value = (1/3)*Math.pow((29/6), 2)*t+(4/29); 
    } 
    return return_value; 
} 

private double makeLinear(double c) { 
    double return_value = 0; 
    if (Double.compare(0.04045, c)<=0) { 
     return_value = c/12.92; 
    } else { 
     double a = 0.055; 
     return_value = Math.pow(((c + a)/(1 + a)), 2.4); 
    } 
    return return_value; 
} 

private double[] multiplyMatrices(double[][] matrix, double[] other_matrix) { 
    double[] return_matrix = new double[3]; 
    for (int i=0; i<3; i++) { 
     for (int j=0; j<3; j++) { 
      return_matrix[i] += matrix[i][j]*other_matrix[j]; 
     } 
    } 
    return return_matrix; 
} 
+0

Вам нужно задать конкретный вопрос ... –

ответ

1

У вас есть целый много целых подразделений, которые должны быть плавающей точкой разделения. Вам нужно указать один из операндов каждого деления на double или включить десятичную точку, чтобы заставить их работать. Например, у вас есть

Color.red(color1)/255 

, который должен быть

Color.red(color1)/255.0 

и у вас также есть такие выражения, как

(1/3)*Math.pow((29/6), 2)*t+(4/29); 

который должен быть

(1.0/3)*Math.pow((29.0/6), 2)*t+(4.0/29); 

и многие другие. Вы сделали такую ​​же ошибку несколько раз.

+1

Я попытался найти вас на linkedin, но мне не удалось. :( –

Смежные вопросы