Skip to content

Commit 74630f9

Browse files
update app
1 parent 54ab164 commit 74630f9

File tree

8 files changed

+223
-56
lines changed

8 files changed

+223
-56
lines changed

NN/utils.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,23 @@
22
import tensorflow_addons as tfa
33
import tensorflow_probability as tfp
44
import tensorflow.keras.layers as L
5+
import tensorflow as tf
6+
import tensorflow_probability as tfp
7+
8+
def gaussian_kernel(size, stdsPx):
9+
stds = tf.cast(stdsPx, tf.float32) / size
10+
B = tf.shape(stds)[0]
11+
stds = tf.reshape(stds, [B, 1])
12+
x = tf.linspace(-size // 2 + 1, size // 2 + 1, size)
13+
x = tf.cast(x ** 2, tf.float32)
14+
x = tf.tile(x[None], [B, 1])
15+
x = tf.nn.softmax(-x / (2.0 * (stds**2)))
16+
x = tf.matmul(x[:, :, None], x[:, None, :])
17+
gauss = tf.reshape(x, [B, size, size, 1])
18+
gauss = tf.repeat(gauss, 3, axis=-1)
19+
gauss = tf.repeat(gauss, 3, axis=0)
20+
gauss = tf.transpose(gauss, [1, 2, 3, 0]) # [B, size, size, 1] => [size, size, 1, B]
21+
return gauss
522

623
def masked(x, mask):
724
'''
@@ -139,4 +156,21 @@ def is_namedtuple(obj) -> bool:
139156
isinstance(obj, tuple) and
140157
hasattr(obj, '_asdict') and
141158
hasattr(obj, '_fields')
142-
)
159+
)
160+
161+
if '__main__' == __name__:
162+
print('Utils test')
163+
print('All tests passed successfully!')
164+
import cv2
165+
import tensorflow_addons as tfa
166+
167+
img = cv2.imread('d:\photo_2024-03-26_15-48-33.jpg')
168+
img = img.astype('float32') / 255.0
169+
gaussians = gaussian_kernel(48, tf.constant([10., 20., 30.]))
170+
imgG = tf.nn.conv2d(img[None], gaussians, strides=[1, 1, 1, 1], padding='SAME')[0]
171+
172+
for i in [3, 6, 9]:
173+
g = imgG[..., i-3:i].numpy()
174+
g = (g * 255.0).astype('uint8')
175+
cv2.imshow('Gaussian %i' % i, g)
176+
cv2.waitKey(0)

huggingface/HF/NN/CARDirectionModelProxy.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ def __init__(self, model):
66
self._model = model
77
return
88

9+
@property
10+
def processor(self):
11+
return self._model.processor
12+
913
def __call__(self,
1014
threshold, start, end, steps, decay, noiseStddev, convergeThreshold,
1115
reverseArgs={},

huggingface/HF/NN/CInterpolantVisualization.py

Lines changed: 90 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from mpl_toolkits.mplot3d import Axes3D
88
from NN.restorators.samplers.CSamplerWatcher import CSamplerWatcher
99
from NN.utils import extractInterpolated, ensure4d
10+
import NN.utils as NNU
11+
from HF.Utils import toPILImage
1012

1113
from collections import namedtuple
1214
CCollectedSteps = namedtuple('CCollectedSteps', ['value', 'x0', 'x1', 'totalSteps', 'totalPoints'])
@@ -124,6 +126,10 @@ def __init__(self, model):
124126
self._model = model
125127
return
126128

129+
@property
130+
def processor(self):
131+
return self._model.processor
132+
127133
def _generateFilename(self, **kwargs):
128134
folder = os.path.abspath('tmp')
129135
os.makedirs(folder, exist_ok=True)
@@ -143,7 +149,7 @@ def _generateFilename(self, **kwargs):
143149
def _collectSteps(self, points, initialValues, kwargs):
144150
NSamples = len(points)
145151
watcher = CSamplerWatcher(
146-
steps=1000, # 1000 steps at most
152+
steps=100, # 100 steps at most
147153
tracked=dict(
148154
value=(NSamples, 3),
149155
x0=(NSamples, 3),
@@ -158,7 +164,7 @@ def _collectSteps(self, points, initialValues, kwargs):
158164
initialValues=initialValues,
159165
reverseArgs=dict(
160166
**reverseArgs,
161-
algorithmInterceptor=watcher,
167+
algorithmInterceptor=watcher
162168
),
163169
)
164170
N = watcher.iteration + 1
@@ -238,6 +244,33 @@ def _generateVideo(self, writer, originalColors, collectedSteps):
238244
plt.close(fig)
239245
return
240246

247+
def _generateProcessVideo(self, writer, resolution, collectedSteps, name):
248+
FIG_COLS = 1
249+
FIG_ROWS = 1
250+
fig = plt.figure(figsize=(FIG_COLS * 9, FIG_ROWS * 6))
251+
gs = fig.add_gridspec(FIG_ROWS, FIG_COLS)
252+
axs = [
253+
fig.add_subplot(gs[0, 0]), # image
254+
]
255+
try:
256+
processor = self.processor
257+
for step in range(collectedSteps.totalSteps):
258+
fig.suptitle(f'Step {step+1}/{collectedSteps.totalSteps}')
259+
# plot the image
260+
image = collectedSteps.value[step] if name == 'value' else collectedSteps.x0[step]
261+
image = image.reshape(resolution, resolution, 3)
262+
image = processor.range.convertBack(image)
263+
image = toPILImage(image, isBGR=False)
264+
axs[0].imshow(image)
265+
266+
fig.tight_layout()
267+
fig.show()
268+
writer.append_data(plot2image(fig))
269+
continue
270+
finally:
271+
plt.close(fig)
272+
return
273+
241274
def _extractOriginalColors(self, points, raw, **kwargs):
242275
assert raw.ndim == 3, 'Unexpected shape of raw'
243276
assert raw.shape[-1] == 3, 'Unexpected number of channels in raw'
@@ -260,18 +293,14 @@ def _initialValuesFor(self, initialValues, seed, N):
260293
return np.random.RandomState(seed).uniform(size=(1, N, 3)).astype(np.float32)
261294

262295
raise ValueError(f'Unexpected initialValues: {initialValues}')
263-
264-
def __call__(self,
265-
VT_numPoints=None, VT_fps=None, VT_useOriginalColors=None, VT_seed=-1,
266-
VT_initialValues=None,
296+
297+
def _trajectories(self,
298+
VT_numPoints, VT_fps, VT_seed, VT_initialValues,
299+
VT_useOriginalColors,
267300
**kwargs
268301
):
269-
if VT_numPoints is None: return self._model(**kwargs)
270302
VT_numPoints = int(VT_numPoints)
271-
VT_seed = None if VT_seed < 0 else int(VT_seed)
272-
VT_fps = int(VT_fps)
273303
VT_useOriginalColors = bool(VT_useOriginalColors)
274-
275304
videoFileName = self._generateFilename(
276305
VT_numPoints=VT_numPoints, VT_seed=VT_seed, VT_fps=VT_fps,
277306
VT_initialValues=VT_initialValues,
@@ -298,6 +327,57 @@ def __call__(self,
298327
)
299328
return { 'video': videoFileName, }
300329

330+
def _process(self,
331+
VT_fps, VT_seed, VT_initialValues, VT_resolution, VT_show,
332+
**kwargs
333+
):
334+
assert VT_show in ['value', 'x0'], f'Unexpected VT_show: {VT_show}'
335+
VT_resolution = int(VT_resolution)
336+
assert 64 <= VT_resolution <= 512, 'Unexpected resolution'
337+
videoFileName = self._generateFilename(
338+
VT_fps=VT_fps, VT_seed=VT_seed, VT_initialValues=VT_initialValues,
339+
VT_resolution=VT_resolution,
340+
**kwargs
341+
)
342+
343+
with imageio.get_writer(videoFileName, mode='I', fps=VT_fps) as writer:
344+
self._generateProcessVideo(
345+
writer=writer,
346+
resolution=VT_resolution,
347+
collectedSteps=self._collectSteps(
348+
points=NNU.generateSquareGrid(size=VT_resolution, scale=1.0, shift=0.0),
349+
initialValues=self._initialValuesFor(
350+
initialValues=VT_initialValues, seed=VT_seed, N=VT_resolution ** 2
351+
),
352+
kwargs=kwargs,
353+
),
354+
name=VT_show,
355+
)
356+
return { 'video': videoFileName, }
357+
358+
def __call__(self,
359+
VT_fps=None, VT_seed=-1,
360+
VT_kind=None,
361+
**kwargs
362+
):
363+
if VT_kind is None: return self._model(**kwargs)
364+
VT_seed = None if VT_seed < 0 else int(VT_seed)
365+
VT_fps = int(VT_fps)
366+
assert VT_kind in ['trajectories', 'process'], f'Unexpected VT_kind: {VT_kind}'
367+
368+
if VT_kind == 'trajectories':
369+
return self._trajectories(
370+
VT_fps=VT_fps, VT_seed=VT_seed,
371+
**kwargs
372+
)
373+
if VT_kind == 'process':
374+
return self._process(
375+
VT_fps=VT_fps, VT_seed=VT_seed,
376+
**kwargs
377+
)
378+
379+
raise ValueError(f'Unexpected VT_kind: {VT_kind}')
380+
301381
@property
302382
def kind(self): return self._model.kind
303383

huggingface/HF/NN/CWithAblations.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ def __init__(self, model):
55
self._model = model
66
return
77

8+
@property
9+
def processor(self):
10+
return self._model.processor
11+
812
def __call__(self, randomizePositions, encoderContext, encoderIntermediate, reverseArgs={}, **kwargs):
913
encoderContextMappping = {
1014
'Both': (False, False),

huggingface/HF/NN/CWithDDIM.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ def __init__(self, model):
55
self._model = model
66
return
77

8+
@property
9+
def processor(self):
10+
return self._model.processor
11+
812
def __call__(self,
913
DDIM_stochasticity, DDIM_K, DDIM_clipping, DDIM_projectNoise, DDIM_noiseStddev,
1014
reverseArgs={}, **kwargs

huggingface/HF/UI/areas/DDIMParametersArea.py

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,20 @@
11
import gradio as gr
22
from ..common import noiseProviderStddev
33

4-
def _presets(extraPresets, defaultPreset):
5-
# (stochasticity, K, clipping, projectNoise, noiseStddev)
6-
presets = {
7-
**extraPresets,
8-
'DDPM': (1.0, 1, False, False, 'normal'),
9-
'DDIM': (0.0, 1, False, False, 'normal'),
10-
}
11-
def onSelect(presetName):
12-
preset = presets.get(presetName, None)
13-
assert preset is not None, f'Unknown preset: {presetName}'
14-
return preset
15-
16-
names = list(presets.keys())
17-
defaultPreset = defaultPreset if defaultPreset in names else names[0]
18-
defaultPresetValues = presets[defaultPreset]
19-
return names, onSelect, {
20-
'name': defaultPreset,
21-
'stochasticity': defaultPresetValues[0],
22-
'K': defaultPresetValues[1],
23-
'clipping': defaultPresetValues[2],
24-
'projectNoise': defaultPresetValues[3],
25-
'noiseStddev': defaultPresetValues[4],
26-
}
27-
28-
def DDIMParametersArea(extraPresets={}, defaultPreset=None):
29-
presets, onSelectPreset, defaultPreset = _presets(extraPresets, defaultPreset=defaultPreset)
4+
def DDIMParametersArea():
305
with gr.Group():
31-
preset = gr.Dropdown(
32-
choices=presets, value=presets[0], label='Parameters preset',
33-
interactive=True, allow_custom_value=False
34-
)
356
# DDIM parameters
367
stochasticity = gr.Slider(
378
minimum=0.0, maximum=1.0, step=0.05, label='Stochasticity', interactive=True,
38-
value=defaultPreset['stochasticity']
9+
value=1.0
3910
)
4011
K = gr.Slider(
4112
minimum=1, maximum=30, step=1, label='K', interactive=True,
42-
value=defaultPreset['K']
43-
)
44-
clipping = gr.Checkbox(label='Clipping to [-1, 1]', interactive=True, value=defaultPreset['clipping'])
45-
projectNoise = gr.Checkbox(label='Use noise projection', interactive=True, value=defaultPreset['projectNoise'])
46-
noiseStddev = noiseProviderStddev(defaultPreset['noiseStddev'])
47-
48-
# bind preset to parameters
49-
preset.change(
50-
onSelectPreset,
51-
inputs=[preset],
52-
outputs=[stochasticity, K, clipping, projectNoise, noiseStddev],
13+
value=10
5314
)
15+
clipping = gr.Checkbox(label='Clipping to [-1, 1]', interactive=True, value=False)
16+
projectNoise = gr.Checkbox(label='Use noise projection', interactive=True, value=True)
17+
noiseStddev = noiseProviderStddev('normal')
5418

5519
return dict(
5620
DDIM_stochasticity=stochasticity,
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import gradio as gr
2+
3+
def trajectoriesArea(submit, parameters):
4+
with gr.Tab(label='Trajectories'):
5+
gr.Markdown('''
6+
# Trajectories
7+
Here you can visualize the trajectories of the particles.
8+
''')
9+
# number of points, button "Visualize", area for video
10+
numPoints = gr.Slider(
11+
label='Number of sampled points',
12+
value=10, minimum=1, maximum=200, step=1
13+
)
14+
useOriginalColors = gr.Checkbox(label='Show original colors', value=False)
15+
button = gr.Button(value='Visualize')
16+
video = gr.Video(label='Video', interactive=False)
17+
# Hidden kind parameter
18+
kind = gr.Textbox(label='Kind', value='trajectories', visible=False)
19+
# bind button
20+
submit(
21+
btn=button,
22+
VT_kind=kind,
23+
VT_numPoints=numPoints,
24+
VT_useOriginalColors=useOriginalColors,
25+
**parameters,
26+
outputs={'video': video}
27+
)
28+
29+
def imageArea(submit, parameters):
30+
with gr.Tab(label='Image Restoration Process'):
31+
gr.Markdown('''
32+
# Images
33+
Here you can visualize the image restoration process step by step.
34+
''')
35+
VT_resolution = gr.Slider(
36+
label='Resolution', value=64, minimum=8, maximum=512, step=1
37+
)
38+
# Radio buttons for the displayed values. 'value' or 'x0
39+
VT_show = gr.Radio(
40+
label='Show',
41+
choices=['value', 'x0'], value='value',
42+
)
43+
button = gr.Button(value='Visualize')
44+
video = gr.Video(label='Video', interactive=False)
45+
# Hidden kind parameter
46+
kind = gr.Textbox(label='Kind', value='process', visible=False)
47+
# bind button
48+
submit(
49+
btn=button,
50+
VT_kind=kind,
51+
VT_resolution=VT_resolution,
52+
VT_show=VT_show,
53+
**parameters,
54+
outputs={'video': video}
55+
)
56+
57+
def visualizeArea(submit):
58+
with gr.Accordion('Visualize Area', open=False):
59+
fps = gr.Slider(label='Frames per second', value=2, minimum=1, maximum=30, step=1)
60+
VT_seed = gr.Number(
61+
label='Seed (-1 for random)', value=-1,
62+
minimum=-1, maximum=1000000, step=1, interactive=True
63+
)
64+
VT_initialValues = gr.Radio(
65+
label='Initial values',
66+
choices=['Seeded', 'Zeros'], value='Seeded',
67+
)
68+
69+
parameters = dict(
70+
VT_fps=fps,
71+
VT_initialValues=VT_initialValues,
72+
VT_seed=VT_seed,
73+
)
74+
trajectoriesArea(submit, parameters)
75+
imageArea(submit, parameters)
76+
pass
77+
return

0 commit comments

Comments
 (0)