Update app.py
Browse files
app.py
CHANGED
|
@@ -58,20 +58,95 @@ def write_flo(flow, filename):
|
|
| 58 |
flow.tofile(f)
|
| 59 |
f.close()
|
| 60 |
|
| 61 |
-
def
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
|
| 76 |
def infer():
|
| 77 |
video_url = "https://download.pytorch.org/tutorial/pexelscom_pavel_danilyuk_basketball_hd.mp4"
|
|
@@ -166,9 +241,19 @@ def infer():
|
|
| 166 |
# output_folder = "/tmp/" # Update this to the folder of your choice
|
| 167 |
write_jpeg(flow_img, f"predicted_flow.jpg")
|
| 168 |
flo_file = write_flo(predicted_flow, "flofile.flo")
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
return "done", "predicted_flow.jpg", ["flofile.flo"]
|
| 173 |
####################################
|
| 174 |
# Bonus: Creating GIFs of predicted flows
|
|
|
|
| 58 |
flow.tofile(f)
|
| 59 |
f.close()
|
| 60 |
|
| 61 |
+
def get_pixel_value(img, x, y):
|
| 62 |
+
"""
|
| 63 |
+
Utility function to get pixel value for coordinate
|
| 64 |
+
vectors x and y from a 4D tensor image.
|
| 65 |
+
Input
|
| 66 |
+
-----
|
| 67 |
+
- img: tensor of shape (B, H, W, C)
|
| 68 |
+
- x: flattened tensor of shape (B*H*W, )
|
| 69 |
+
- y: flattened tensor of shape (B*H*W, )
|
| 70 |
+
Returns
|
| 71 |
+
-------
|
| 72 |
+
- output: tensor of shape (B, H, W, C)
|
| 73 |
+
"""
|
| 74 |
+
shape = tf.shape(x)
|
| 75 |
+
batch_size = shape[0]
|
| 76 |
+
height = shape[1]
|
| 77 |
+
width = shape[2]
|
| 78 |
+
|
| 79 |
+
batch_idx = tf.range(0, batch_size)
|
| 80 |
+
batch_idx = tf.reshape(batch_idx, (batch_size, 1, 1))
|
| 81 |
+
b = tf.tile(batch_idx, (1, height, width))
|
| 82 |
+
|
| 83 |
+
indices = tf.stack([b, y, x], 3)
|
| 84 |
+
|
| 85 |
+
return tf.gather_nd(img, indices)
|
| 86 |
+
|
| 87 |
+
def tf_warp(img, flow, H, W):
|
| 88 |
+
# H = 256
|
| 89 |
+
# W = 256
|
| 90 |
+
x,y = tf.meshgrid(tf.range(W), tf.range(H))
|
| 91 |
+
x = tf.expand_dims(x,0)
|
| 92 |
+
x = tf.expand_dims(x,0)
|
| 93 |
+
|
| 94 |
+
y =tf.expand_dims(y,0)
|
| 95 |
+
y = tf.expand_dims(y,0)
|
| 96 |
+
|
| 97 |
+
x = tf.cast(x, tf.float32)
|
| 98 |
+
y = tf.cast(y, tf.float32)
|
| 99 |
+
grid = tf.concat([x,y],axis = 1)
|
| 100 |
+
# print grid.shape
|
| 101 |
+
flows = grid+flow
|
| 102 |
+
print(flows.shape)
|
| 103 |
+
max_y = tf.cast(H - 1, tf.int32)
|
| 104 |
+
max_x = tf.cast(W - 1, tf.int32)
|
| 105 |
+
zero = tf.zeros([], dtype=tf.int32)
|
| 106 |
+
|
| 107 |
+
x = flows[:,0,:,:]
|
| 108 |
+
y = flows[:,1,:,:]
|
| 109 |
+
x0 = x
|
| 110 |
+
y0 = y
|
| 111 |
+
x0 = tf.cast(x0, tf.int32)
|
| 112 |
+
x1 = x0 + 1
|
| 113 |
+
y0 = tf.cast(y0, tf.int32)
|
| 114 |
+
y1 = y0 + 1
|
| 115 |
+
|
| 116 |
+
# clip to range [0, H/W] to not violate img boundaries
|
| 117 |
+
x0 = tf.clip_by_value(x0, zero, max_x)
|
| 118 |
+
x1 = tf.clip_by_value(x1, zero, max_x)
|
| 119 |
+
y0 = tf.clip_by_value(y0, zero, max_y)
|
| 120 |
+
y1 = tf.clip_by_value(y1, zero, max_y)
|
| 121 |
+
|
| 122 |
+
# get pixel value at corner coords
|
| 123 |
+
Ia = get_pixel_value(img, x0, y0)
|
| 124 |
+
Ib = get_pixel_value(img, x0, y1)
|
| 125 |
+
Ic = get_pixel_value(img, x1, y0)
|
| 126 |
+
Id = get_pixel_value(img, x1, y1)
|
| 127 |
+
|
| 128 |
+
# recast as float for delta calculation
|
| 129 |
+
x0 = tf.cast(x0, tf.float32)
|
| 130 |
+
x1 = tf.cast(x1, tf.float32)
|
| 131 |
+
y0 = tf.cast(y0, tf.float32)
|
| 132 |
+
y1 = tf.cast(y1, tf.float32)
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
# calculate deltas
|
| 136 |
+
wa = (x1-x) * (y1-y)
|
| 137 |
+
wb = (x1-x) * (y-y0)
|
| 138 |
+
wc = (x-x0) * (y1-y)
|
| 139 |
+
wd = (x-x0) * (y-y0)
|
| 140 |
+
|
| 141 |
+
# add dimension for addition
|
| 142 |
+
wa = tf.expand_dims(wa, axis=3)
|
| 143 |
+
wb = tf.expand_dims(wb, axis=3)
|
| 144 |
+
wc = tf.expand_dims(wc, axis=3)
|
| 145 |
+
wd = tf.expand_dims(wd, axis=3)
|
| 146 |
+
|
| 147 |
+
# compute output
|
| 148 |
+
out = tf.add_n([wa*Ia, wb*Ib, wc*Ic, wd*Id])
|
| 149 |
+
return out
|
| 150 |
|
| 151 |
def infer():
|
| 152 |
video_url = "https://download.pytorch.org/tutorial/pexelscom_pavel_danilyuk_basketball_hd.mp4"
|
|
|
|
| 241 |
# output_folder = "/tmp/" # Update this to the folder of your choice
|
| 242 |
write_jpeg(flow_img, f"predicted_flow.jpg")
|
| 243 |
flo_file = write_flo(predicted_flow, "flofile.flo")
|
| 244 |
+
|
| 245 |
+
with tf.Session() as sess:
|
| 246 |
+
a = tf.placeholder(tf.float32, shape = [None,None,None,3])
|
| 247 |
+
flow_vec = tf.placeholder(tf.float32, shape = [None, 2, None, None])
|
| 248 |
+
init = tf.global_variables_initializer()
|
| 249 |
+
sess.run(init)
|
| 250 |
+
|
| 251 |
+
output = tf_warp(a, predicted_flow, 520, 960)
|
| 252 |
+
out = sess.run(output, feed_dict = {a:img, flow_vec:flow})
|
| 253 |
+
out = np.clip(out,0,255).astype('uint8')
|
| 254 |
+
# print out.shape
|
| 255 |
+
im = Image.fromarray(out[0].astype('uint8'))
|
| 256 |
+
im.save('output.jpg')
|
| 257 |
return "done", "predicted_flow.jpg", ["flofile.flo"]
|
| 258 |
####################################
|
| 259 |
# Bonus: Creating GIFs of predicted flows
|