Reputation: 3974
I am using a numpy masked array to perform some image processing. The mask is in place to handle NoData pixels which surround the image (a necessary border as these are map projected images with the origin in a no data pixel).
Using the following code block, I am able to perform a gaussian stretch on an image.
def gaussian_stretch(input_array, array_mean, array_standard_deviation, number_of_bins, n):
shape = input_array.shape
input_array = input_array.flatten()
#define a gaussian distribution, get binned GDF histogram
array_standard_deviation *= n
gdf = numpy.random.normal(array_mean, array_standard_deviation, 10000)
hist, bins = numpy.histogram(gdf, number_of_bins, normed=True)
cdf = hist.cumsum()
cdf = 256 * cdf / cdf[-1]
#interpolate and reshape
input_array = numpy.interp(input_array,bins[:-1],cdf)
input_array = input_array.reshape(shape)
return input_array
If the image does not contain a NoData border the stretch works as expected. On an image with a mask, the mask is ignored. Is this expected behavior? Any ideas on how to process only the unmasked data?
I have tried using input_array.compressed(), but this returns a 1D array of only the unmasked values. Using numpy.interp then fails, as expected, because of the size disparity between arrays.
Finally, I understand that using numpy.random.normal will not always return a perfect gaussian distribution and I will add some margin of error contraints once the rest of the algorithm is functioning.
Upvotes: 3
Views: 2049
Reputation: 97281
you can get the mask of input_array first, and apply it to the result array, and use scipy.stats.norm to calculate cdf of normal distribution, or you can use scipy.special.erf() to calculate cdf by using the cdf formula of normal distribution:
import scipy.stats as stats
def gaussian_stretch2(input_array, array_mean, array_standard_deviation, n):
mask = input_array.mask
n = stats.norm(array_mean, array_standard_deviation*n)
return numpy.ma.array(n.cdf(input_array), mask=mask)
Upvotes: 3