1. 程式人生 > 實用技巧 >關於雙線性插值中重疊畫素與空白畫素掩膜函式的一種迭代batch的寫法

關於雙線性插值中重疊畫素與空白畫素掩膜函式的一種迭代batch的寫法

  1 from __future__ import division
  2 import matplotlib.pyplot as plt
  3 import numpy as np
  4 import tensorflow as tf
  5 
  6 
  7 imgs = [[[[255, 0, 0], [0, 255, 0], [0, 0, 255]],
  8          [[255, 0, 0], [0, 255, 0], [0, 0, 255]],
  9          [[255, 0, 0], [0, 255, 0], [0, 0, 255]],
 10          [[255, 0, 0], [0, 255, 0], [0, 0, 255]]],
11 [[[255, 0, 0], [0, 255, 0], [0, 0, 255]], 12 [[255, 0, 0], [0, 255, 0], [0, 0, 255]], 13 [[255, 0, 0], [0, 255, 0], [0, 0, 255]], 14 [[255, 0, 0], [0, 255, 0], [0, 0, 255]]]] 15 imgs = tf.reshape(imgs, [2, 4, 3, 3]) 16 coords = [[[[0.2, 0.2], [1.3, 0.2], [1.8, 2.2]], 17 [[0.5, 2], [1.3, 2], [0.2, 1.6]],
18 [[0.2, 0.2], [1.3, 0.2], [1.8, 2.2]], 19 [[0.5, 2], [1.3, 2], [0.2, 1.6]]], 20 [[[0.2, 0.2], [1.3, 0.2], [1.8, 2.2]], 21 [[0.5, 2], [1.3, 2], [0.2, 1.6]], 22 [[0.2, 0.2], [1.3, 0.2], [1.8, 2.2]], 23 [[0.5, 2], [1.3, 2], [0.2, 1.6]]]] 24
coords = tf.reshape(coords, [2, 4, 3, 2]) 25 26 27 cam_coords = [[[[1, 2, 3, 1], [2, 3, 4, 1], [3, 4, 5, 1]], 28 [[4, 5, 6, 1], [7, 8, 9, 1], [10, 11, 12, 1]], 29 [[1, 0, 3, 1], [3, 3, 4, 1], [3, 5, 5, 1]], 30 [[4, 4, 6, 1], [7, 7, 9, 1], [10, 12, 12, 1]]], 31 [[[1, 2, 3, 1], [2, 3, 4, 1], [3, 4, 5, 1]], 32 [[4, 5, 6, 1], [7, 8, 9, 1], [10, 11, 12, 1]], 33 [[1, 0, 3, 1], [3, 3, 4, 1], [3, 5, 5, 1]], 34 [[4, 4, 6, 1], [7, 7, 9, 1], [10, 12, 12, 1]]]] 35 cam_coords = tf.reshape(cam_coords, [2, 4, 3, 4]) 36 37 38 def bilinear_sampler(imgs, coords, cam_coords): 39 def _repeat(x, n_repeats): # x = tf.cast(tf.range(4), 'float32') * 53248 n_repeats = 53248。 40 rep = tf.transpose( 41 tf.expand_dims(tf.ones(shape=tf.stack([ 42 n_repeats, 43 ])), 1), [1, 44 0]) # 最後得到[1,53248]大小的全一矩陣。tf.stack其作用類似於tf.concat,都是拼接兩個張量,而不同之處在於,tf.concat拼接的是兩個shape完全相同的張量,並且產生的張量的階數不會發生變化,而tf.stack則會在新的張量階上拼接,產生的張量的階數將會增加 45 rep = tf.cast(rep, 'float32') 46 x = tf.matmul(tf.reshape(x, (-1, 1)), 47 rep) # reshape為一列,得到[[ 0.][ 53248.][106496.][159744.]]*rep,最後得到shape=(4, 53248)的矩陣。 48 return tf.reshape(x, [-1]) # 最後又化為一列Tensor("Reshape_1:0", shape=(212992,), dtype=float32) 49 50 with tf.name_scope('image_sampling'): 51 coords_x, coords_y = tf.split(coords, [1, 1], axis=3) 52 inp_size = imgs.get_shape() 53 coord_size = coords.get_shape() 54 out_size = coords.get_shape().as_list() 55 out_size[3] = imgs.get_shape().as_list()[3] 56 57 coords_x = tf.cast(coords_x, 'float32') 58 coords_y = tf.cast(coords_y, 'float32') 59 60 x0 = tf.floor(coords_x) 61 x1 = x0 + 1 62 y0 = tf.floor(coords_y) 63 y1 = y0 + 1 64 65 y_max = tf.cast(tf.shape(imgs)[1] - 1, 'float32') 66 x_max = tf.cast(tf.shape(imgs)[2] - 1, 'float32') 67 zero = tf.zeros([1], dtype='float32') 68 69 x0_safe = tf.clip_by_value(x0, zero, x_max) 70 y0_safe = tf.clip_by_value(y0, zero, y_max) 71 x1_safe = tf.clip_by_value(x1, zero, x_max) 72 y1_safe = tf.clip_by_value(y1, zero, y_max) 73 74 ## bilinear interp weights, with points outside the grid having weight 0#判斷是否相等,相等為1,不相等為0. 75 # wt_x0 = (x1 - coords_x) * tf.cast(tf.equal(x0, x0_safe), 'float32') 76 # wt_x1 = (coords_x - x0) * tf.cast(tf.equal(x1, x1_safe), 'float32') 77 # wt_y0 = (y1 - coords_y) * tf.cast(tf.equal(y0, y0_safe), 'float32') 78 # wt_y1 = (coords_y - y0) * tf.cast(tf.equal(y1, y1_safe), 'float32') 79 80 wt_x0 = x1_safe - coords_x 81 wt_x1 = coords_x - x0_safe 82 wt_y0 = y1_safe - coords_y 83 wt_y1 = coords_y - y0_safe 84 85 ## indices in the flat image to sample from 86 dim2 = tf.cast(inp_size[2], 'float32') 87 dim1 = tf.cast(inp_size[2] * inp_size[1], 'float32') 88 base = tf.reshape( 89 _repeat( 90 tf.cast(tf.range(coord_size[0]), 'float32') * dim1, 91 coord_size[1] * coord_size[2]), 92 [out_size[0], out_size[1], out_size[2], 93 1]) # tf.reshape(_repeat(tf.cast(tf.range(4), 'float32') * 128 * 416, 128 * 416), [4, 128, 416, 1]) 94 # 上面最後得base=Tensor("Reshape_2:0", shape=(4, 128, 416, 1), dtype=float32)。中間有[ 0.][ 53248.][106496.][159744.]四種數。 95 base_y0 = base + y0_safe * dim2 96 base_y1 = base + y1_safe * dim2 # 考慮進有4個batch,所以不同batch要加上不同的基數。 97 idx00 = tf.reshape(x0_safe + base_y0, [-1]) # 加上基數之後構成了四個畫素值的索引。 98 idx01 = x0_safe + base_y1 99 idx10 = x1_safe + base_y0 100 idx11 = x1_safe + base_y1 101 102 ## sample from imgs 103 imgs_flat = tf.reshape(imgs, tf.stack([-1, inp_size[3]])) 104 imgs_flat = tf.cast(imgs_flat, 'float32') 105 im00 = tf.reshape(tf.gather(imgs_flat, tf.cast(idx00, 'int32')), out_size) # 每一個輸出都有對應的四個畫素點的值參與運算。 106 im01 = tf.reshape(tf.gather(imgs_flat, tf.cast(idx01, 'int32')), out_size) 107 im10 = tf.reshape(tf.gather(imgs_flat, tf.cast(idx10, 'int32')), out_size) 108 im11 = tf.reshape(tf.gather(imgs_flat, tf.cast(idx11, 'int32')), out_size) 109 110 w00 = wt_x0 * wt_y0 ######這裡橫軸和縱軸的距離乘機就算距離了。 111 w01 = wt_x0 * wt_y1 112 w10 = wt_x1 * wt_y0 113 w11 = wt_x1 * wt_y1 114 115 output = tf.add_n([ 116 w00 * im00, w01 * im01, 117 w10 * im10, w11 * im11 118 ]) 119 120 # 以下為自定義程式碼 121 batch, height, width, channels = imgs.get_shape().as_list() 122 cam_coords = cam_coords[:, :, :, 0:-1] 123 cam_coords = tf.cast(cam_coords, 'float32') 124 euclidean = tf.sqrt(tf.reduce_sum(tf.square(cam_coords), 3)) 125 euclidean = tf.reshape(euclidean, [2, -1]) 126 127 xy00 = tf.concat([x0, y0], axis=3) 128 for i in range(batch): 129 cam_coordsi = cam_coords[i, :, :, :] 130 euclideani = euclidean[i, :] 131 euclideani = tf.reshape(euclideani, [-1, 1]) 132 xy00_batchi = xy00[i, :, :, :] # 將橫縱座標合在一起,取batch1. 133 xy00_batchi = tf.reshape(xy00_batchi, [-1, 2]) 134 xy00_batchi = tf.cast(xy00_batchi, tf.int32) 135 xy10_batchi = xy00_batchi + [1, 0] 136 xy01_batchi = xy00_batchi + [0, 1] 137 xy11_batchi = xy00_batchi + [1, 1] 138 139 mask0 = tf.ones(shape=[height * width], dtype='float32') 140 141 def true_1(): 142 h = tf.cond(pred=tf.less(euclideani[h2, 0], euclideani[h1, 0]), true_fn=lambda: h1, false_fn=lambda: h2) 143 one_hot_true = tf.one_hot(indices=h, depth=12, axis=0) 144 return one_hot_true 145 146 def false_1(): 147 one_hot_false = tf.zeros([tf.shape(mask0)[0]]) 148 return one_hot_false 149 150 for h1 in range(xy00_batchi.get_shape().as_list()[0] - 1): 151 for h2 in range(h1 + 1, xy00_batchi.get_shape().as_list()[0]): 152 one_hot = tf.cond(pred=tf.reduce_all(tf.equal(xy00_batchi[h1, :], xy00_batchi[h2, :])), true_fn=true_1, 153 false_fn=false_1) 154 mask0 = mask0 - one_hot 155 mask0 = tf.clip_by_value(mask0, 0, 1) 156 mask0 = tf.reshape(mask0, [height, width]) 157 mask1 = np.zeros(shape=[height, width], dtype='float32') 158 for l1 in range(xy00_batchi.get_shape().as_list()[0]): 159 q001 = xy00_batchi[l1, 0] 160 q002 = xy00_batchi[l1, 1] 161 q101 = xy10_batchi[l1, 0] 162 q102 = xy10_batchi[l1, 1] 163 q011 = xy01_batchi[l1, 0] 164 q012 = xy01_batchi[l1, 1] 165 q111 = xy11_batchi[l1, 0] 166 q112 = xy11_batchi[l1, 1] 167 var001 = tf.one_hot(indices=q002, depth=width, on_value=q001, off_value=height, axis=-1) 168 var002 = tf.one_hot(indices=var001, depth=height, axis=0) 169 var101 = tf.one_hot(indices=q102, depth=width, on_value=q101, off_value=height, axis=-1) 170 var102 = tf.one_hot(indices=var101, depth=height, axis=0) 171 var011 = tf.one_hot(indices=q012, depth=width, on_value=q011, off_value=height, axis=-1) 172 var012 = tf.one_hot(indices=var011, depth=height, axis=0) 173 var111 = tf.one_hot(indices=q112, depth=width, on_value=q111, off_value=height, axis=-1) 174 var112 = tf.one_hot(indices=var111, depth=height, axis=0) 175 mask1 = mask1 + var002 + var102 + var012 + var112 176 mask1 = tf.clip_by_value(mask1, 0, 1) 177 if i == 0: 178 mask0_stack = mask0 179 mask1_stack = mask1 180 else: 181 mask0_stack = tf.stack([mask0_stack, mask0], axis=0) 182 mask1_stack = tf.stack([mask1_stack, mask1], axis=0) 183 return output, mask0_stack, mask1_stack 184 185 186 output_img, mask0_stack, mask1_stack = bilinear_sampler(imgs, coords, cam_coords) 187 with tf.Session() as sess: 188 # print(output_img) 189 # print(sess.run(output)) 190 print(sess.run(output_img)) 191 print(sess.run(mask0_stack)) 192 print(sess.run(mask1_stack)) 193 print(mask0_stack) 194 print(mask1_stack)