質問: TensorFlowで画像処理を行いたい初心者です。 機械学習ネットワークから出力される、64×64の画像20枚分のテンソル[20,64,64,3]に対してある処理を行い、新たなテンソル[20,64,64,1]を求めたいのですが、適切な操作がわからず困っております。 やりたい処理としては、画像一枚の4×4のパッチ領域でRGBチャネル内の一番小さい値を見つけ出し、新たな画像のパッチ領域をその値で埋めてくことを繰り返すというものです。 RGBチャネルそれぞれの値へのアクセスの仕方が分からず手も足も出ません。 ご回答よろしくお願いいたします。 --- 処理について図を描いてみました。 下の図を例とすると、 最初の4×4領域において、RGBのうちGのチャネルが最小値16を有するため、新たな画像の同じ領域は全て16とします。 また、次の4×4領域においては、Bのチャネルが最小6を有するため、新たな画像において値を6とします。 これを繰り返してシングルチャネルの画像20枚分のテンソルを求めていきたいです。 --- ![やりたいこと画像](https://i.stack.imgur.com/que4T.png) ---
回答: まずカラーチャンネルの次元を縮約することを考えるなら Tensorflowには、reduce関数が定義されています。 これは、あるrankの値を全て何らかの操作で、1つの値にまとめ上げる操作を行うものです。 reduce関数は `tf.reduce_xxx(<対象のテンソル>, )` という形式をしています。 xxxの部分には、どのような操作を行うのかが入り、たとえば `tf.reduce_sum`, `tf.reduce_prod`, `tf.reduce_mean` などが定義されています。 (最新の情報はTensorflowのリファレンスを参照ください) さて今回の場合 `tf.reduce_min` がまさに対象となる関数です。 具体的には `[20,64,64,3]` であるテンソルを `t` と呼ぶことにすると `tf.reduce_min(t, 3)` により、 `[20, 64, 64]` なテンソルを得ることが出来ます。 また、 `keep_dims=True` とすることで、計算後にrank数そのものは落とさず残すことが出来ます。 したがってモノクロ1チャンネルだけにして最後のrankを残したいのであれば `tf.reduce_min(t, 3, keep_dims=True)` としてみてください。 この場合は `[20, 64, 64, 1]` なテンソルが得られます。 これとは別に、 `tf.space_to_depth(<対象のテンソル>, <ブロックサイズ>)` という、 複数枚の画像のテンソルを、それぞれ縦横NxNのブロックに区切り、 その区切りのブロック内を1rank内に並べてしまう関数が定義されています。 たとえば `[20, 64, 64, 3]` のテンソル `t` を 4x4 の画像ブロックごとに並べるなら `tf.space_to_depth( t, 4 )` とします。 この結果は `[20, 16, 16, 48]` になります。 そこで `tf.reduce_min( tf.space_to_depth( t, 4 ), 3, keep_dims=True )` のような処理で所望の結果 `[20, 16, 16, 1]` が得られることになります。