RGB 轉灰度
//rgba(grey,grey,grey,1)
function rgb2Grey(r,g,b)
{
var grey=Math.round((r*299 + g*587 + b*114 + 500) / 1000)
return grey
}
判斷兩種顏色相似程度
//rbg
function isSimilarColorRBG(r1, g1, b1, r2, g2, b2, offset)
{
if (Math.sqrt((r1 - r2) * (r1 - r2) + (g1 - g2) * (g1 - g2) + (b1 - b2) * (b1 - b2)) < offset)
{
return true;
}
else
{
return false;
}
}
//hex
function isSimilarColorHEX(sHexColorA, sHexColorB, nOffset)
{
this.offsetNum = Math.abs(nOffset);
this.offsetNum > 255 ? this.offsetNum = this.offsetNum - 256 : "";
var arrNumA = [parseInt(sHexColorA.substring(0, 2), 16),
parseInt(sHexColorA.substring(2, 4), 16),
parseInt(sHexColorA.substring(4, 6), 16)
];
var arrNumB = [parseInt(sHexColorB.substring(0, 2), 16),
parseInt(sHexColorB.substring(2, 4), 16),
parseInt(sHexColorB.substring(4, 6), 16)
];
for (var i = 0; i < arrNumA.length; i++)
{
if (Math.abs(arrNumA[i] - arrNumB[i]) > this.offsetNum)
{
return false;//不相似
};
}
return true;//相似
}
RGB轉HEX
//rgbToHex("rbg(r,g,b)")
function rgb2Hex(rgb)
{
var color = rgb.toString().match(/\d+/g);
var hex = "#";
for (var i = 0; i < 3; i++)
{
hex += ("0" + Number(color[i]).toString(16)).slice(-2);
}
return hex;
}
色差計算
色彩有多種顏色空間表示方式,如RGB,HSV,HSL,LAB等等,
RGB顏色空間:
RGB顏色空間相對簡單,也最為普遍,就分為三個顏色通道,分別為紅色,綠色,藍色這三種基本色調的值,然后將這三個顏色融合在一起,也就成為一種顏色.
但用RGB比較顏色之間的相似度時,存在很大的問題,不建議直接使用,因為往往一個通道的一點改變,會導致最后融合在一起的顏色發生巨大變化,而如果三個通道的同時改變,卻只會使最后的明暗發生變化,色調並不會產生巨大變化.
而這也是H系列色彩空間普遍存在的問題.
HSV顏色空間:
HSV是個六棱錐模型,這個模型中顏色的參數分別是:色調(H),飽和度(S),明度(V)。
色調H:
用角度度量,取值范圍為0°~360°,從紅色開始按逆時針方向計算,紅色為0°,綠色為120°,藍色為240°。它們的補色是:黃色為60°,青色為180°,品紅為300°;
飽和度S:
飽和度S表示顏色接近光譜色的程度。一種顏色,可以看成是某種光譜色與白色混合的結果。其中光譜色所占的比例愈大,顏色接近光譜色的程度就愈高,顏色的飽和度也就愈高。飽和度高,顏色則深而艷。光譜色的白光成分為0,飽和度達到最高。通常取值范圍為0%~100%,值越大,顏色越飽和。
明度V:
明度表示顏色明亮的程度,對於光源色,明度值與發光體的光亮度有關;對於物體色,此值和物體的透射比或反射比有關。通常取值范圍為0%(黑)到100%(白)。
其中:V對應的是棱錐的中間軸,H對應的是角度,S對應的是距離中間軸的距離.
RGB跟HSV的相互轉換可參考百度百科
距離計算方法:
在斜邊長R,底面圓半徑為r,高為h的HSV圓錐體內,以地面圓心為原點,H=0為x軸正方向建立坐標軸。那么色值是(H,S,V)的點的三維坐標(x,y,z)是
x = r∗V∗S∗cosH
y = r∗V∗S∗sinH
z = h∗(1−V)
具體Python代碼實現(參考這個連接)
def HSVDistance(hsv_1,hsv_2):
H_1,S_1,V_1 = hsv_1
H_2,S_2,V_2 = hsv_2
R=100
angle=30
h = R * math.cos(angle / 180 * math.pi)
r = R * math.sin(angle / 180 * math.pi)
x1 = r * V_1 * S_1 * math.cos(H_1 / 180 * math.pi);
y1 = r * V_1 * S_1 * math.sin(H_1 / 180 * math.pi);
z1 = h * (1 - V_1);
x2 = r * V_2 * S_1 * math.cos(H_2 / 180 * math.pi);
y2 = r * V_2 * S_1 * math.sin(H_2 / 180 * math.pi);
z2 = h * (1 - V_2);
dx = x1 - x2;
dy = y1 - y2;
dz = z1 - z2;
return math.sqrt(dx * dx + dy * dy + dz * dz);
HSV顏色空間分布圖
但HSV空間計算距離時,存在一定的問題,比如,在接近頂點的地方,基本都接近黑色,不管H色調怎么改變,而在底面的中心或者S飽和度接近0時,基本都接近灰色,不管H色調怎么改變,而在飽和度S較大,且V亮度較大時,H色調的一點改變往往會讓整體的顏色產生巨大變化,所以,用HSV計算距離時往往還存在某些問題.
LAB顏色空間:
LAB顏色空間是基於人眼對顏色的感知,可以表示人眼所能感受到的所有顏色。L表示明度,A表示紅綠色差,B表示藍黃色差。兩個顏色之見的色差:
ΔE=( ΔL^2 + ΔA^2 + ΔB^2 ) ^ (1/2)
ΔE 表示色差,ΔL/ΔA/Δb分別表示兩個顏色之間在不同分量的差值。
為了簡化計算及保證計算效果,有人在RGB空間上通過公式計算出加權的歐式距離。
以下為具體的計算方法,詳細說明可以參考:鏈接
https://www.compuphase.com/cmetric.htm
具體Python代碼實現(參考這個鏈接):
def ColourDistance(rgb_1, rgb_2):
R_1,G_1,B_1 = rgb_1
R_2,G_2,B_2 = rgb_2
rmean = (R_1 +R_2 ) / 2
R = R_1 - R_2
G = G_1 -G_2
B = B_1 - B_2
return math.sqrt((2+rmean/256)*(R**2)+4*(G**2)+(2+(255-rmean)/256)*(B**2))
這個方法是我目前嘗試,最為可靠有效的方法.
CIEDE2000色差公式計算