2012-11-27 13 views
8

Potrzebuję obliczyć różnicę między dwiema wartościami koloru szesnastkowego, więc wynik jest wartością procentową. Pierwszą rzeczą, którą odrzuciłem, było przekonwertowanie wartości heksadecymalnej na dziesiętną, ponieważ pierwsza z nich będzie miała znacznie większą wagę niż ostatnia.Różnica kolorów/podobieństwo% między dwiema wartościami z JS

Drugą opcją jest obliczenie różnicy między każdą z wartości RGB, a następnie dodanie ich wszystkich. Jednak różnica między 0, 0, 0 i 30, 30, 30 jest znacznie mniejsza niż między 0, 0, 0 i 90, 0, 0.

This question zaleca używanie YUV, ale nie wiem, jak go użyć, aby ustalić różnicę.

Również, this other question ma ładną formułę do obliczenia różnicy i wyprowadzenia wartości RGB, ale to jeszcze nie koniec.

+0

znalazłem dobry artykuł o pasujących kolorach http://html5hub.com/exploring-color-matching-in-javascript/ – maersu

Odpowiedz

3

Wystarczy obliczyć Euclidean distance:

var c1 = [0, 0, 0], 
    c2 = [30, 30, 30], 
    c3 = [90, 0, 0], 
    distance = function(v1, v2){ 
     var i, 
      d = 0; 

     for (i = 0; i < v1.length; i++) { 
      d += (v1[i] - v2[i])*(v1[i] - v2[i]); 
     } 
     return Math.sqrt(d); 
    }; 

console.log(distance(c1, c2), distance(c1, c3), distance(c2, c3)); 
//will give you 51.96152422706632 90 73.48469228349535 
+0

czy przeczytałeś komentarz od alchemika gry? Myślę, że wskazuje na pewne powody, dla których twoja odpowiedź nie jest zbyt dobra. Zasadniczo dalsze oddzielenie nie oznacza wyraźniejszego dla ludzkiego oka. – xaxxon

+2

Odległość euklidesowa nie działa w przestrzeni kolorów RGB, ale w przestrzeni kolorów LAB. Jednakże, podczas gdy przestrzeń LAB była przeznaczona do percepcyjnej jednolitości w postrzeganym kolorze, to jest krótka! Zatem dE76 (odległość euklidesowa, dosłownie) nie jest bardzo dokładna, szczególnie z nasyceniem. de94 i ​​de00 są lepsze dla dokładności. Więcej informacji: http://zschuessler.github.io/DeltaE/learn/ –

6

problem jest, że chcesz coś takiego dystansu na 3 dimensionnal świata, ale reprezentacja RGB nie jest intuicyjny w ogóle: „blisko” kolory mogą być znacznie różni się tym "dalekim" kolorem.

Weźmy na przykład dwa odcienie szarości c1: (120,120,120) i c2: (150,150,150) i teraz bierzemy c3: (160,140,140) jest bliżej c2 niż c1, a jednak jest fioletowy, a dla oka ciemniejszy szary jest znacznie bliższy szarości niż fioletu.

Proponuję użyć hsv: kolor jest definiowany przez "podstawowy" kolor (odcień), nasycenie i intensywność. kolory o zbliżonym odcieniu są rzeczywiście bardzo blisko. kolory o bardzo różnym odcieniu nie odnoszą się do siebie (eksp. żółte i zielone), ale mogą wydawać się bliższe z (bardzo) niskim nasyceniem i (bardzo) małym natężeniem.
(Nocą wszystkie kolory są takie same.)

Ponieważ barwa jest podzielony na 6 bloków, cyl = Math.floor (Hue/6) daje pierwszy etap swojej podobieństwa evalution: jeśli sama część cylindra -> dość blisko. Jeśli nie należą do tego samego cylindra, mogą nadal być (całkiem) zamknięte, jeśli (h2-h1) są małe, porównać je z (1/6). Jeśli (h2-h1)> 1/6 może to być po prostu zbyt różne kolory.

Następnie możesz być bardziej precyzyjny za pomocą (s, v). Kolory są bliższe, jeśli zarówno niskie/bardzo niskie nasycenie i/lub niskie natężenie.

Graj z selektorem kolorów obsługującym zarówno plik rgb, jak i hsv, dopóki nie wiesz, co chcesz mieć jako wartość różnicy. Ale pamiętaj, że nie możesz mieć "prawdziwej" miary podobieństwa.

masz RGB -> HSV javascript konwerter tutaj: http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c

2

The 3rd zasada porównań kolorów na ColorWiki jest „Nigdy nie próbuj konwertować między różnic kolorystycznych obliczonych według różnych równań poprzez stosowanie uśredniania czynniki”. Dzieje się tak, ponieważ kolory, które są matematycznie blisko siebie, nie zawsze są wizualnie podobne do nas, ludzi.

To, czego szukasz, to prawdopodobnie delta-e, czyli jedna liczba reprezentująca "odległość" między dwoma kolorami.

Najbardziej popularne algorytmy są wymienione poniżej, przy czym CIE76 (znany jako CIE 1976 lub dE76) jest najbardziej popularny.

Każdy idzie o rzeczy w inny sposób, ale w większości przypadków wszystkie one wymagają konwersji na lepsze (dla porównania) model kolorowy niż RGB.

Wikipedia ma wszystkie formuły: http://en.wikipedia.org/wiki/Color_difference

można sprawdzić swoją pracę z internetowych kolorów kalkulatorów:

Wreszcie, nie jest javascript ale tam open-source C# library Rozpocząłem niektóre z tych konwersji i obliczeń: https://github.com/THEjoezack/ColorMine

+0

Witaj, Joe. Jak to się stało, że nie ma konwersji między radianami i stopniami w twojej bibliotece C#? takie jak 'Math.Atan2 (lab1.B, aPrime1)% 360;' to wartość radianowa mod 360 stopni, która naprawdę mnie zdezorientowała ... daj mi znać, co myślisz, dzięki. –

3

wydałem pakiet npm/Bower obliczania trzy algorytmy CIE de76, de94 i ​​de00.

To domena publiczna i na Github:

http://zschuessler.github.io/DeltaE/

Oto przewodnik Szybki start:

zainstalować poprzez KMP

npm install delta-e 

Wykorzystanie

// Include library 
var DeltaE = require('delta-e'); 

// Create two test LAB color objects to compare! 
var color1 = {L: 36, A: 60, B: 41}; 
var color2 = {L: 100, A: 40, B: 90}; 

// 1976 formula 
console.log(DeltaE.getDeltaE76(color1, color2)); 

// 1994 formula 
console.log(DeltaE.getDeltaE94(color1, color2)); 

// 2000 formula 
console.log(DeltaE.getDeltaE00(color1, color2)); 

Konieczne będzie przekonwertowanie na kolor LAB, aby użyć tej biblioteki. d3.js ma do tego znakomity interfejs API - i jestem pewien, że możesz znaleźć coś adhoc.

Powiązane problemy