ΔE00を求めるプログラムを書いてみました
ただ、分類するだけならここまで厳密な値は使わなくても、
単純にRGBのユークリッド距離でいいかもしれません
#module
#deffunc sRGBtoXYZ array XYZ, double r, double g, double b
tmp = r/255, g/255, b/255
repeat 3
if tmp(cnt)<=0.040450{
tmp(cnt) = tmp(cnt) / 12.92
}else{
tmp(cnt) = powf((tmp(cnt)+0.055)/1.055, 2.4)
}
loop
ddim XYZ,3
XYZ(0) = 0.412391*tmp(0) + 0.357584*tmp(1) + 0.180481*tmp(2)
XYZ(1) = 0.212639*tmp(0) + 0.715169*tmp(1) + 0.072192*tmp(2)
XYZ(2) = 0.019331*tmp(0) + 0.119195*tmp(1) + 0.950532*tmp(2)
return
#defcfunc LabConvertFunc double t
if t>0.008856 {
return powf(t, 1.0/3)
}else{
return (903.296296*t+16)/116
}
#deffunc XYZtoLab array Lab, double X, double Y, double Z
sRGBtoXYZ white, 255, 255, 255
ddim Lab,3
Lab(0) = 116.0*LabConvertFunc(Y/white(1))-16
Lab(1) = 500.0*(LabConvertFunc(X/white(0))-LabConvertFunc(Y/white(1)))
Lab(2) = 200.0*(LabConvertFunc(Y/white(1))-LabConvertFunc(Z/white(2)))
return
#defcfunc ColorDif array Lab1, array Lab2
delta_L = Lab2(0) - Lab1(0)
L = (Lab1(0) + Lab2(0))/2
c1 = sqrt(powf(Lab1(1),2)+powf(Lab1(2),2))
c2 = sqrt(powf(Lab2(1),2)+powf(Lab2(2),2))
c = (c1 + c2)/2
c7 = powf(c,7)
co = sqrt(c7/(c7+powf(25,7)))
a1p = Lab1(1)*(1.5-co/2)
a2p = Lab2(1)*(1.5-co/2)
c1p = sqrt(powf(a1p,2)+powf(Lab1(2),2))
c2p = sqrt(powf(a2p,2)+powf(Lab2(2),2))
delta_cp = c2p - c1p
cp = (c1p + c2p)/2
h1 = atan(Lab1(2),a1p)
h2 = atan(Lab2(2),a2p)
h1 = (h1 + 2.0*m_pi)\(2.0*m_pi)
h2 = (h2 + 2.0*m_pi)\(2.0*m_pi)
if abs(h1-h2)<=m_pi{
delta_h = h2 - h1
h = (h1 + h2)/2
}else{
if h2 <= h1{
delta_h = h2 - h1 + 2*m_pi
}else{
delta_h = h2 - h1 - 2*m_pi
}
if h1+h2 < 2*m_pi{
h = (h1 + h2)/2 + m_pi
}else{
h = (h1 + h2)/2 - m_pi
}
}
delta_hp = 2.0*sqrt(c1p*c2p)*sin(delta_h/2)
if c1p==0 | c2p==0 {
h = h1+h2
delta_hp = 0.0
}
t = 1.0 - 0.17*cos(h - m_pi/6) + 0.24*cos(2.0*h) + 0.32*cos(3.0*h+deg2rad(6)) - 0.2*cos(4.0*h-deg2rad(63))
sl = 1.0 + 0.015*powf(L-50, 2)/sqrt(20.0+powf(L-50, 2))
sc = 1.0 + 0.045*cp
sh = 1.0 + 0.015*cp*t
cp7 = powf(cp,7)
rt = -2.0*sqrt(cp7/(cp7+powf(25,7)))*sin(m_pi/3*powf(2.718282,-1.0*powf((h-deg2rad(275))/deg2rad(25),2)))
return sqrt(powf(delta_L/sl,2)+powf(delta_cp/sc,2)+powf(delta_hp/sh,2)+rt*delta_cp/sc*delta_hp/sh)
#defcfunc ColorDifRGB array RGB1, array RGB2
sRGBtoXYZ XYZ1, RGB1(0), RGB1(1), RGB1(2)
XYZtoLab Lab1, XYZ1(0), XYZ1(1), XYZ1(2)
sRGBtoXYZ XYZ2, RGB2(0), RGB2(1), RGB2(2)
XYZtoLab Lab2, XYZ2(0), XYZ2(1), XYZ2(2)
return ColorDif(Lab1, Lab2)
#global
RGB = 1,191,130
color RGB(0),RGB(1),RGB(2)
boxf 0,0,100,100
color
pos 0,100
dim colors,3,7
colors(0,0) = 255,0,0
colors(0,1) = 0,255,0
colors(0,2) = 0,0,255
colors(0,3) = 255,255,0
colors(0,4) = 0,255,255
colors(0,5) = 255,0,255
colors(0,6) = 128,128,128
color_names = "赤", "緑", "青", "黄", "水", "紫","灰"
mindis = 0.0
repeat 7
color_ = colors(0,cnt), colors(1,cnt), colors(2,cnt)
dis = ColorDifRGB(color_, rgb)
if cnt==0|dis<mindis{
mindis = dis
nearest = cnt
}
loop
mes "一番近い色は" + color_names(nearest) + "色だよ"
参考にしたページ:
http://w3.kcua.ac.jp/~fujiwara/infosci/colorspace/colorspace2.html
http://w3.kcua.ac.jp/~fujiwara/infosci/colorspace/colorspace3.html
https://ja.wikipedia.org/wiki/%E8%89%B2%E5%B7%AE#CIEDE2000_(delta_E00)