Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用TensorFlow对图像中的点进行插值采样_Python_Tensorflow - Fatal编程技术网

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

Python 用TensorFlow对图像中的点进行插值采样,python,tensorflow,Python,Tensorflow,给出了一个灰度图像I,作为二维张量(维W,H)和坐标张量C(Dim.None,2)。我想将C的行解释为I中的坐标,使用某种插值在这些坐标处采样I(双线性可能适合我的用例),并将结果值存储在新的张量P(无维度的,即1维,条目数与C的行数相同) 使用TensorFlow可以(有效地)实现这一点吗?我所能找到的只是用于调整图像大小(如果您愿意,可以进行等距重采样)的函数。但我无法在坐标列表中找到任何现成的东西进行采样 也就是说,我希望找到类似于tf.interpolate()函数的东西: I = tf

给出了一个灰度图像I,作为二维张量(维W,H)和坐标张量C(Dim.None,2)。我想将C的行解释为I中的坐标,使用某种插值在这些坐标处采样I(双线性可能适合我的用例),并将结果值存储在新的张量P(无维度的,即1维,条目数与C的行数相同)

使用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")
理想情况下,我将寻找一种解决方案,该解决方案允许我使用带有形状(无,M)的C沿M维插值N维张量I,并产生nm+1维输出,如上面代码中的“axis”参数所示

(顺便说一句,我的应用程序中的“图像”不是图片,它是来自物理模型(用作占位符)或替代学习模型(用作变量)的采样数据。目前,该物理模型有2个自由度,因此在“图像”中插值现在已经足够了,但我将来可能会研究更高维度的模型。)


如果现有的TensorFlow功能无法实现类似的功能:当我想要实现类似于tf.interpolate()操作符的功能时,应该从哪里开始?(文档和/或简单的示例代码)

没有执行这种插值的内置运算,但您应该能够使用现有TensorFlow运算的组合来完成。对于双线性情况,我建议采用以下策略:

  • 从索引的张量
    C
    ,计算对应于四个角点的整数张量。例如(名称假设原点位于左上角):

  • 从表示特定角点的每个张量中,从这些点的
    I
    中提取一个值向量。例如,对于以下函数,在二维情况下执行此操作:

    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)
    
  • 首先计算水平方向上的插值:

    # 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))
    
  • 现在计算垂直方向上的插值:

    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))
    

  • 考虑到TF还没有Numpy切片的通用性(),而且
    gather
    只在第一维度上工作,这对于最近邻来说是很棘手的。但是这里有一种方法可以通过使用gather->transpose->gather->extract diagonal来解决这个问题

    def identity_matrix(n):
      """Returns nxn identity matrix."""
      # note, if n is a constant node, this assert node won't be executed,
      # this error will be caught during shape analysis 
      assert_op = tf.Assert(tf.greater(n, 0), ["Matrix size must be positive"])
      with tf.control_dependencies([assert_op]):
        ones = tf.fill(n, 1)
        diag = tf.diag(ones)
      return diag
    
    def extract_diagonal(tensor):
      """Extract diagonal of a square matrix."""
    
      shape = tf.shape(tensor)
      n = shape[0]
      assert_op = tf.Assert(tf.equal(shape[0], shape[1]), ["Can't get diagonal of "
                                                           "a non-square matrix"])
    
      with tf.control_dependencies([assert_op]):
        return tf.reduce_sum(tf.mul(tensor, identity_matrix(n)), [0])
    
    
    # create sample matrix
    size=4
    I0=np.zeros((size,size), dtype=np.int32)
    for i in range(size):
      for j in range(size):
        I0[i, j] = 10*i+j
    
    I = tf.placeholder(dtype=np.int32, shape=(size,size))
    C = tf.placeholder(np.int32, shape=[None, 2])
    C0 = np.array([[0, 1], [1, 2], [2, 3]])
    row_indices = C[:, 0]
    col_indices = C[:, 1]
    
    # since gather only supports dim0, have to transpose
    I1 = tf.gather(I, row_indices)
    I2 = tf.gather(tf.transpose(I1), col_indices)
    I3 = extract_diagonal(tf.transpose(I2))
    
    sess = create_session()
    print sess.run([I3], feed_dict={I:I0, C:C0})
    
    从这样的矩阵开始:

    array([[ 0,  1,  2,  3],
           [10, 11, 12, 13],
           [20, 21, 22, 23],
           [30, 31, 32, 33]], dtype=int32)
    
    此代码提取主节点上方的对角线

    [array([ 1, 12, 23], dtype=int32)]
    
    []操作符变成了
    挤压
    切片


    有一种使用tf.gather进行最近邻插值的有效方法…不确定线性插值是否存在
    tf.image.resize_双线性
    。这不是你想要的吗?@Albert不。如果我想在网格上的所有点上采样源图像,这只能满足我的要求。但是C行可以是s中的任何坐标源图像。这可以应用于批处理的rgb图像吗?我尝试更改
    get_values\u at_coordinates()
    将图像重塑为
    input_as_vector=tf。重塑(input,[-1,3])
    (C=3),但不起作用!答案中的代码专门用于单个灰度图像(如问题中所示),但您可以使用
    tf.map\u fn()
    将其应用于一批图像。在应用
    tf.map\u fn()之前,RGB图像会发生任何变化吗
    ?仍然无法使其工作。如果可以独立插值每个通道,您可以执行类似于
    images\u red、images\u green、images\u blue=tf.unstack(images,axis=3)
    的操作以获得单独的通道,然后使用
    tf.map\u fn()
    插值每个通道,并
    tf.stack([interpolated_red,interpolated_green,interpolated_blue])
    重新组合图像。如果这不起作用,请随时提出新问题,具体说明您尝试的代码和看到的错误!
    [array([ 1, 12, 23], dtype=int32)]