HighCWu commited on
Commit
801c5bc
1 Parent(s): bc8f221
This view is limited to 50 files because it contains too many changes.   See raw diff
README.md CHANGED
@@ -1,7 +1,7 @@
1
  ---
2
  title: Style2Paints 4.5 Gradio
3
- emoji: 📉
4
- colorFrom: red
5
  colorTo: yellow
6
  sdk: gradio
7
  sdk_version: 3.27.0
 
1
  ---
2
  title: Style2Paints 4.5 Gradio
3
+ emoji: 🐨
4
+ colorFrom: indigo
5
  colorTo: yellow
6
  sdk: gradio
7
  sdk_version: 3.27.0
app.py ADDED
@@ -0,0 +1,663 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ import datetime
4
+ import pickle
5
+ import base64
6
+ import json
7
+ import gzip
8
+ import re
9
+ import gradio as gr
10
+
11
+ from tqdm import tqdm
12
+ from cv2.ximgproc import l0Smooth, createGuidedFilter, guidedFilter
13
+
14
+
15
+ import tensorflow
16
+
17
+ tensorflow.compat.v1.disable_v2_behavior()
18
+ tf = tensorflow.compat.v1
19
+
20
+
21
+ import os
22
+ import glob
23
+ import shutil
24
+
25
+ splash = glob.glob('ui/web-mobile/splash*')[0]
26
+ os.remove(splash)
27
+ shutil.copy('res/splash.png', splash)
28
+ with open('ui/web-mobile/index.html', 'r', encoding='utf-8') as f:
29
+ page = f.read()
30
+ with open('ui/web-mobile/index.html', 'w', encoding='utf-8') as f:
31
+ f.write(page.replace('Cocos Creator | ', ''))
32
+
33
+
34
+ def ToGray(x):
35
+ R = x[:, :, :, 0:1]
36
+ G = x[:, :, :, 1:2]
37
+ B = x[:, :, :, 2:3]
38
+ return 0.30 * R + 0.59 * G + 0.11 * B
39
+
40
+
41
+ def VGG2RGB(x):
42
+ return (x + [103.939, 116.779, 123.68])[:, :, :, ::-1]
43
+
44
+
45
+ def norm_feature(x, core):
46
+ cs0 = tf.shape(core)[1]
47
+ cs1 = tf.shape(core)[2]
48
+ small = tf.image.resize_area(x, (cs0, cs1))
49
+ avged = tf.nn.avg_pool(tf.pad(small, [[0, 0], [2, 2], [2, 2], [0, 0]], 'REFLECT'), [1, 5, 5, 1], [1, 1, 1, 1],
50
+ 'VALID')
51
+ return tf.image.resize_bicubic(avged, tf.shape(x)[1:3])
52
+
53
+
54
+ def blur(x):
55
+ def layer(op):
56
+ def layer_decorated(self, *args, **kwargs):
57
+ # Automatically set a name if not provided.
58
+ name = kwargs.setdefault('name', self.get_unique_name(op.__name__))
59
+ # Figure out the layer inputs.
60
+ if len(self.terminals) == 0:
61
+ raise RuntimeError('No input variables found for layer %s.' % name)
62
+ elif len(self.terminals) == 1:
63
+ layer_input = self.terminals[0]
64
+ else:
65
+ layer_input = list(self.terminals)
66
+ # Perform the operation and get the output.
67
+ layer_output = op(self, layer_input, *args, **kwargs)
68
+ # Add to layer LUT.
69
+ self.layers[name] = layer_output
70
+ # This output is now the input for the next layer.
71
+ self.feed(layer_output)
72
+ # Return self for chained calls.
73
+ return self
74
+
75
+ return layer_decorated
76
+
77
+ class Smoother(object):
78
+ def __init__(self, inputs, filter_size, sigma):
79
+ self.inputs = inputs
80
+ self.terminals = []
81
+ self.layers = dict(inputs)
82
+ self.filter_size = filter_size
83
+ self.sigma = sigma
84
+ self.setup()
85
+
86
+ def setup(self):
87
+ (self.feed('data')
88
+ .conv(name='smoothing'))
89
+
90
+ def get_unique_name(self, prefix):
91
+ ident = sum(t.startswith(prefix) for t, _ in self.layers.items()) + 1
92
+ return '%s_%d' % (prefix, ident)
93
+
94
+ def feed(self, *args):
95
+ assert len(args) != 0
96
+ self.terminals = []
97
+ for fed_layer in args:
98
+ if isinstance(fed_layer, str):
99
+ try:
100
+ fed_layer = self.layers[fed_layer]
101
+ except KeyError:
102
+ raise KeyError('Unknown layer name fed: %s' % fed_layer)
103
+ self.terminals.append(fed_layer)
104
+ return self
105
+
106
+ def gauss_kernel(self, kernlen=21, nsig=3, channels=1):
107
+ out_filter = np.load('./nets/gau.npy')
108
+ return out_filter
109
+
110
+ def make_gauss_var(self, name, size, sigma, c_i):
111
+ kernel = self.gauss_kernel(size, sigma, c_i)
112
+ var = tf.Variable(tf.convert_to_tensor(kernel), name=name)
113
+ return var
114
+
115
+ def get_output(self):
116
+ '''Returns the smoother output.'''
117
+ return self.terminals[-1]
118
+
119
+ @layer
120
+ def conv(self,
121
+ input,
122
+ name,
123
+ padding='SAME'):
124
+ # Get the number of channels in the input
125
+ c_i = input.get_shape().as_list()[3]
126
+ # Convolution for a given input and kernel
127
+ convolve = lambda i, k: tf.nn.depthwise_conv2d(i, k, [1, 1, 1, 1],
128
+ padding=padding)
129
+ with tf.variable_scope(name) as scope:
130
+ kernel = self.make_gauss_var('gauss_weight', self.filter_size,
131
+ self.sigma, c_i)
132
+ output = convolve(input, kernel)
133
+ return output
134
+
135
+ return Smoother({'data': tf.pad(x, [[0, 0], [9, 9], [9, 9], [0, 0]], 'SYMMETRIC')}, 7, 2).get_output()[:, 9: -9,
136
+ 9: -9, :]
137
+
138
+
139
+ def downsample(x):
140
+ return tf.nn.avg_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
141
+
142
+
143
+ def nts(x):
144
+ return (x + [103.939, 116.779, 123.68])[:, :, :, ::-1] / 255.0
145
+
146
+
147
+ def np_expand_image(x):
148
+ p = np.pad(x, ((1, 1), (1, 1), (0, 0)), 'symmetric')
149
+ r = []
150
+ r.append(p[:-2, 1:-1, :])
151
+ r.append(p[1:-1, :-2, :])
152
+ r.append(p[1:-1, 1:-1, :])
153
+ r.append(p[1:-1, 2:, :])
154
+ r.append(p[2:, 1:-1, :])
155
+ return np.stack(r, axis=2)
156
+
157
+
158
+ def build_sketch_sparse(x, abs):
159
+ x = x[:, :, None].astype(np.float32)
160
+ expanded = np_expand_image(x)
161
+ distance = x[:, :, None] - expanded
162
+ if abs:
163
+ distance = np.abs(distance)
164
+ weight = 8 - distance
165
+ weight[weight < 0] = 0.0
166
+ weight /= np.sum(weight, axis=2, keepdims=True)
167
+ return weight
168
+
169
+
170
+ def build_repeat_mulsep(x, m, i):
171
+ a = m[:, :, 0]
172
+ b = m[:, :, 1]
173
+ c = m[:, :, 2]
174
+ d = m[:, :, 3]
175
+ e = m[:, :, 4]
176
+ y = x
177
+ for _ in range(i):
178
+ p = tf.pad(y, [[1, 1], [1, 1], [0, 0]], 'SYMMETRIC')
179
+ y = p[:-2, 1:-1, :] * a + p[1:-1, :-2, :] * b + y * c + p[1:-1, 2:, :] * d + p[2:, 1:-1, :] * e
180
+ return y
181
+
182
+
183
+ session = tf.Session()
184
+ tf.keras.backend.set_session(session)
185
+
186
+ ip1 = tf.placeholder(dtype=tf.float32, shape=(None, None, None, 1))
187
+ ip3 = tf.placeholder(dtype=tf.float32, shape=(None, None, None, 3))
188
+ ip4 = tf.placeholder(dtype=tf.float32, shape=(None, None, None, 4))
189
+ ipsp9 = tf.placeholder(dtype=tf.float32, shape=(None, None, 5, 1))
190
+ ipsp3 = tf.placeholder(dtype=tf.float32, shape=(None, None, 3))
191
+
192
+ tf_sparse_op_H = build_repeat_mulsep(ipsp3, ipsp9, 64)
193
+ tf_sparse_op_L = build_repeat_mulsep(ipsp3, ipsp9, 16)
194
+
195
+
196
+ def make_graph():
197
+ with gzip.open('./nets/refs.net', 'rb') as fp:
198
+ refs_img = pickle.load(fp)
199
+
200
+ tail = tf.keras.models.load_model('./nets/tail.net')
201
+ reader = tf.keras.models.load_model('./nets/reader.net')
202
+ head = tf.keras.models.load_model('./nets/head.net')
203
+ neck = tf.keras.models.load_model('./nets/neck.net')
204
+ inception = tf.keras.models.load_model('./nets/inception.net')
205
+ render_head = tf.keras.models.load_model('./nets/render_head.net')
206
+ render_neck = tf.keras.models.load_model('./nets/render_neck.net')
207
+
208
+ tail_op = tail(ip3)
209
+ features = reader(ip3 / 255.0)
210
+ print('Loaded some basic models.')
211
+ feed = [1 - ip1 / 255.0, (ip4[:, :, :, 0:3] / 127.5 - 1) * ip4[:, :, :, 3:4] / 255.0]
212
+ for _ in range(len(features)):
213
+ feed.append(tf.reduce_mean(features[_], axis=[1, 2]))
214
+ nil0, nil1, head_temp = head(feed)
215
+ feed[0] = tf.clip_by_value(1 - tf.image.resize_bilinear(ToGray(VGG2RGB(head_temp) / 255.0), tf.shape(ip1)[1:3]),
216
+ 0.0, 1.0)
217
+ nil4, nil5, head_temp = neck(feed)
218
+ head_op = VGG2RGB(head_temp)
219
+ features_render = inception((ip3 + (downsample(ip1) - blur(downsample(ip1))) * 2.0) / 255.0)
220
+ precessed_feed = [(ip4[:, :, :, 0:3] / 127.5 - 1) * ip4[:, :, :, 3:4] / 255.0] + [
221
+ norm_feature(item, features_render[-1]) for item in features_render]
222
+ nil6, nil7, render_A = render_head([1 - ip1 / 255.0] + precessed_feed)
223
+ nil8, nil9, render_B = render_neck(
224
+ [1 - tf.image.resize_bilinear(ToGray(nts(render_A)), tf.shape(ip1)[1:3])] + precessed_feed)
225
+ render_op = nts(render_B) * 255.0
226
+ print('Loaded - Style2Paints Deep Learning Engine V4.6 - GPU')
227
+
228
+ session.run(tf.global_variables_initializer())
229
+
230
+ tail.load_weights('./nets/tail.net')
231
+ head.load_weights('./nets/head.net')
232
+ neck.load_weights('./nets/neck.net')
233
+ reader.load_weights('./nets/reader.net')
234
+ inception.load_weights('./nets/inception.net')
235
+ render_head.load_weights('./nets/render_head.net')
236
+ render_neck.load_weights('./nets/render_neck.net')
237
+
238
+ print('Deep learning modules are ready.')
239
+
240
+ return tail_op, head_op, render_op, refs_img
241
+
242
+
243
+ tail_op_g, head_op_g, render_op_g, refs_img_g = make_graph()
244
+
245
+
246
+ def go_tail(x):
247
+ def srange(l, s):
248
+ result = []
249
+ iters = int(float(l) / float(s))
250
+ for i in range(iters):
251
+ result.append([i * s, (i + 1) * s])
252
+ result[len(result) - 1][1] = l
253
+ return result
254
+
255
+ H, W, C = x.shape
256
+ padded_img = np.pad(x, ((20, 20), (20, 20), (0, 0)), 'symmetric').astype(np.float32) / 255.0
257
+ lines = []
258
+ for hs, he in srange(H, 64):
259
+ items = []
260
+ for ws, we in srange(W, 64):
261
+ items.append(padded_img[hs:he + 40, ws:we + 40, :])
262
+ lines.append(items)
263
+ iex = 0
264
+ result_all_lines = []
265
+ for line in lines:
266
+ result_one_line = []
267
+ for item in line:
268
+ ots = session.run(tail_op_g, feed_dict={ip3: item[None, :, :, :]})[0]
269
+ result_one_line.append(ots[41:-41, 41:-41, :])
270
+ print('Slicing ... ' + str(iex))
271
+ iex += 1
272
+ result_one_line = np.concatenate(result_one_line, axis=1)
273
+ result_all_lines.append(result_one_line)
274
+ result_all_lines = np.concatenate(result_all_lines, axis=0)
275
+ return (result_all_lines * 255.0).clip(0, 255).astype(np.uint8)
276
+
277
+
278
+ def go_head(sketch, global_hint, local_hint):
279
+ return session.run(head_op_g, feed_dict={
280
+ ip1: sketch[None, :, :, None], ip3: global_hint[None, :, :, :], ip4: local_hint[None, :, :, :]
281
+ })[0].clip(0, 255).astype(np.uint8)
282
+
283
+
284
+ def go_render(sketch, segmentation, points):
285
+ return session.run(render_op_g, feed_dict={
286
+ ip1: sketch[None, :, :, None], ip3: segmentation[None, :, :, :], ip4: points[None, :, :, :]
287
+ })[0].clip(0, 255).astype(np.uint8)
288
+
289
+
290
+ print('Deep learning functions are ready.')
291
+
292
+
293
+ def k_resize(x, k):
294
+ if x.shape[0] < x.shape[1]:
295
+ s0 = k
296
+ s1 = int(x.shape[1] * (k / x.shape[0]))
297
+ s1 = s1 - s1 % 64
298
+ _s0 = 16 * s0
299
+ _s1 = int(x.shape[1] * (_s0 / x.shape[0]))
300
+ _s1 = (_s1 + 32) - (_s1 + 32) % 64
301
+ else:
302
+ s1 = k
303
+ s0 = int(x.shape[0] * (k / x.shape[1]))
304
+ s0 = s0 - s0 % 64
305
+ _s1 = 16 * s1
306
+ _s0 = int(x.shape[0] * (_s1 / x.shape[1]))
307
+ _s0 = (_s0 + 32) - (_s0 + 32) % 64
308
+ new_min = min(_s1, _s0)
309
+ raw_min = min(x.shape[0], x.shape[1])
310
+ if new_min < raw_min:
311
+ interpolation = cv2.INTER_AREA
312
+ else:
313
+ interpolation = cv2.INTER_LANCZOS4
314
+ y = cv2.resize(x, (_s1, _s0), interpolation=interpolation)
315
+ return y
316
+
317
+
318
+ def d_resize(x, d, fac=1.0):
319
+ new_min = min(int(d[1] * fac), int(d[0] * fac))
320
+ raw_min = min(x.shape[0], x.shape[1])
321
+ if new_min < raw_min:
322
+ interpolation = cv2.INTER_AREA
323
+ else:
324
+ interpolation = cv2.INTER_LANCZOS4
325
+ y = cv2.resize(x, (int(d[1] * fac), int(d[0] * fac)), interpolation=interpolation)
326
+ return y
327
+
328
+
329
+ def min_resize(x, m):
330
+ if x.shape[0] < x.shape[1]:
331
+ s0 = m
332
+ s1 = int(float(m) / float(x.shape[0]) * float(x.shape[1]))
333
+ else:
334
+ s0 = int(float(m) / float(x.shape[1]) * float(x.shape[0]))
335
+ s1 = m
336
+ new_max = min(s1, s0)
337
+ raw_max = min(x.shape[0], x.shape[1])
338
+ if new_max < raw_max:
339
+ interpolation = cv2.INTER_AREA
340
+ else:
341
+ interpolation = cv2.INTER_LANCZOS4
342
+ y = cv2.resize(x, (s1, s0), interpolation=interpolation)
343
+ return y
344
+
345
+
346
+ def cli_norm(sketch):
347
+ light = np.max(min_resize(sketch, 64), axis=(0, 1), keepdims=True)
348
+ intensity = (light - sketch.astype(np.float32)).clip(0, 255)
349
+ line_intensities = np.sort(intensity[intensity > 16])[::-1]
350
+ line_quantity = float(line_intensities.shape[0])
351
+ intensity /= line_intensities[int(line_quantity * 0.1)]
352
+ intensity *= 0.9
353
+ return (255.0 - intensity * 255.0).clip(0, 255).astype(np.uint8)
354
+
355
+
356
+ def cv2_imwrite(a, b):
357
+ print(a)
358
+ cv2.imwrite(a, b)
359
+
360
+
361
+ def from_png_to_jpg(map):
362
+ if map.shape[2] == 3:
363
+ return map
364
+ color = map[:, :, 0:3].astype(np.float) / 255.0
365
+ alpha = map[:, :, 3:4].astype(np.float) / 255.0
366
+ reversed_color = 1 - color
367
+ final_color = (255.0 - reversed_color * alpha * 255.0).clip(0, 255).astype(np.uint8)
368
+ return final_color
369
+
370
+
371
+ def s_enhance(x, k=2.0):
372
+ p = cv2.cvtColor(x, cv2.COLOR_RGB2HSV).astype(np.float)
373
+ p[:, :, 1] *= k
374
+ p = p.clip(0, 255).astype(np.uint8)
375
+ return cv2.cvtColor(p, cv2.COLOR_HSV2RGB).clip(0, 255)
376
+
377
+
378
+ def ini_hint(x):
379
+ r = np.zeros(shape=(x.shape[0], x.shape[1], 4), dtype=np.uint8)
380
+ return r
381
+
382
+
383
+ def opreate_normal_hint(gird, points, length):
384
+ h = gird.shape[0]
385
+ w = gird.shape[1]
386
+ for point in points:
387
+ x, y, r, g, b = point
388
+ x = int(x * w)
389
+ y = int(y * h)
390
+ l_ = max(0, x - length)
391
+ b_ = max(0, y - length)
392
+ r_ = min(w, x + length + 1)
393
+ t_ = min(h, y + length + 1)
394
+ gird[b_:t_, l_:r_, 2] = r
395
+ gird[b_:t_, l_:r_, 1] = g
396
+ gird[b_:t_, l_:r_, 0] = b
397
+ gird[b_:t_, l_:r_, 3] = 255.0
398
+ return gird
399
+
400
+
401
+ def get_hdr(x):
402
+ def get_hdr_g(x):
403
+ img = x.astype(np.float32)
404
+ mean = np.mean(img)
405
+ h_mean = mean.copy()
406
+ l_mean = mean.copy()
407
+ for i in range(2):
408
+ h_mean = np.mean(img[img >= h_mean])
409
+ l_mean = np.mean(img[img <= l_mean])
410
+ for i in range(2):
411
+ l_mean = np.mean(img[img <= l_mean])
412
+ return l_mean, mean, h_mean
413
+
414
+ l_mean = np.zeros(shape=(1, 1, 3), dtype=np.float32)
415
+ mean = np.zeros(shape=(1, 1, 3), dtype=np.float32)
416
+ h_mean = np.zeros(shape=(1, 1, 3), dtype=np.float32)
417
+ for c in range(3):
418
+ l, m, h = get_hdr_g(x[:, :, c])
419
+ l_mean[:, :, c] = l
420
+ mean[:, :, c] = m
421
+ h_mean[:, :, c] = h
422
+ return l_mean, mean, h_mean
423
+
424
+
425
+ def f2(x1, x2, x3, y1, y2, y3, x):
426
+ A = y1 * ((x - x2) * (x - x3)) / ((x1 - x2) * (x1 - x3))
427
+ B = y2 * ((x - x1) * (x - x3)) / ((x2 - x1) * (x2 - x3))
428
+ C = y3 * ((x - x1) * (x - x2)) / ((x3 - x1) * (x3 - x2))
429
+ return A + B + C
430
+
431
+
432
+ print('Tricks loaded.')
433
+
434
+
435
+ def refine_image(image, sketch, origin):
436
+ verbose = False
437
+
438
+ def cv_log(name, img):
439
+ if verbose:
440
+ print(name)
441
+ cv2.imshow('cv_log', img.clip(0, 255).astype(np.uint8))
442
+ cv2.imwrite('cv_log.png', img.clip(0, 255).astype(np.uint8))
443
+ cv2.waitKey(0)
444
+
445
+ print('Building Sparse Matrix ...')
446
+ sketch = sketch.astype(np.float32)
447
+ sparse_matrix = build_sketch_sparse(sketch, True)
448
+ bright_matrix = build_sketch_sparse(sketch - cv2.GaussianBlur(sketch, (0, 0), 3.0), False)
449
+ guided_matrix = createGuidedFilter(sketch.clip(0, 255).astype(np.uint8), 1, 0.01)
450
+ HDRL, HDRM, HDRH = get_hdr(image)
451
+
452
+ def go_guide(x):
453
+ y = x + (x - cv2.GaussianBlur(x, (0, 0), 1)) * 2.0
454
+ for _ in tqdm(range(4)):
455
+ y = guided_matrix.filter(y)
456
+ return y
457
+
458
+ def go_refine_sparse(x):
459
+ return session.run(tf_sparse_op_H, feed_dict={ipsp3: x, ipsp9: sparse_matrix})
460
+
461
+ def go_refine_bright(x):
462
+ return session.run(tf_sparse_op_L, feed_dict={ipsp3: x, ipsp9: bright_matrix})
463
+
464
+ def go_flat(x):
465
+ pia = 32
466
+ y = x.clip(0, 255).astype(np.uint8)
467
+ y = cv2.resize(y, (x.shape[1] // 2, x.shape[0] // 2), interpolation=cv2.INTER_AREA)
468
+ y = np.pad(y, ((pia, pia), (pia, pia), (0, 0)), 'reflect')
469
+ y = l0Smooth(y, None, 0.01)
470
+ y = y[pia:-pia, pia:-pia, :]
471
+ y = cv2.resize(y, (x.shape[1], x.shape[0]), interpolation=cv2.INTER_CUBIC)
472
+ return y
473
+
474
+ def go_hdr(x):
475
+ xl, xm, xh = get_hdr(x)
476
+ y = f2(xl, xm, xh, HDRL, HDRM, HDRH, x)
477
+ return y.clip(0, 255)
478
+
479
+ def go_blend(BGR, X, m):
480
+ BGR = BGR.clip(0, 255).astype(np.uint8)
481
+ X = X.clip(0, 255).astype(np.uint8)
482
+ YUV = cv2.cvtColor(BGR, cv2.COLOR_BGR2YUV)
483
+ s_l = YUV[:, :, 0].astype(np.float32)
484
+ t_l = X.astype(np.float32)
485
+ r_l = (s_l * t_l / 255.0) if m else np.minimum(s_l, t_l)
486
+ YUV[:, :, 0] = r_l.clip(0, 255).astype(np.uint8)
487
+ return cv2.cvtColor(YUV, cv2.COLOR_YUV2BGR)
488
+
489
+ print('Getting Target ...')
490
+ smoothed = d_resize(image, sketch.shape)
491
+ print('Global Optimization ...')
492
+ cv_log('smoothed', smoothed)
493
+ sparse_smoothed = go_refine_sparse(smoothed)
494
+ cv_log('smoothed', sparse_smoothed)
495
+ smoothed = go_guide(sparse_smoothed)
496
+ cv_log('smoothed', smoothed)
497
+ smoothed = go_hdr(smoothed)
498
+ cv_log('smoothed', smoothed)
499
+ print('Decomposition Optimization ...')
500
+ flat = sparse_smoothed.copy()
501
+ cv_log('flat', flat)
502
+ flat = go_refine_bright(flat)
503
+ cv_log('flat', flat)
504
+ flat = go_flat(flat)
505
+ cv_log('flat', flat)
506
+ flat = go_refine_sparse(flat)
507
+ cv_log('flat', flat)
508
+ flat = go_guide(flat)
509
+ cv_log('flat', flat)
510
+ flat = go_hdr(flat)
511
+ cv_log('flat', flat)
512
+ print('Blending Optimization ...')
513
+ cv_log('origin', origin)
514
+ blended_smoothed = go_blend(smoothed, origin, False)
515
+ cv_log('blended_smoothed', blended_smoothed)
516
+ blended_flat = go_blend(flat, origin, True)
517
+ cv_log('blended_flat', blended_flat)
518
+ print('Optimization finished.')
519
+ return smoothed, flat, blended_smoothed, blended_flat
520
+
521
+
522
+ print('Fundamental Methods loaded.')
523
+
524
+
525
+ def cv2_encode(image: np.ndarray):
526
+ if image is None:
527
+ return 'null'
528
+ _, data = cv2.imencode('.png', image)
529
+ return 'data:image/png;base64,' + base64.b64encode(data).decode('utf8')
530
+
531
+
532
+ def get_request_image(request, name):
533
+ img = request.get(name)
534
+ img = re.sub('^data:image/.+;base64,', '', img)
535
+ img = base64.b64decode(img)
536
+ img = np.fromstring(img, dtype=np.uint8)
537
+ img = cv2.imdecode(img, -1)
538
+ return img
539
+
540
+
541
+ def upload_sketch(json_str, history):
542
+ request = json.loads(json_str)
543
+ origin = from_png_to_jpg(get_request_image(request, 'sketch'))
544
+ ID = datetime.datetime.now().strftime('H%HM%MS%S')
545
+ print('New room ID: ' + ID)
546
+ sketch = min_resize(origin, 512)
547
+ sketch = np.min(sketch, axis=2)
548
+ sketch = cli_norm(sketch)
549
+ sketch = np.tile(sketch[:, :, None], [1, 1, 3])
550
+ sketch = go_tail(sketch)
551
+ sketch = np.mean(sketch, axis=2)
552
+ if len(history) > 5:
553
+ history = history[-5:]
554
+ return ID + '_' + ID, [*history, {'ID': ID, 'origin': origin, 'sketch': sketch, 'results': {}}]
555
+
556
+
557
+ def request_result(json_str, history):
558
+ request = json.loads(json_str)
559
+ room = request.get("room")
560
+ ridx = next(i for i, his in enumerate(history) if his['ID'] == room)
561
+ room_path = './rooms/' + room + '/'
562
+ ID = datetime.datetime.now().strftime('H%HM%MS%S')
563
+ history[ridx]['results'][ID] = {}
564
+ points = request.get("points")
565
+ points = json.loads(points)
566
+ history[ridx]['results'][ID]['points'] = points
567
+ for _ in range(len(points)):
568
+ points[_][1] = 1 - points[_][1]
569
+ sketch = history[ridx]['sketch']
570
+ origin = history[ridx]['origin']
571
+ if origin.ndim == 3:
572
+ origin = cv2.cvtColor(origin, cv2.COLOR_BGR2GRAY)
573
+ origin = d_resize(origin, sketch.shape).astype(np.float32)
574
+ low_origin = cv2.GaussianBlur(origin, (0, 0), 3.0)
575
+ high_origin = origin - low_origin
576
+ low_origin = (low_origin / np.median(low_origin) * 255.0).clip(0, 255)
577
+ origin = (low_origin + high_origin).clip(0, 255).astype(np.uint8)
578
+ faceID = int(request.get("faceID")) - 65535
579
+ print(faceID)
580
+ if faceID > -1:
581
+ print('Default reference.')
582
+ face = from_png_to_jpg(refs_img_g[faceID])
583
+ else:
584
+ print('Load reference.')
585
+ face = from_png_to_jpg(get_request_image(request, 'face'))
586
+ face = s_enhance(face, 2.0)
587
+ print('request result room = ' + str(room) + ', ID = ' + str(ID))
588
+ print('processing painting in ' + room_path)
589
+ sketch_1024 = k_resize(sketch, 64)
590
+ hints_1024 = opreate_normal_hint(ini_hint(sketch_1024), points, length=2)
591
+ careless = go_head(sketch_1024, k_resize(face, 14), hints_1024)
592
+ smoothed_careless, flat_careless, blended_smoothed_careless, blended_flat_careless = refine_image(careless, sketch,
593
+ origin)
594
+ history[ridx]['results'][ID]['smoothed_careless'] = smoothed_careless
595
+ history[ridx]['results'][ID]['flat_careless'] = flat_careless
596
+ history[ridx]['results'][ID]['blended_smoothed_careless'] = blended_smoothed_careless
597
+ history[ridx]['results'][ID]['blended_flat_careless'] = blended_flat_careless
598
+ print('Stage I finished.')
599
+ careful = go_render(sketch_1024, d_resize(flat_careless, sketch_1024.shape, 0.5), hints_1024)
600
+ smoothed_careful, flat_careful, blended_smoothed_careful, blended_flat_careful = refine_image(careful, sketch,
601
+ origin)
602
+ history[ridx]['results'][ID]['smoothed_careful'] = smoothed_careful
603
+ history[ridx]['results'][ID]['flat_careful'] = flat_careful
604
+ history[ridx]['results'][ID]['blended_smoothed_careful'] = blended_smoothed_careful
605
+ history[ridx]['results'][ID]['blended_flat_careful'] = blended_flat_careful
606
+ history[ridx]['results'][ID]['lighted'] = blended_flat_careful
607
+ print('Stage II finished.')
608
+ return room + '_' + ID, history
609
+
610
+
611
+ def download_result(json_str, history):
612
+ request = json.loads(json_str)
613
+ room = request.get("room")
614
+ step = request.get("step")
615
+ name = request.get("name")
616
+ ridx = next(i for i, his in enumerate(history) if his['ID'] == room)
617
+ if history[ridx].get(name, None) is None:
618
+ result = history[ridx]['results'][step][name]
619
+ else:
620
+ result = history[ridx][name]
621
+
622
+ if name == 'points':
623
+ return json.dumps(result)
624
+
625
+ return cv2_encode(result)
626
+
627
+
628
+ with gr.Blocks() as demo:
629
+ history = gr.State(value=[])
630
+ with gr.Row():
631
+ with gr.Column():
632
+ btn_show = gr.Button("Open Style2Paints V4.6")
633
+ btn_show.click(None, _js="(_) => open('file/ui/web-mobile/index.html')")
634
+
635
+ with gr.Row():
636
+ with gr.Box():
637
+ with gr.Row():
638
+ upload_sketch_json = gr.Textbox(label="upload_sketch(json string)")
639
+ with gr.Row():
640
+ upload_sketch_btn = gr.Button(label="Submit sketch json")
641
+ with gr.Row():
642
+ upload_sketch_result = gr.Textbox(label="Result", interactive=False)
643
+ upload_sketch_btn.click(upload_sketch, [upload_sketch_json, history], [upload_sketch_result, history], api_name="upload_sketch")
644
+
645
+ with gr.Box():
646
+ with gr.Row():
647
+ request_result_json = gr.Textbox(label="request_result(json string)")
648
+ with gr.Row():
649
+ request_result_btn = gr.Button(label="Submit json of request for result")
650
+ with gr.Row():
651
+ request_result_result = gr.Textbox(label="Result", interactive=False)
652
+ upload_sketch_btn.click(request_result, [request_result_json, history], [request_result_result, history], api_name="request_result")
653
+
654
+ with gr.Box():
655
+ with gr.Row():
656
+ download_result_json = gr.Textbox(label="download_result(json string)")
657
+ with gr.Row():
658
+ download_result_btn = gr.Button(label="Submit json of download for result")
659
+ with gr.Row():
660
+ download_result_result = gr.Textbox(label="Result", interactive=False)
661
+ upload_sketch_btn.click(download_result, [download_result_json, history], [download_result_result], api_name="download_result")
662
+
663
+ demo.launch()
nets/gau.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3297028c7d29078be7722bca9b68b119f852794741cfb4185b990e1c469ecbae
3
+ size 324
nets/head.net ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fd5f608bf5511293cd582e6d87e55f483259b8d606feba7a5042382a19cde630
3
+ size 411622416
nets/inception.net ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9a503841e955ee56f2e0b71219952f0f554c9eaff9e887f82853f600f0ddee80
3
+ size 41501888
nets/neck.net ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e91e4e688379dc95a14ea8f33fa1c2141584b0387e16be5efcc7acb5299ad5d7
3
+ size 411623808
nets/reader.net ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5a65a53091acb96dbdcf325afb1b233ff374e220cb822fe8b1771dcd65f999df
3
+ size 41502832
nets/refs.net ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:92e95f226cb67abd309014b50eff810fef25e6cf3731aacea4efa3254c0a6adc
3
+ size 18324023
nets/render_head.net ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cacac78d2e19bd38b2efbdd8eb372594e333e5284e9f2c2b605652c8dd26ffad
3
+ size 411612752
nets/render_neck.net ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:66050656839363d7977dd970cc2f6d7f81722a8cf5cd67a1793bae8214a07c0b
3
+ size 411613336
nets/tail.net ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2255073ccdc311d8c61c074ffeb4ad7db200ca9116011e1cf213d6d4b1967e15
3
+ size 4018208
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ opencv-contrib-python>=4.1.0.25
2
+ tensorflow>=2.12.0
3
+ gradio>=3.20.1
4
+ scikit-learn>=0.23.1
5
+ scikit-image>=0.14.5
6
+ tqdm
res/Texture/1.jpg ADDED

Git LFS Details

  • SHA256: 0dce28125d936f3c5bbf8871b34aa6d038e01889bcc65cbbae49f9bb7a23f1a8
  • Pointer size: 129 Bytes
  • Size of remote file: 4.76 kB
res/Texture/127.png ADDED

Git LFS Details

  • SHA256: 2ee180cbe8710605abfb8a77dce2b77d9215263bfb77cb43fba9fe9c62e9c84e
  • Pointer size: 128 Bytes
  • Size of remote file: 362 Bytes
res/Texture/ai.png ADDED

Git LFS Details

  • SHA256: 6ff6df797e62b56fb1f5a21691d3b97708f09921455d446917997ac8d2be1ec5
  • Pointer size: 129 Bytes
  • Size of remote file: 1.84 kB
res/Texture/b.png ADDED

Git LFS Details

  • SHA256: 8c18e868a191f1a171643b8a4a5652072683f412d27d7880223876638918bd65
  • Pointer size: 128 Bytes
  • Size of remote file: 144 Bytes
res/Texture/big_logo.png ADDED

Git LFS Details

  • SHA256: 643664af8e1c0be0d6da4196e1a58c817fef726b5646e0755d5bda472fa98b17
  • Pointer size: 129 Bytes
  • Size of remote file: 3.18 kB
res/Texture/board.png ADDED

Git LFS Details

  • SHA256: 9483f602b24f67daf49b3007048554d9e9cbeff243c564c3f9cbfc9e43017a34
  • Pointer size: 128 Bytes
  • Size of remote file: 257 Bytes
res/Texture/brush.png ADDED

Git LFS Details

  • SHA256: e1da02b8d48292760959714fabb6f59170c30aadadbe9d73356f55f02c8ee26d
  • Pointer size: 129 Bytes
  • Size of remote file: 1.89 kB
res/Texture/circle.png ADDED

Git LFS Details

  • SHA256: d420b7999194572a9addd25831fdbf0f8eb86636e4d0e75c5526a073dbd9446a
  • Pointer size: 130 Bytes
  • Size of remote file: 16.9 kB
res/Texture/clear.png ADDED

Git LFS Details

  • SHA256: f61dfaa7179562f500c5a7bdfb70871f8048802669d03e82292426ca3859440c
  • Pointer size: 130 Bytes
  • Size of remote file: 15.7 kB
res/Texture/downloadh.png ADDED

Git LFS Details

  • SHA256: c0bae1de2227f90604a757a740ca89a62de326e387b78448e1b24767ccecfcb2
  • Pointer size: 130 Bytes
  • Size of remote file: 18.1 kB
res/Texture/drag.png ADDED

Git LFS Details

  • SHA256: 62a5691a31c9b24b5ea7b53fb704a50f5927e9a8b5b087cf7688be34d37abd5c
  • Pointer size: 130 Bytes
  • Size of remote file: 18.8 kB
res/Texture/dropper.png ADDED

Git LFS Details

  • SHA256: 5c746fc669e3e33d74bafe6dbcf9c9e467717024362acf940138f7492020fdcd
  • Pointer size: 130 Bytes
  • Size of remote file: 18.4 kB
res/Texture/dustbin.png ADDED

Git LFS Details

  • SHA256: 70e3291987314190480d0001f3d3dbeac5762f7714a3b71edfaac92046728aa5
  • Pointer size: 129 Bytes
  • Size of remote file: 1.52 kB
res/Texture/eraser.png ADDED

Git LFS Details

  • SHA256: 2ae7b99f34e1e7514d8cb24031ab780d735fba9d64a591d4f67784c0e3f16e3e
  • Pointer size: 130 Bytes
  • Size of remote file: 16.9 kB
res/Texture/fil.png ADDED

Git LFS Details

  • SHA256: 70e2055e83026d941458a49dd5057dcf259beb633563f1f565365f2a8f985885
  • Pointer size: 128 Bytes
  • Size of remote file: 461 Bytes
res/Texture/filled-circle.png ADDED

Git LFS Details

  • SHA256: eaa10af572bbd99b65362239b39e00ea1bb7106b9ddc8796fbf938af13a8c543
  • Pointer size: 129 Bytes
  • Size of remote file: 1.66 kB
res/Texture/folder.png ADDED

Git LFS Details

  • SHA256: 7902c8aa41f0f2d130cd01ad4bd439d507e401261e3eead2bc2fab5db27f6594
  • Pointer size: 129 Bytes
  • Size of remote file: 1.65 kB
res/Texture/girl.png ADDED

Git LFS Details

  • SHA256: d7eeac2edbb5d9a07bccc422077df3cec2b81e50876a49adbc477685e51c89ec
  • Pointer size: 131 Bytes
  • Size of remote file: 519 kB
res/Texture/girl_raw.png ADDED

Git LFS Details

  • SHA256: 02fdc9b17b3648ec379c18c7f9824446fa16849740c0cd8cc93e65092a4d25ae
  • Pointer size: 131 Bytes
  • Size of remote file: 439 kB
res/Texture/github.png ADDED

Git LFS Details

  • SHA256: 14fda50eaec92a4f2217e2480b4cf4dd0567c101b666fb4923b65479ea7a84c3
  • Pointer size: 129 Bytes
  • Size of remote file: 2.74 kB
res/Texture/grids.png ADDED

Git LFS Details

  • SHA256: 60a88e121f97a3c288ee40421909a9f433286a74979ecd5e2a17f188b8ffc1dd
  • Pointer size: 130 Bytes
  • Size of remote file: 15.6 kB
res/Texture/help.png ADDED

Git LFS Details

  • SHA256: e97d336706b1d6dbb3919414ad6cfb2927065793cd84ad3bf9903f097e722c09
  • Pointer size: 129 Bytes
  • Size of remote file: 2.73 kB
res/Texture/hint.png ADDED

Git LFS Details

  • SHA256: 6d09493aa0b1741dc99aef199d2b04118d5bd04493db85d18459ff348642921c
  • Pointer size: 127 Bytes
  • Size of remote file: 91 Bytes
res/Texture/left-arrow.png ADDED

Git LFS Details

  • SHA256: ae9d815a6608d7605de93a06a8edfdc0ef812da1c454e19d603f6f9316d26abe
  • Pointer size: 130 Bytes
  • Size of remote file: 15.9 kB
res/Texture/left.png ADDED

Git LFS Details

  • SHA256: 6973ae3b9ec05be4cca2a06a70e8cd00671c3d04373b59b2aa3fdc2cfeb3c567
  • Pointer size: 130 Bytes
  • Size of remote file: 16.6 kB
res/Texture/loading.png ADDED

Git LFS Details

  • SHA256: bf9e87e667193562b8775578664ef49ace0256f9599d2cef948c24bc3d729fbe
  • Pointer size: 129 Bytes
  • Size of remote file: 2.55 kB
res/Texture/magic.png ADDED

Git LFS Details

  • SHA256: cfa80908453f821a3fcec9bdd7cbb4badbcb9acb3df476d1965341eb7b696d39
  • Pointer size: 129 Bytes
  • Size of remote file: 2.77 kB
res/Texture/pallete.png ADDED

Git LFS Details

  • SHA256: 84ccf449e5b5aef9260144b4131d0489cd51841c1f2c4a73236809ad25399d4d
  • Pointer size: 130 Bytes
  • Size of remote file: 20.5 kB
res/Texture/pencil.png ADDED

Git LFS Details

  • SHA256: df09b6093d56b95ff0b8245192f142deccb2cd4717acc09af0d70a5939b6ff35
  • Pointer size: 129 Bytes
  • Size of remote file: 2.35 kB
res/Texture/ref.png ADDED

Git LFS Details

  • SHA256: 49bcc48c0b47f6f49430ed90afa57aecda6ff4515814869896b8b739ff74a32d
  • Pointer size: 130 Bytes
  • Size of remote file: 19.2 kB
res/Texture/refresh.png ADDED

Git LFS Details

  • SHA256: 2bcb26526357b1bf760d5be92fc570baa7b82bb8f9bc7633ce48c1f71a24e3ac
  • Pointer size: 130 Bytes
  • Size of remote file: 22.3 kB
res/Texture/result.png ADDED

Git LFS Details

  • SHA256: 6d09493aa0b1741dc99aef199d2b04118d5bd04493db85d18459ff348642921c
  • Pointer size: 127 Bytes
  • Size of remote file: 91 Bytes
res/Texture/right-arrow.png ADDED

Git LFS Details

  • SHA256: a3a552a0383739350721328aba81e314f12a6b6abfa148908063281171bfb8ef
  • Pointer size: 129 Bytes
  • Size of remote file: 2.07 kB
res/Texture/right.png ADDED

Git LFS Details

  • SHA256: e682e50174428be69453ab5533cc04ad2b41e0fc3c166bab1de97964e40f7ada
  • Pointer size: 130 Bytes
  • Size of remote file: 16.5 kB
res/Texture/ring.png ADDED

Git LFS Details

  • SHA256: 789a4a9f372e48f03631a45ceca726ea6046ffa80061fc960ede359dc9e31a11
  • Pointer size: 130 Bytes
  • Size of remote file: 38 kB
res/Texture/s.png ADDED

Git LFS Details

  • SHA256: 00dc07a6cb2711bb24851068239c9d8cd01f51e90fc097660699a00e65b303da
  • Pointer size: 131 Bytes
  • Size of remote file: 545 kB
res/Texture/sketch.png ADDED

Git LFS Details

  • SHA256: 6d09493aa0b1741dc99aef199d2b04118d5bd04493db85d18459ff348642921c
  • Pointer size: 127 Bytes
  • Size of remote file: 91 Bytes
res/Texture/skilled.png ADDED

Git LFS Details

  • SHA256: b33c9d493fd188c20864c96d8e88af3161e95620c1c5078aa9da32454173840d
  • Pointer size: 130 Bytes
  • Size of remote file: 17.8 kB