def ripple(tensor, shape, freq, displacement=1.0, kink=1.0, reference=None, spline_order=3):
"""
Apply displacement from pixel radian values.
:param Tensor tensor: An image tensor.
:param list[int] shape:
:param list[int] freq: Displacement frequency
:param float displacement:
:param float kink:
:param Tensor reference: An optional displacement map.
:param int spline_order: Ortho offset spline point count. 0=Constant, 1=Linear, 2=Cosine, 3=Bicubic
:return: Tensor
"""
height, width, channels = shape
x0_index = row_index(shape)
y0_index = column_index(shape)
value_shape = [shape[0], shape[1], 1]
if reference is None:
reference = resample(tf.random_uniform([freq[0], freq[1], 1]), value_shape, spline_order=spline_order)
# reference = derivative(reference, [shape[0], shape[1], 1], with_normalize=False)
# Twist index, borrowed from worms. TODO merge me.
index = value_map(reference, shape) * 360.0 * math.radians(1) * kink
reference_x = (tf.cos(index) * displacement * width) % width
reference_y = (tf.sin(index) * displacement * height) % height
# Bilinear interpolation of midpoints, borrowed from refract(). TODO merge me
x0_offsets = (tf.cast(reference_x, tf.int32) + x0_index) % width
x1_offsets = (x0_offsets + 1) % width
y0_offsets = (tf.cast(reference_y, tf.int32) + y0_index) % height
y1_offsets = (y0_offsets + 1) % height
x0_y0 = tf.gather_nd(tensor, tf.stack([y0_offsets, x0_offsets], 2))
x1_y0 = tf.gather_nd(tensor, tf.stack([y0_offsets, x1_offsets], 2))
x0_y1 = tf.gather_nd(tensor, tf.stack([y1_offsets, x0_offsets], 2))
x1_y1 = tf.gather_nd(tensor, tf.stack([y1_offsets, x1_offsets], 2))
x_fract = tf.reshape(reference_x - tf.floor(reference_x), [height, width, 1])
y_fract = tf.reshape(reference_y - tf.floor(reference_y), [height, width, 1])
x_y0 = blend(x0_y0, x1_y0, x_fract)
x_y1 = blend(x0_y1, x1_y1, x_fract)
return blend(x_y0, x_y1, y_fract)
评论列表
文章目录