batuman
batuman

Reputation: 7304

Averaged array calculation using numpy in Python

I am trying to get averaged pixel intensity using numpy in Python. I just started Python so I have some difficulties. My python script is

import numpy as np
import glob, os
from scipy import misc

path = "C:\\train"
files = []
for name in os.listdir(path):
    if os.path.isfile(os.path.join(path, name)):
       files.append(os.path.join(path, name))
divider = 1
averaged = []
for file in files:
   image = misc.imread(file)
   image = image.astype(np.float32, copy=False)
   if(divider == 1):
       averaged = image
       divider+=1
   else:
       for i in range(703):
          for j in range(1247):
             averaged[i][j] = averaged[i][j] + image[i][j]
             averaged[i][j] /= 2

averaged_mean = np.transpose(averaged,[2,0,1])
averaged_mean = averaged_mean.astype(np.float32, copy=False)
np.save("image_mean.npy", averaged_mean,fmt='%f')

I have two issues I need to make them improved. (1)My matrix dimensions are 704 x 1248 x 3. So taking average as I calculate shown above takes long time. I have 2000 images. How can I change the way to make it faster?

(2)When I save, I got the header in binary file as “NUMPY V {'descr': '<f4', 'fortran_order': False, 'shape': (3L, 704L, 1248L), }. I want to save as “NUMPY F {'descr': '<f8', 'fortran_order': False, 'shape': (3, 704, 1248), } How can I change it? Thanks

Upvotes: 0

Views: 106

Answers (1)

hilberts_drinking_problem
hilberts_drinking_problem

Reputation: 11602

You can replace

for i in range(703):
      for j in range(1247):
         averaged[i][j] = averaged[i][j] + image[i][j]
         averaged[i][j] /= 2

With averaged = (averaged + image) / 2 if averaged is defined to be a numpy array in the first place of the same shape as image. In terms of your code,

averaged = reduce(lambda l, r: (l + r)/2, 
    (misc.imread(f).astype(np.float32, copy = False) for f in files))

Note that this will put more weight on later images. To weight everything evenly, you can use

np.mean([misc.imread(f).astype(np.float32, copy = False) for f in files], axis = 0)

EDIT: This implements the second approach without having to load all images as once.

averaged2 = reduce(lambda l, r: l + r, 
    (misc.imread(f).astype(np.float32, copy = False) for f in files))\
    / len(files)

Upvotes: 3

Related Questions