2017-01-10 11 views
0

私はTensorflowで動的に決定された画像のトリミング方法を理解しようとしています。以下は私が達成しようとしているものの例ですが、それを機能させるようには見えません。基本的には、グラフ内の画像とその画像のクロップ値をフィードし、それらのクロップされた部分の他の計算を続けます。私の現在の試み: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 
Traceback (most recent call last): 
    File "/Users/p111/PycharmProjects/analysis_code/testing.py", line 31, in 
    cropped_image = tf.map_fn(lambda img, crop: crop_image(img, crop), elems=[image_placeholder, crop_placeholder]) 
    File "/Users/p111/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/functional_ops.py", line 390, in map_fn 
    swap_memory=swap_memory) 
    File "/Users/p111/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/control_flow_ops.py", line 2636, in while_loop 
    result = context.BuildLoop(cond, body, loop_vars, shape_invariants) 
    File "/Users/p111/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/control_flow_ops.py", line 2469, in BuildLoop 
    pred, body, original_loop_vars, loop_vars, shape_invariants) 
    File "/Users/p111/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/control_flow_ops.py", line 2419, in _BuildLoop 
    body_result = body(*packed_vars_for_body) 
    File "/Users/p111/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/functional_ops.py", line 380, in compute 
    packed_fn_values = fn(packed_values) 
TypeError:() missing 1 required positional argument: 'crop' 

編集:elemsは単一テンソルを受け入れることが表示されます。つまり、どうにかして2つのテンソルを1つにまとめる必要があり、次に値を取得するために関数で展開します。私はそのようなテンソル操作をどのように実行するのかはわかりません。私はすでに垣間見る方法を見つけたが、それはうまくいくが、私はこの特定の方法で同じことができるかどうか疑問に思っている。ほとんどの場合、このメソッドで使用できるように、テンソルのペアを結合して分割する方法が不思議です。

+0

あなたの現在の試行でうまくいきませんか?トレースバックがある場合は、完全に投稿してください!申し訳ありませんが、 – mrry

+0

追加されたスタックトレース。私は、問題が明らかになるような単純な問題であるように思われたので、私は仮定しました。私は、これについて最善の方法で何とかしていくつもりはないと確信しています。 – Beaker

答えて

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] 

タプルまたはリストを使用して複数の要素を1つにまとめることができます。これを試しました。

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で動作します。これがあなたを助けることを願っています。物事の

+0

なぜ私は自分自身でこれを理解することができなかったのか分かりません。あなたはそれをとてもシンプルに見せます!ありがとう! – Beaker

0

tf.map_fn(f、l)は、リストlのテンソルごとに関数fを実行します。あなたの場合、関数は2つの引数を必要としますが、フラットリストを提供するので、map_fn()はそれらを1つずつ送ります。ドキュメントによると、map_fn()は変数アリティをサポートしていますので、何をやるべきことは、この

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

のようなものは、あなたがmap_fnに渡すリストは、引数のペアが含まれています。

+0

TypeError:()missing 1必要な位置引数: 'crop' – Beaker

+0

私の例は何も必要なく実行されます。上記のコードを使ってメソッドを試すことができます。 – Beaker

+0

これは、これが違いを生む場合は、Python 3です。 – Beaker

1

カップル:

  • あなたはcrop_image機能でreturn文はありません。
  • map_fnは、1つの引数を受け入れます。
  • グラフ定義とセッションの使用方法を分けることを強くお勧めします。

-

# 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() 
関連する問題