質問編集履歴
2
問題点の追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -302,6 +302,8 @@
|
|
302
302
|
|
303
303
|
|
304
304
|
|
305
|
+
ユークリッド距離はそもそもの色が若干違う点、CIE94は大まかには合っているものの黒い斑点が多く入ってしまうこと、が問題点です。
|
306
|
+
|
305
307
|
|
306
308
|
|
307
309
|
|
1
2つめのソースコード追加(CIE94)、参考画像追加
test
CHANGED
File without changes
|
test
CHANGED
@@ -102,7 +102,7 @@
|
|
102
102
|
|
103
103
|
|
104
104
|
|
105
|
-
for x in range(im.size[
|
105
|
+
for x in range(im.size[0]):
|
106
106
|
|
107
107
|
for z in range(im.size[1]):
|
108
108
|
|
@@ -122,16 +122,158 @@
|
|
122
122
|
|
123
123
|
|
124
124
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
125
|
```
|
132
126
|
|
133
127
|
|
134
128
|
|
129
|
+
### 2つ目のソースコード
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
```Python
|
134
|
+
|
135
|
+
from PIL import Image
|
136
|
+
|
137
|
+
import numpy as np
|
138
|
+
|
139
|
+
|
140
|
+
|
141
|
+
|
142
|
+
|
143
|
+
im=Image.open("base.jpg") #元画像base.jpg
|
144
|
+
|
145
|
+
new_im=Image.new('RGB',(im.size[0],im.size[1]), (255,255,255))
|
146
|
+
|
147
|
+
#元画像と同じ大きさ、背景白の新たな画像
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
|
152
|
+
|
153
|
+
def rgb_to_xyz(rgb): #rgb(255まで)→xyzの割合(0<=return<=1)を出す
|
154
|
+
|
155
|
+
a=[0.4124,0.3575,0.1805]
|
156
|
+
|
157
|
+
b=[0.2127,0.7152,0.0722]
|
158
|
+
|
159
|
+
c=[0.0193,0.1192,0.9504]
|
160
|
+
|
161
|
+
k=np.array([a,b,c]) #変換用倍率の行列
|
162
|
+
|
163
|
+
|
164
|
+
|
165
|
+
t=k.dot(np.array([x/255 for x in rgb]))
|
166
|
+
|
167
|
+
return (t[0]/0.9504,t[1]/1.0001,t[2]/1.0889)
|
168
|
+
|
169
|
+
#↑白(255,255,255)で(0.9504,1.0001,1.0889)なので割合として返す
|
170
|
+
|
171
|
+
|
172
|
+
|
173
|
+
def F(t): #L*a*b*用の関数
|
174
|
+
|
175
|
+
if t>216/24389:
|
176
|
+
|
177
|
+
return 116*pow(t,1/3)-16
|
178
|
+
|
179
|
+
else:
|
180
|
+
|
181
|
+
return 24389/27*t
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
def Lab(x,y,z): #xyz方式をL*a*b*に変換
|
186
|
+
|
187
|
+
L=F(y)
|
188
|
+
|
189
|
+
a=125/29*(F(x)-F(y))
|
190
|
+
|
191
|
+
b=50/29*(F(y)-F(z))
|
192
|
+
|
193
|
+
return (L,a,b)
|
194
|
+
|
195
|
+
|
196
|
+
|
197
|
+
def cos(a,b):
|
198
|
+
|
199
|
+
return sum([change(*a)[x]*change(*b)[x] for x in range(2)])
|
200
|
+
|
201
|
+
|
202
|
+
|
203
|
+
def C94(L1,a1,b1,L2,a2,b2):
|
204
|
+
|
205
|
+
k1=0.045
|
206
|
+
|
207
|
+
k2=0.015
|
208
|
+
|
209
|
+
kL=1
|
210
|
+
|
211
|
+
C1=(a1**2+b1**2)**(0.5)
|
212
|
+
|
213
|
+
C2=(a2**2+b2**2)**(0.5)
|
214
|
+
|
215
|
+
dC=C1-C2
|
216
|
+
|
217
|
+
dH=((a1-a2)**2+(b1-b2)**2-dC**2)**(0.5)
|
218
|
+
|
219
|
+
Sc=1+k1*C1
|
220
|
+
|
221
|
+
Sh=1+k2*C2
|
222
|
+
|
223
|
+
return (((L1-L2)/kL)**2+(dC/Sc)**2+(dH/Sh)**2)**(0.5)
|
224
|
+
|
225
|
+
|
226
|
+
|
227
|
+
|
228
|
+
|
229
|
+
def dis(a,b):
|
230
|
+
|
231
|
+
return sum([C94(*Lab(*rgb_to_xyz(a)),*Lab(*rgb_to_xyz(b))) for x in range(2)])
|
232
|
+
|
233
|
+
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
palette=[(60, 60, 60), (120, 120, 120), (130, 130, 130), (90, 90, 90), (255, 255, 255), (130, 135, 145), (70, 175, 170), (190, 100, 130), (140, 60, 170), (100, 50, 40), (130, 130, 200), (40, 60, 40), (60, 100, 120), (80, 120, 170), (120, 40, 40), (90, 0, 0), (200, 0, 0), (170, 100, 40), (200, 185, 130), (120, 85, 60), (100, 70, 40), (80, 60, 40), (100, 140, 45), (115, 150, 70), (0, 170, 45), (100, 160, 20), (180, 180, 40), (200, 190, 60), (80, 100, 40), (0, 100, 0), (50, 70, 30), (40, 65, 40)]
|
238
|
+
|
239
|
+
#↑用意した色のテンプレート(rgb)
|
240
|
+
|
241
|
+
|
242
|
+
|
243
|
+
|
244
|
+
|
245
|
+
|
246
|
+
|
247
|
+
f![イメージ説明](9792dc25b0893bd07159f748839d1633.png)n range(im.size[0]):
|
248
|
+
|
249
|
+
for z in range(im.size[1]):
|
250
|
+
|
251
|
+
rgb=im.getpixel((x,z))[0:3]
|
252
|
+
|
253
|
+
m=[dis(rgb,p) for p in palette]
|
254
|
+
|
255
|
+
#↑現在指定しているピクセルの色(rgb)とパレットそれぞれを比較したリスト作成
|
256
|
+
|
257
|
+
new_im.putpixel((x,z),palette[m.index(min(m))]) #作成したリストの最小値に値するタプルで色付け
|
258
|
+
|
259
|
+
|
260
|
+
|
261
|
+
|
262
|
+
|
263
|
+
new_im.save("output.jpg",quarity=90)
|
264
|
+
|
265
|
+
|
266
|
+
|
267
|
+
|
268
|
+
|
269
|
+
|
270
|
+
|
271
|
+
```
|
272
|
+
|
273
|
+
|
274
|
+
|
275
|
+
|
276
|
+
|
135
277
|
### 試したこと
|
136
278
|
|
137
279
|
近い色を判定するために、まずrgbのタプル同士でのユークリッド距離として近い色を検出させました。
|
@@ -145,3 +287,25 @@
|
|
145
287
|
最後に、現在のソースコードのようにrgb→xyz→L*a*b*方式に変換してユークリッド距離での判定をしました。
|
146
288
|
|
147
289
|
これらのことを行なったのですが似たような色へと変換することが困難でした。
|
290
|
+
|
291
|
+
|
292
|
+
|
293
|
+
|
294
|
+
|
295
|
+
|
296
|
+
|
297
|
+
### 《追記分》
|
298
|
+
|
299
|
+
ユークリッド距離での判定がイマイチだったので、2つ目のソースコードでは以下のURLの「CIE94」を試しています。
|
300
|
+
|
301
|
+
https://ja.m.wikipedia.org/wiki/色差
|
302
|
+
|
303
|
+
|
304
|
+
|
305
|
+
|
306
|
+
|
307
|
+
|
308
|
+
|
309
|
+
左(base.jpg)→右(output.jpg)です。それぞれ2つ試しています。
|
310
|
+
|
311
|
+
![イメージ説明](33721052ec07fee94bce216931a18e07.png)
|