はじめに
研究で表色系の比較を行うことが多いので,表色系変換のコードをまとめてみました.
opencvを使えば1行で実行できます.
しかし,実際にどうやって変換しているのか気になったので,自分でコードを書いてみました.
実行環境
python3.6
RGB→CIE Luv
def convert_luv(img_data):
"""
Convert RGB to Luv
"""
img_flat = img_data.reshape(-1, 3)
red = np.delete(img_flat, [1,2],1)
green = np.delete(img_flat, [0,2],1)
blue = np.delete(img_flat, [0,1],1)
#RGB >>> XYZ
X = 0.412391*red +0.357584*green +0.180481*blue
Y = 0.212639*red +0.715169*green +0.072192*blue
Z = 0.019331*red +0.119195*green +0.950532*blue
#XYZ >>> u'v'
cielu = 4*X / (X + 15*Y + 3*Z)
cielu[(np.isnan(cielu)) | (len(cielu)==float("inf")) | (len(cielu) == float("-inf"))] = 0
cielv = 9*Y / (X + 15*Y + 3*Z)
cielv[(np.isnan(cielv)) | (len(cielv)==float("inf")) | (len(cielv) == float("-inf"))] = 0
uv = np.c_[cielu,cielv]
#XYZ >>> L*u*v*
Yn = 100
un = 0.19793943
vn = 0.46831096
L = np.empty((0,1),int)
for i in Y:
if i/Yn <= (6/29)**3:
L = np.append(L, np.array([(29/3)**3 * i / Yn]),axis=0)
else:
L = np.append(L,np.array([116 * (i/Yn)**(1/3) -16]),axis=0)
u_asterisk = 13*L * (cielu - un)
v_asterisk = 13*L * (cielv - vn)
Luv = np.c_[L, u_asterisk, v_asterisk]
return Luv
CIE Lab→HSV
def convert_hue(color_list):
"""
Convert Lab to HSV
"""
a = np.delete(color_list,[0,2],1)
b = np.delete(color_list, [0,1],1)
h = []
count = 0
for ab in color_list:
a = math.radians(ab[1])
b = math.radians(ab[2])
hs = math.atan2(b,a)
hs = math.degrees(hs)
if hs < 0:
hs = hs + 360
count += 1
h.append([hs])
h = np.array(h)
hue = np.array([])
for i in h:
hue = np.append(hue,i)
return hue
CIE Luv→u'v'
def convert_asteriskuv(color_list):
"""
Convert L*u*v* to u'v'
"""
un = 0.19793943
vn = 0.46831096
L = np.delete(color_list,[1,2],1)
u_asterisk = np.delete(color_list,[0,2],1)
v_asterisk = np.delete(color_list,[0,1],1)
cielu = u_asterisk / (13*L) + un
cielv = v_asterisk / (13*L) + vn
asterisk_uv = np.c_[cielu,cielv]
return L, asterisk_uv
まとめ
代表的な表色系の変換を行いました.
書いてみて,opencvのありがたさを改めて感じますね.
何かの参考にしていただけると,嬉しいです!