Matt
Matt

Reputation: 75

Conditional logic with Python ndimage generic_filter

I am trying to write a python function to remove hot-pixels in 2D image data. I am trying to make function that will take the mean for the neighbors around each element in the 2D array and conditionally overwrite that element if its value exceeds the mean of its neighbors by a specific amount (for example 3 sigma). This is where I am:

def myFunction(values):
    if np.mean(values) + 3*np.std(values) < origin:
        return np.mean(values)

footprint = np.array([[1,1,1],
                      [1,0,1],
                      [1,1,1]])
correctedData = ndimage.generic_filter(data, myFunction, footprint = footprint)

'origin' in the above code is demonstrative. I know it isn't correct, I am just trying to show what I am trying to do. Is there a way to pass the value of the current element to the generic_function?

Thanks!

Upvotes: 1

Views: 843

Answers (1)

Matt Hall
Matt Hall

Reputation: 8122

Your footprint is not passing the central value back to your function.

I find it easier to use size (equivalent to using all ones in the footprint), then deal with everything in the callback function. So in your case I'd extract the central value inside the callback function. Something like this:

from scipy.ndimage import generic_filter

def despike(values):
    centre = int(values.size / 2)
    avg = np.mean([values[:centre], values[centre+1:]])
    std = np.std([values[:centre], values[centre+1:]])
    if avg + 3 * std < values[centre]:
        return avg
    else:
        return values[centre]

Let's make some fake data:

data = np.random.randint(0, 10, (5, 5))
data[2, 2] = 100

This yields (for example):

array([[  2,   8,   4,   2,   4],
       [  9,   4,   7,   6,   5],
       [  9,   9, 100,   7,   3],
       [  0,   1,   0,   8,   0],
       [  9,   9,   7,   6,   0]])

Now you can apply the filter:

correctedData = generic_filter(data, despike, size=3)

Which removed the spike I added:

array([[2, 8, 4, 2, 4],
       [9, 4, 7, 6, 5],
       [9, 9, 5, 7, 3],
       [0, 1, 0, 8, 0],
       [9, 9, 7, 6, 0]])

Upvotes: 1

Related Questions