質問編集履歴

1

追記依頼の反映

2019/04/29 07:19

投稿

YabQ
YabQ

スコア35

test CHANGED
File without changes
test CHANGED
@@ -72,6 +72,282 @@
72
72
 
73
73
 
74
74
 
75
+ **[追記]コード提示の追記依頼を受けたため,掲載します.**
76
+
77
+ 参考にしたサイト[「ツイッター画像を使ってモザイクアートを作る」
78
+
79
+ ](https://kenyu-life.com/2018/10/31/mosaic_art_python/)
80
+
81
+ (https://kenyu-life.com/2018/10/31/mosaic_art_python/)
82
+
83
+ のソースコードからファイルパスを変えたのみです.
84
+
85
+ (ユーザ名の部分のみ[ユーザ名]で置き換えてあります.)
86
+
87
+
88
+
89
+ ```Python3
90
+
91
+ from PIL import Image,ImageFilter
92
+
93
+ import subprocess
94
+
95
+ import os
96
+
97
+ import random
98
+
99
+ import math
100
+
101
+ import time
102
+
103
+ import cv2 as cv
104
+
105
+ import numpy as np
106
+
107
+
108
+
109
+ #==============設定===================
110
+
111
+ #素材画像の入っているフォルダ
112
+
113
+ SourceDir="/Users/[ユーザ名]/Desktop/mosaicA/sozai/"
114
+
115
+
116
+
117
+ #目標となる画像
118
+
119
+ GoalImage="/Users/[ユーザ名]/Desktop/mosaicA/moto/moto1.jpg"
120
+
121
+
122
+
123
+ #出力の名前
124
+
125
+ OutputImage="output.jpg"
126
+
127
+
128
+
129
+ #動画
130
+
131
+ OutputMovie="movie.mp4"
132
+
133
+
134
+
135
+ #動画のフレームレート
136
+
137
+ Framerate=25
138
+
139
+
140
+
141
+ #動画フォーマット
142
+
143
+ fourcc="mp4v"
144
+
145
+
146
+
147
+ #フレームスキップ
148
+
149
+ FrameSkip=30
150
+
151
+
152
+
153
+ #素材画像の色の平均値を出す時に色を取得する間隔
154
+
155
+ PickInterval=(1,1)
156
+
157
+
158
+
159
+ #素材の画像のサイズ(読み込み時にここで指定したサイズに変換される)
160
+
161
+ SourceImageSize=(100,100)
162
+
163
+
164
+
165
+ #x,yそれぞれ何個の画像を並べるか
166
+
167
+ TileCount=(100,100)
168
+
169
+
170
+
171
+ #ターゲット画像の倍率
172
+
173
+ TargetZoom=5
174
+
175
+ #=====================================
176
+
177
+
178
+
179
+
180
+
181
+ def ColorAvg(img,interval=(1,1)): #pythonのループ使用
182
+
183
+ #画像の色の平均値を求める
184
+
185
+ s=(0,0,0)
186
+
187
+ n=0
188
+
189
+ for y in range(0,img.size[1],interval[1]):
190
+
191
+ for x in range(0,img.size[0],interval[0]):
192
+
193
+ c=img.getpixel((x,y))
194
+
195
+ s=tuple(i+k for i,k in zip(s,c))
196
+
197
+ n=n+1
198
+
199
+ s=tuple(math.floor(i/n) for i in s)
200
+
201
+ return s
202
+
203
+
204
+
205
+ def ColorChange(img,col,Avg):
206
+
207
+ #imgの色の平均値がcolになるようにフィルターに掛ける
208
+
209
+ #元画像の平均値を必要とする
210
+
211
+ ds=tuple(i-k for i,k in zip(col,Avg))
212
+
213
+ r,g,b=img.split()[0:3]
214
+
215
+ r=r.point(lambda x: x+ds[0] if 0 <= x+ds[0] and x+ds[0] < 256 else 0 if x+ds[0] < 0 else 255)
216
+
217
+ g=g.point(lambda x: x+ds[1] if 0 <= x+ds[1] and x+ds[1] < 256 else 0 if x+ds[1] < 0 else 255)
218
+
219
+ b=b.point(lambda x: x+ds[2] if 0 <= x+ds[2] and x+ds[2] < 256 else 0 if x+ds[2] < 0 else 255)
220
+
221
+ return Image.merge("RGB",(r,g,b))
222
+
223
+
224
+
225
+ def Mosaic(img,src,video=None,count=(100,100),interval=(10,10),FrameSkip=0):
226
+
227
+ #モザイクアートを生成する
228
+
229
+ #img:元画像
230
+
231
+ #dst:動画の保存先
232
+
233
+ #src:モザイクアートに使う画像群
234
+
235
+ #count:x方向,y方向にそれぞれ何個の画像を使うか
236
+
237
+ #split:画像の色平均を取る時に色を取得する間隔
238
+
239
+
240
+
241
+ Target=Image.new("RGB",img.size)
242
+
243
+ print("%s:各素材グラフィックの色平均値を導出開始"%(str(time.time()-startTime)))
244
+
245
+ SourceImg=[(i,ColorAvg(i,interval)) for i in src]
246
+
247
+ SourceImgTemp=[]
248
+
249
+ print("%s:各素材グラフィックの色平均値を導出完了"%(str(time.time()-startTime)))
250
+
251
+ print("%s:タイルリストを生成開始"%(str(time.time()-startTime)))
252
+
253
+ RectList=[]
254
+
255
+ for y in range(0,count[1]):
256
+
257
+ for x in range(0,count[0]):
258
+
259
+ tileRect=(x*img.size[0]/count[0],y*img.size[1]/count[1],(x+1)*img.size[0]/count[0],(y+1)*img.size[1]/count[1])
260
+
261
+ tileRect=tuple(math.floor(i) for i in tileRect)
262
+
263
+ RectList.append(tileRect)
264
+
265
+ print("%s:タイルリストを生成完了"%(str(time.time()-startTime)))
266
+
267
+ print("%s:モザイクアートを生成開始"%(time.time()-startTime))
268
+
269
+ TileCount=0
270
+
271
+ Frame=np.array(Target)[:,:,::-1]
272
+
273
+ video.write(Frame)
274
+
275
+ while(len(RectList)>0):
276
+
277
+ r=random.randrange(len(RectList))
278
+
279
+ tileRect=RectList[r]
280
+
281
+ del RectList[r]
282
+
283
+ Pivot=img.getpixel((math.floor((tileRect[0]+tileRect[2])/2),math.floor((tileRect[1]+tileRect[3])/2)))
284
+
285
+ if(len(SourceImgTemp)==0):
286
+
287
+ SourceImgTemp=SourceImg.copy()
288
+
289
+ r=random.randrange(len(SourceImgTemp))
290
+
291
+ tempSrc=ColorChange(SourceImgTemp[r][0],Pivot,SourceImgTemp[r][1])
292
+
293
+ del SourceImgTemp[r]
294
+
295
+ tempSrc=tempSrc.resize((tileRect[2]-tileRect[0],tileRect[3]-tileRect[1]))
296
+
297
+ Target.paste(tempSrc,(tileRect[0],tileRect[1]))
298
+
299
+ if(TileCount%(FrameSkip+1)==0 and type(video)==cv.VideoWriter):
300
+
301
+ Frame=np.array(Target)[:,:,::-1]
302
+
303
+ video.write(Frame)
304
+
305
+ #cv.imshow("",Frame)
306
+
307
+ #cv.waitKey(1)
308
+
309
+ TileCount+=1
310
+
311
+ Frame=np.array(Target)[:,:,::-1]
312
+
313
+ video.write(Frame)
314
+
315
+ print("%s:モザイクアートを生成完了"%(str(time.time()-startTime)))
316
+
317
+ return Target
318
+
319
+
320
+
321
+ if __name__=="__main__":
322
+
323
+ startTime=time.time()
324
+
325
+ Res=subprocess.run(["ls",SourceDir],stdout=subprocess.PIPE)
326
+
327
+ Res=Res.stdout.decode().split("\n")
328
+
329
+ Res=Res[:len(Res)-1]
330
+
331
+ src=[Image.open(SourceDir+i).resize(SourceImageSize) for i in Res]
332
+
333
+ target=Image.open(GoalImage)
334
+
335
+ target=target.resize(tuple(math.floor(i*TargetZoom) for i in target.size))
336
+
337
+ fourcc2=cv.VideoWriter.fourcc(*fourcc)
338
+
339
+ v=cv.VideoWriter(OutputMovie,int(fourcc2),Framerate,target.size)
340
+
341
+ Mosaic(target,src,video=v,interval=PickInterval,count=TileCount,FrameSkip=FrameSkip).save(OutputImage)
342
+
343
+ v.release()
344
+
345
+ ```
346
+
347
+
348
+
349
+
350
+
75
351
  ### 試したこと
76
352
 
77
353
  * ```pip3 install pillow -U``` でpillowをアップデートしてみましたが,エラーは発生