Followup: znalezienie dokładnej "odległości" między kolorami
Szukam funkcji, która próbuje określić jak "odległe" (lub odrębne) są dwa kolory. To pytanie jest naprawdę w dwóch częściach:
- jaka przestrzeń kolorów najlepiej reprezentuje ludzką wizję? Jaka metryka odległości w tej przestrzeni najlepiej reprezentuje ludzką wizję (euklidesową?)
8 answers
Konwertuj do La * b *(aka po prostu "Lab", a zobaczysz również odniesienie do "CIELAB"). Dobry szybki pomiar różnicy kolorów to
[5]}kolorowi naukowcy mają inne bardziej wyrafinowane środki, które mogą nie być warte zachodu, w zależności od dokładności potrzebnej do tego, co robisz.(L1-L2)^2 + (a1-A2)^2 + (b1-b2)^2
Wartości a
i b
reprezentują przeciwstawne kolory w sposób podobny do działania stożków i mogą być negatywne lub pozytywne. Neutralny kolory-biały, szarości są a=0
,b=0
. L
jest jasnością zdefiniowaną w szczególny sposób, od zera (czysta ciemność) do czegokolwiek.
Prymitywne Wyjaśnienie: > > biorąc pod uwagę kolor, nasze oczy rozróżniają dwa szerokie zakresy długości fali-niebieski vs dłuższe fale. a potem, dzięki nowszej mutacji genetycznej, stożki o dłuższej długości fali rozszczepiły się na dwa, rozróżniając dla nas czerwony vs. zielony.
/ Align = "left" / jaskiniowcy, którzy znają tylko "RGB" lub "CMYK", które są świetne dla urządzeń, ale do ciężkiej pracy percepcyjnej. Pracowałem dla naukowców obrazujących, którzy nic o tym nie wiedzieli!Aby uzyskać więcej zabawy z teorią różnicy kolorów, spróbuj:
- http://white.stanford.edu / ~brian/scielab/introduction.html i info
- i linki do teorii kolorów w ogóle, websurf zaczyna się od http://www.efg2.com/Lab/Library/Color / i
- http://www.poynton.com/Poynton-color.html
Więcej szczegółów na temat laboratorium na http://en.kioskea.net/video/cie-lab.php3 nie mogę w tej chwili znaleźć nie brzydkie strony, która faktycznie miała formuły konwersji, ale jestem pewien, że ktoś edytuje tę odpowiedź, aby dołączyć jeden.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-04 04:33:06
Jako cmetric.powyższy link htm nie powiódł się dla mnie, podobnie jak wiele innych implementacji dla odległości kolorów, które znalazłem (po bardzo długim jurney..) jak obliczyć najlepszą odległość koloru i .. najbardziej dokładne naukowo: deltaE i od 2 RGB (!) wartości za pomocą OpenCV:
To wymagało 3 konwersji przestrzeni kolorów + trochę konwersji kodu z javascript ( http://svn.int64.org/viewvc/int64/colors/colors.js) do C++
I wreszcie kod (wydaje się działać od razu z pudełka, mam nadzieję, że nikt nie znajdzie tam poważnego błędu ... ale wydaje się być w porządku po wielu testach)
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/photo/photo.hpp>
#include <math.h>
using namespace cv;
using namespace std;
#define REF_X 95.047; // Observer= 2°, Illuminant= D65
#define REF_Y 100.000;
#define REF_Z 108.883;
void bgr2xyz( const Vec3b& BGR, Vec3d& XYZ );
void xyz2lab( const Vec3d& XYZ, Vec3d& Lab );
void lab2lch( const Vec3d& Lab, Vec3d& LCH );
double deltaE2000( const Vec3b& bgr1, const Vec3b& bgr2 );
double deltaE2000( const Vec3d& lch1, const Vec3d& lch2 );
void bgr2xyz( const Vec3b& BGR, Vec3d& XYZ )
{
double r = (double)BGR[2] / 255.0;
double g = (double)BGR[1] / 255.0;
double b = (double)BGR[0] / 255.0;
if( r > 0.04045 )
r = pow( ( r + 0.055 ) / 1.055, 2.4 );
else
r = r / 12.92;
if( g > 0.04045 )
g = pow( ( g + 0.055 ) / 1.055, 2.4 );
else
g = g / 12.92;
if( b > 0.04045 )
b = pow( ( b + 0.055 ) / 1.055, 2.4 );
else
b = b / 12.92;
r *= 100.0;
g *= 100.0;
b *= 100.0;
XYZ[0] = r * 0.4124 + g * 0.3576 + b * 0.1805;
XYZ[1] = r * 0.2126 + g * 0.7152 + b * 0.0722;
XYZ[2] = r * 0.0193 + g * 0.1192 + b * 0.9505;
}
void xyz2lab( const Vec3d& XYZ, Vec3d& Lab )
{
double x = XYZ[0] / REF_X;
double y = XYZ[1] / REF_X;
double z = XYZ[2] / REF_X;
if( x > 0.008856 )
x = pow( x , .3333333333 );
else
x = ( 7.787 * x ) + ( 16.0 / 116.0 );
if( y > 0.008856 )
y = pow( y , .3333333333 );
else
y = ( 7.787 * y ) + ( 16.0 / 116.0 );
if( z > 0.008856 )
z = pow( z , .3333333333 );
else
z = ( 7.787 * z ) + ( 16.0 / 116.0 );
Lab[0] = ( 116.0 * y ) - 16.0;
Lab[1] = 500.0 * ( x - y );
Lab[2] = 200.0 * ( y - z );
}
void lab2lch( const Vec3d& Lab, Vec3d& LCH )
{
LCH[0] = Lab[0];
LCH[1] = sqrt( ( Lab[1] * Lab[1] ) + ( Lab[2] * Lab[2] ) );
LCH[2] = atan2( Lab[2], Lab[1] );
}
double deltaE2000( const Vec3b& bgr1, const Vec3b& bgr2 )
{
Vec3d xyz1, xyz2, lab1, lab2, lch1, lch2;
bgr2xyz( bgr1, xyz1 );
bgr2xyz( bgr2, xyz2 );
xyz2lab( xyz1, lab1 );
xyz2lab( xyz2, lab2 );
lab2lch( lab1, lch1 );
lab2lch( lab2, lch2 );
return deltaE2000( lch1, lch2 );
}
double deltaE2000( const Vec3d& lch1, const Vec3d& lch2 )
{
double avg_L = ( lch1[0] + lch2[0] ) * 0.5;
double delta_L = lch2[0] - lch1[0];
double avg_C = ( lch1[1] + lch2[1] ) * 0.5;
double delta_C = lch1[1] - lch2[1];
double avg_H = ( lch1[2] + lch2[2] ) * 0.5;
if( fabs( lch1[2] - lch2[2] ) > CV_PI )
avg_H += CV_PI;
double delta_H = lch2[2] - lch1[2];
if( fabs( delta_H ) > CV_PI )
{
if( lch2[2] <= lch1[2] )
delta_H += CV_PI * 2.0;
else
delta_H -= CV_PI * 2.0;
}
delta_H = sqrt( lch1[1] * lch2[1] ) * sin( delta_H ) * 2.0;
double T = 1.0 -
0.17 * cos( avg_H - CV_PI / 6.0 ) +
0.24 * cos( avg_H * 2.0 ) +
0.32 * cos( avg_H * 3.0 + CV_PI / 30.0 ) -
0.20 * cos( avg_H * 4.0 - CV_PI * 7.0 / 20.0 );
double SL = avg_L - 50.0;
SL *= SL;
SL = SL * 0.015 / sqrt( SL + 20.0 ) + 1.0;
double SC = avg_C * 0.045 + 1.0;
double SH = avg_C * T * 0.015 + 1.0;
double delta_Theta = avg_H / 25.0 - CV_PI * 11.0 / 180.0;
delta_Theta = exp( delta_Theta * -delta_Theta ) * ( CV_PI / 6.0 );
double RT = pow( avg_C, 7.0 );
RT = sqrt( RT / ( RT + 6103515625.0 ) ) * sin( delta_Theta ) * -2.0; // 6103515625 = 25^7
delta_L /= SL;
delta_C /= SC;
delta_H /= SH;
return sqrt( delta_L * delta_L + delta_C * delta_C + delta_H * delta_H + RT * delta_C * delta_H );
}
Mam nadzieję, że komuś pomoże:)
HSL i HSV są lepsze dla ludzkiego postrzegania kolorów. Według Wikipedii :
W pracy z materiałami artystycznymi, zdigitalizowanymi obrazami lub innymi mediami zaleca się czasami używanie modelu kolorów HSV lub HSL zamiast alternatywnych modeli, takich jak RGB lub CMYK, ze względu na różnice w sposobie, w jaki modele naśladują sposób postrzegania kolorów przez ludzi. RGB i CMYK są odpowiednio addytywnymi i subtraktywnymi modelami, modelującymi sposób, w jaki kolory podstawowe światła lub pigmenty (odpowiednio) Połącz, aby utworzyć nowe kolory po zmieszaniu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-09 14:01:26
Artykuł w Wikipedii na temat różnic kolorów zawiera listę przestrzeni kolorów i wskaźników odległości zaprojektowanych tak, aby zgadzały się z ludzkim postrzeganiem odległości kolorów.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-24 15:38:38
Może wyglądać jak spam, ale nie, ten link jest naprawdę interesujący dla przestrzeni kolorów:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-04 15:14:39
Najprostszą odległością byłoby oczywiście rozważenie kolorów jako wektorów 3d pochodzących z tego samego pochodzenia i biorąc odległość między ich punktami końcowymi.
Jeśli musisz wziąć pod uwagę takie czynniki, że zielony jest bardziej widoczny w ocenie intensywności, możesz zważyć wartości.
ImageMagic zapewnia następujące skale:
- czerwony: 0.3
- zielony: 0.6
- Niebieski: 0.1
Oczywiście takie wartości być znaczące tylko w odniesieniu do innych wartości dla innych kolorów, a nie jako coś, co byłoby znaczące dla ludzi, więc wszystko, co można użyć wartości dla byłoby kolejność podobieństwa.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-04 15:14:40
Cóż, jako pierwszy punkt wezwania, powiedziałbym o wspólnych metrykach HSV (Barwa, Nasycenie i wartość) lub HSL są lepiej reprezentatywne dla tego, jak ludzie postrzegają kolor niż powiedzmy RGB lub CYMK. Zobacz HSL, HSV na Wikipedii.
Przypuszczam, że naiwnie wykreśliłbym punkty w przestrzeni HSL dla dwóch kolorów i obliczył wielkość wektora różnicy. Oznaczałoby to jednak, że jasnożółty i jasnozielony byłby uważany za równie różny od zielonego do ciemnozielonego. Ale wtedy wielu uważa czerwony i różowy za dwa różne kolory.
Ponadto wektory różnicy w tym samym kierunku w tej przestrzeni parametru nie są równe. Na przykład ludzkie oko odbiera zieleń znacznie lepiej niż inne kolory. Zmiana odcienia z Zielonego o taką samą ilość jak zmiana z czerwonego może wydawać się większa. Również przesunięcie nasycenia z niewielkiej ilości do zera jest różnicą między szarością a różem, gdzie indziej przesunięcie byłoby różnicą między dwoma odcieniami czerwieni.
Od a z punktu widzenia programistów, trzeba byłoby wykreślić wektory różnicowe, ale zmodyfikowane przez macierz proporcjonalności, która dostosowywałaby odpowiednio długości w różnych regionach przestrzeni HSL - byłoby to dość arbitralne i opierałoby się na różnych koncepcjach teorii kolorów, ale było dość arbitralnie modyfikowane w zależności od tego, do czego chcesz to zastosować.
Jeszcze lepiej, można zobaczyć, czy ktoś już zrobił coś takiego w Internecie...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-04 15:37:43
Jako ktoś, kto jest daltonistą uważam, że dobrze jest spróbować dodać więcej separacji niż normalne widzenie. Najczęstszą formą ślepoty barw jest czerwony / zielony niedobór. Nie oznacza to, że nie widać czerwonego lub Zielonego, oznacza to, że trudniej jest zobaczyć i trudniej dostrzec różnice. Więc to wymaga większej separacji, zanim osoba niewidoma może odróżnić.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 16:45:50