【问题标题】:Dynamic image cropping in TensorflowTensorFlow 中的动态图像裁剪
【发布时间】:2017-05-25 10:07:02
【问题描述】:

我试图弄清楚如何截取在 Tensorflow 中动态确定的图像。下面是我想要完成的一个例子,但是我似乎无法让它工作。本质上,我想在图中提供图像和该图像的裁剪值,然后继续对这些裁剪的部分进行其他计算。我目前的尝试:

import tensorflow as tf
from matplotlib import pyplot as plt
import numpy as np

sess = tf.InteractiveSession()

img1 = np.random.random([400, 600, 3])
img2 = np.random.random([400, 600, 3])
img3 = np.random.random([400, 600, 3])

images = [img1, img2, img3]

img1_crop = [100, 100, 100, 100]
img2_crop = [200, 150, 100, 100]
img3_crop = [150, 200, 100, 100]

crop_values = [img1_crop, img2_crop, img3_crop]

def crop_image(img, crop):
    tf.image.crop_to_bounding_box(img,
                                  crop[0],
                                  crop[1],
                                  crop[2],
                                  crop[3])


image_placeholder = tf.placeholder("float", [None, 400, 600, 3])
crop_placeholder = tf.placeholder(dtype=tf.int32)
sess.run(tf.global_variables_initializer())

cropped_image = tf.map_fn(lambda img, crop: crop_image(img, crop), elems=[image_placeholder, crop_placeholder])
result = sess.run(cropped_image, feed_dict={image_placeholder: images, crop_placeholder:crop_values})

plt.imshow(result)
plt.show()
/Users/p111/anaconda/bin/python /Users/p111/PycharmProjects/analysis_code/testing.py 回溯(最近一次通话最后): 文件“/Users/p111/PycharmProjects/analysis_code/testing.py”,第 31 行,在 cropped_image = tf.map_fn(lambda img,crop:crop_image(img,crop), elems=[image_placeholder,crop_placeholder]) map_fn 中的文件“/Users/p111/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/functional_ops.py”,第 390 行 交换内存=交换内存) 文件“/Users/p111/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/control_flow_ops.py”,第 2636 行,在 while_loop 结果 = context.BuildLoop(cond, body, loop_vars, shape_invariants) BuildLoop 中的文件“/Users/p111/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/control_flow_ops.py”,第 2469 行 pred, body, original_loop_vars, loop_vars, shape_invariants) _BuildLoop 中的文件“/Users/p111/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/control_flow_ops.py”,第 2419 行 body_result = body(*packed_vars_for_body) 文件“/Users/p111/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/functional_ops.py”,第 380 行,在计算中 packed_fn_values = fn(packed_values) TypeError:()缺少1个必需的位置参数:'crop'

编辑:elems 似乎只接受一个张量。这意味着我需要以某种方式将我的两个张量合并为一个,然后在我的函数中解包以获取值。我不确定我将如何执行这种张量操作。我已经找到了 glimpse 方法并且确实有效,但是我想知道是否可以使用这种特定方法来完成相同的操作。大多数情况下,我想知道您将如何组合然后拆分一对张量,以便可以在此方法中使用它。

【问题讨论】:

  • 您当前的尝试出了什么问题?如果有回溯,请完整发布!
  • 对此感到抱歉。添加了堆栈跟踪。我只是假设,因为它似乎是一个如此简单的问题,所以问题很明显。我不完全确定我会以最好的方式解决这个问题。

标签: image python-3.x tensorflow


【解决方案1】:

我从here看到了这段代码。

elems = (np.array([1, 2, 3]), np.array([-1, 1, -1]))
alternate = map_fn(lambda x: x[0] * x[1], elems, dtype=tf.int64)
# alternate == [-1, 2, -3]

可以使用元组或列表将多个元素打包成一个,所以我尝试了这个。

import tensorflow as tf
from matplotlib import pyplot as plt
import numpy as np

sess = tf.InteractiveSession()

img1 = np.random.random([400, 600, 3])
img2 = np.random.random([400, 600, 3])
img3 = np.random.random([400, 600, 3])
images = np.array([img1, img2, img3])
# images = tf.convert_to_tensor(images)  # it can be uncommented.

img1_crop = [100, 100, 100, 100]
img2_crop = [200, 150, 100, 100]
img3_crop = [150, 200, 100, 100]
crop_values = np.array([img1_crop, img2_crop, img3_crop])
# crop_values = tf.convert_to_tensor(crop_values)  # it can be uncommented.

def crop_image(img, crop):
    return tf.image.crop_to_bounding_box(img,
                                         crop[0],
                                         crop[1],
                                         crop[2],
                                         crop[3])

fn = lambda x: crop_image(x[0], x[1])
elems = (images, crop_values)

cropped_image = tf.map_fn(fn, elems=elems, dtype=tf.float64)
result = sess.run(cropped_image)

print result.shape

plt.imshow(result[0])
plt.show()

它可以在我的机器上使用 tf 版本 0.11 和 python2。希望对您有所帮助。

【讨论】:

  • 我不知道为什么我无法自己解决这个问题。你让它看起来很简单!谢谢!
【解决方案2】:

几件事:

  • crop_image 函数中没有return 语句。
  • map_fn 接受单个参数。
  • 我强烈建议您将图形定义和会话使用分开。

--

# Graph def
def crop_image(img, crop):
    return tf.image.crop_to_bounding_box(img,
                                  crop[0],
                                  crop[1],
                                  crop[2],
                                  crop[3])

image_placeholder = tf.placeholder(tf.float32, [None, 400, 600, 3])
crop_placeholder = tf.placeholder(dtype=tf.int32)
cropped_image = tf.map_fn(lambda inputs: crop_image(*inputs), elems=[image_placeholder, crop_placeholder], dtype=tf.float32)


# Session
sess = tf.InteractiveSession()

img1 = np.random.random([400, 600, 3])
img2 = np.random.random([400, 600, 3])
img3 = np.random.random([400, 600, 3])

images = [img1, img2, img3]

img1_crop = [100, 100, 100, 100]
img2_crop = [200, 150, 100, 100]
img3_crop = [150, 200, 100, 100]

crop_values = [img1_crop, img2_crop, img3_crop]

sess.run(tf.global_variables_initializer())

result = sess.run(cropped_image, feed_dict={image_placeholder: images, crop_placeholder:crop_values})

plt.imshow(result[0])
plt.show()

【讨论】:

    【解决方案3】:

    tf.map_fn(f, l) 为列表 l 中的每个张量运行函数 f。在您的情况下,您的函数需要 2 个参数,但是由于您提供了一个平面列表,因此 map_fn() 将它们一一发送。根据文档, map_fn() 支持变量arity,所以你应该做的是这样的

    tf.map_fn(lambda img,crop:crop_image(img,crop), elems=([image_placeholder,crop_placeholder], ))

    因此您传递给 map_fn 的列表包含成对的参数。

    【讨论】:

    • TypeError: () 缺少 1 个必需的位置参数:'crop'
    • 我的示例不需要其他任何东西就可以运行。因此,您可以使用我上面发布的代码尝试您的方法,如果这样可以让事情变得更容易。
    • 这是 python 3,如果这会有所不同的话。
    • 该错误表明您的 lambda 函数得到一个参数而不是两个。您需要确保 map_fn 成对而不是一个一个地传递参数。我目前没有可以测试的系统。
    • 看来 elems 只接受一个张量。
    猜你喜欢
    • 2012-11-18
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-22
    • 1970-01-01
    • 1970-01-01
    • 2015-02-02
    相关资源
    最近更新 更多