50427
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)](https://i.stack.imgur.com/que4T.png)

* * *
CC BY-SA 4.0
2018-11-18T14:36:40.043
50419
2018-11-19T08:52:37.493
2018-11-18T14:47:24.973
76
31038
question
python 機械学習 tensorflow
画像データが格納されたテンソルの扱い方
回答ではありません。趣旨としてはコメントでするべきですが、commentは「説明する」「補足する」の意味なので、信用がないと説明を加えられないようです。

ご要望のことは、TensorFlowではなく、Numpyなどの行列演算でできそうです。[20, 64, 64,
3]は、バッチ数、縦、横、カラー数なので、データ[n,h,w,c]のcでRGBにアクセスできます。[n,h:h+4,w:w+4,:].min()で、範囲内の最小が出ます。ただ、画像データの取得方法によって、RGBかBGRか変わります。色の違いに意味があるなら、注意してください。  
ここまで、TensorFlowの出番はありません。どう関係してくるのでしょうか。
CC BY-SA 4.0
2018-11-18T23:54:25.737
50422
2018-11-19T00:03:50.487
2018-11-19T00:03:50.487
29996
29996
50419
answer
まずカラーチャンネルの次元を縮約することを考えるなら  
Tensorflowには、reduce関数が定義されています。  
これは、あるrankの値を全て何らかの操作で、１つの値にまとめ上げる操作を行うものです。

reduce関数は `tf.reduce_xxx(<対象のテンソル>, <reduceする次元>)` という形式をしています。  
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のブロックに区切り、  
その区切りのブロック内を１rank内に並べてしまう関数が定義されています。

たとえば `[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]` が得られることになります。
CC BY-SA 4.0
2018-11-19T02:43:08.530
50427
2018-11-19T08:52:37.493
2018-11-19T08:52:37.493
30827
30827
50419
answer