使用TensorFlow对图像中的点进行插值采样

Cli*_*nna 9 python tensorflow

给出灰度图像I作为2D张量(维度W,H)和坐标C的张量(Dim.None,2).我想解释的行Ç作为坐标,样品在使用某种类型的插值(双线性很可能是罚款,我的使用情况),并将得到的值存储在一个新的张量的坐标P(尺寸无的,即,具有与C一样多的条目的1维具有行).

这是否可以(有效)使用TensorFlow?我能找到的只是用于调整图像大小(等距重新采样,如果你喜欢)的函数.但我无法在坐标列表中找到任何开箱即用的样本.

即我希望找到类似tf.interpolate()函数的东西:

I = tf.placeholder("float", shape=[128, 128])
C = tf.placeholder("float", shape=[None, 2])
P = tf.interpolate(I, C, axis=[0, 1], method="linear")
Run Code Online (Sandbox Code Playgroud)

理想情况下,我会寻找一种解决方案,允许我使用带有形状的C(无,M)在M维上插入N维张量I,并产生N-M + 1维输出,如"轴"所示"上面代码中的参数.

(我的应用程序中的"图像"不是图片顺便说一下,它是来自物理模型的采样数据(当用作占位符时)或替代学习模型(当用作变量时).此时此物理模型具有2度自由,因此在"图像"中插值现在已足够,但我可能会在未来研究更高维度的模型.)

如果使用现有的TensorFlow功能无法做到这一点:当我想实现像这样的tf.interpolate()运算符时,我应该从哪里开始?(文档和/或简单示例代码)

mrr*_*rry 10

没有内置的op执行这种插值,但你应该能够使用现有TensorFlow操作的组合来完成它.我建议双线性案例采用以下策略:

  1. 根据C索引的张量,计算与四个角点对应的整数张量.例如(名称假设原点位于左上角):

    top_left = tf.cast(tf.floor(C), tf.int32)
    
    top_right = tf.cast(
        tf.concat(1, [tf.floor(C[:, 0:1]), tf.ceil(C[:, 1:2])]), tf.int32)
    
    bottom_left = tf.cast(
        tf.concat(1, [tf.ceil(C[:, 0:1]), tf.floor(C[:, 1:2])]), tf.int32)
    
    bottom_right = tf.cast(tf.ceil(C), tf.int32)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 从表示特定角点的每个张量中,从I这些点提取值的矢量.例如,对于以下函数,对于2-D情况执行此操作:

    def get_values_at_coordinates(input, coordinates):
      input_as_vector = tf.reshape(input, [-1])
      coordinates_as_indices = (coordinates[:, 0] * tf.shape(input)[1]) + coordinates[:, 1]
      return tf.gather(input_as_vector, coordinates_as_indices)
    
    values_at_top_left = get_values_at_coordinates(I, top_left)
    values_at_top_right = get_values_at_coordinates(I, top_right)
    values_at_bottom_left = get_values_at_coordinates(I, bottom_left)
    values_at_bottom_right = get_values_at_coordinates(I, bottom_right)
    
    Run Code Online (Sandbox Code Playgroud)
  3. 首先计算水平方向的插值:

    # Varies between 0.0 and 1.0.
    horizontal_offset = C[:, 0] - tf.cast(top_left[:, 0], tf.float32)
    
    horizontal_interpolated_top = (
        ((1.0 - horizontal_offset) * values_at_top_left)
        + (horizontal_offset * values_at_top_right))
    
    horizontal_interpolated_bottom = (
        ((1.0 - horizontal_offset) * values_at_bottom_left)
        + (horizontal_offset * values_at_bottom_right))
    
    Run Code Online (Sandbox Code Playgroud)
  4. 现在计算垂直方向的插值:

    vertical_offset = C[:, 1] - tf.cast(top_left[:, 1], tf.float32)
    
    interpolated_result = (
        ((1.0 - vertical_offset) * horizontal_interpolated_top)
        + (vertical_offset * horizontal_interpolated_bottom))
    
    Run Code Online (Sandbox Code Playgroud)