Home > database >  How to get the mean of each image in a batch?
How to get the mean of each image in a batch?

Time:11-17

I have a batch of images thus the shape [None, 256, 256, 3] (the batch is set to none for practical purposes on use).

I am trying to implement a layer that calculates the average of each of the of images or frames in the batch to result the shape [None, 1] or [None, 1, 1, 1]. I have checked to use enter image description here

Which makes it entirely wrong.

I also tried this change on the call:

    def call(self, inputs):
        tensors = []
        for ii in range(inputs.shape[0] if inputs.shape[0] is not None else 1):
            tensors.append(tf.reduce_mean(inputs[ii, ...]))
        return tf.convert_to_tensor(tensors)

Which in turn results to:

Model: "model"
_________________________________________________________________
 Layer (type)                Output Shape              Param #
=================================================================
 input_1 (InputLayer)        [(None, 256, 256, 3)]     0

 element_mean (ElementMean)  (1,)                      0

=================================================================
Total params: 0
Trainable params: 0
Non-trainable params: 0
_________________________________________________________________

enter image description here

Which is also wrong.

CodePudding user response:

You can play around with the axes like this:

import tensorflow as tf

class ElementMean(tf.keras.layers.Layer):
    def __init__(self, **kwargs):
        super(ElementMean, self).__init__(**kwargs)
    
    def call(self, inputs):
        return tf.reduce_mean(inputs, axis=(1, 2, 3), keepdims=True)

x = tf.keras.layers.Input([256, 256, 3], None)
em = ElementMean()
y = em(x)
model = tf.keras.Model(x, y)
model.summary()
Model: "model_1"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_1 (InputLayer)        [(None, 256, 256, 3)]     0         
                                                                 
 element_mean_1 (ElementMean  (None, 1, 1, 1)          0         
 )                                                               
                                                                 
=================================================================
Total params: 0
Trainable params: 0
Non-trainable params: 0
_________________________________________________________________

CodePudding user response:

there is another way with segment means that allowed you to segment by heights, widths, and channels by remain its properties.

Sample: Width x Height x Channels, mean of each channel represent its data as mean value and you may summarize them later.

import os
from os.path import exists

import tensorflow as tf
import tensorflow_io as tfio

import matplotlib.pyplot as plt

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Variables
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
PATH = os.path.join('F:\\datasets\\downloads\\Actors\\train\\Pikaploy', '*.tif')
files = tf.data.Dataset.list_files(PATH)
list_file = []

for file in files.take(1):
    image = tf.io.read_file( file )
    image = tfio.experimental.image.decode_tiff(image, index=0)
    image = tf.image.resize(image, [28,32], method='nearest')
    list_file.append( image )

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Class / Definitions
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""   
class MyDenseLayer(tf.keras.layers.Layer):
    def __init__(self, num_outputs):
        super(MyDenseLayer, self).__init__()
        self.num_outputs = num_outputs
        
    def build(self, input_shape):
        self.kernel = self.add_weight("kernel",
        shape=[int(input_shape[-1]),
        self.num_outputs])

    def call(self, inputs):
    
        temp = tf.transpose( tf.constant(tf.cast(list_file, dtype=tf.int64), shape=(28, 32, 4), dtype=tf.int64) )
        temp = tf.transpose( temp )                                                                                         
        mean = tf.constant( tf.math.segment_mean( temp, tf.ones([28], dtype=tf.int64)).numpy() )
        
        temp = tf.image.rot90(temp)
        mean = tf.constant( tf.math.segment_mean( tf.constant(mean[1::], shape=(32, 4)), tf.ones([32], dtype=tf.int64)).numpy() )

        return mean[1::]

layer = MyDenseLayer(10)
sample = tf.transpose( tf.constant(tf.cast(list_file, dtype=tf.int64), shape=(28, 32, 4), dtype=tf.int64) )
data = layer(sample)

print( data )

Output: Rx Gx Bx Yx

tf.Tensor([[161 166 171 255]], shape=(1, 4), dtype=int64)
  • Related