Search code examples
pythonhistogramminimum

Find locale minimum in histogram (1D array) (Python)


I have processed radar image and to detect water I have to find local minimum in the histogram. Histogram is little bit different for every area so I have to automatically find local minimum based on every histogram.

Histogram for Sigma0_VV

My input array is 1D array of image values (0.82154, 0.012211,...). I know how to create histogram in numpy and matplotlib but I do not know what should I do to determine locale minimum which is showed in the picture. I use python scipy libraries.

First step should be to smooth the histogram for easier determination of minimum, could you tell me what to use to smooth data ? Something like this:

Smoothed/Unsmoothed


Solution

  • You can smooth the data with numpy with numpy.convolve() or you can use the following function:

    import numpy
    
    def smooth(x,window_len=11,window='hanning'):
        if x.ndim != 1:
            raise ValueError, "smooth only accepts 1 dimension arrays."
    
        if x.size < window_len:
            raise ValueError, "Input vector needs to be bigger than window size."
    
    
        if window_len<3:
            return x
    
    
        if not window in ['flat', 'hanning', 'hamming', 'bartlett', 'blackman']:
            raise ValueError, "Window is on of 'flat', 'hanning', 'hamming', 'bartlett', 'blackman'"
    
    
        s=numpy.r_[x[window_len-1:0:-1],x,x[-2:-window_len-1:-1]]
        #print(len(s))
        if window == 'flat': #moving average
            w=numpy.ones(window_len,'d')
        else:
            w=eval('numpy.'+window+'(window_len)')
    
        y=numpy.convolve(w/w.sum(),s,mode='valid')
        return y
    

    Also please take a look at the scipy documentation:

    If you are looking for all entries in the 1d array a smaller than their neighbors, you can try

    numpy.r_[True, a[1:] < a[:-1]] & numpy.r_[a[:-1] < a[1:], True]
    

    In SciPy >= 0.11 you can use the following:

    import numpy as np
    from scipy.signal import argrelextrema
    
    x = np.random.random(12)
    
    # for local minima
    argrelextrema(x, np.less)