0

the following code calculates local contrasts over the whole picture. And my version is really slow. I tried multithreading with 'pool' from the 'multiprocessing'-module, but it only speeded up 10%.
Can you help me speed it up more?

#pic: gray value picture (large 2d-array)
#xvar,yvar: scalar values, e.g. 200

contrast=[np.std(pic[stepx-xvar:xvar+stepx:,stepy-yvar:yvar+stepy:])*2 \
          for ystep in np.arange(yvar,np.int(pic.shape[1]-yvar),1)] \
          for stepx in np.arange(xvar,np.int(pic.shape[0]-xvar),1)]
Charlie Haley
  • 3,262
  • 3
  • 20
  • 34
SMBW
  • 41
  • 4
  • You know putting it all on one line doesn't actually speed it up. – Charles Clayton Sep 15 '15 at 15:10
  • Are you sure that is the code you are running? I guess you are missing a `[`. Also it would help if you specified the values/dimensions of your variables/arrays such as `pic`, as speed-ups are normally dependent on array shapes. – romeric Sep 15 '15 at 15:14

1 Answers1

0

The most-straightforward way would be:

from skimage.util import view_as_windows

windows = view_as_windows(pic, (xvar, yvar))
contrast = 2 * np.std(windows, axis=(2,3))

This blows up the picture to an array containing all the windows, but without additional memory overhead. The advantage is that you get rid of the Python loop/function-call overhead. It's based on a Numpy "stride-trick", see for the implementation here (or alternatively, the scikit-learn variant).

There is a method which scales a lot better though, see the answers here: improving code efficiency: standard deviation on sliding windows

Community
  • 1
  • 1