def binImage(self, bin_factor_x=1, bin_factor_y=1, fraction_required_to_keep = 0.5):
# bin an image by bin_factor_x in X and bin_factor_y in Y by averaging all pixels in an bin_factor_x by bin_factor_y rectangle
# This is accomplished using convolution followed by downsampling, with the downsampling chosen so that the center
# of the binned image coincides with the center of the original unbinned one.
from scipy.signal import convolve2d
self.data [self.data <0 ] = 0 # temporarily remove flags
numberOfValues = (self.data != 0).astype(int) # record positions that have a value
binning_kernel = np.ones((bin_factor_x, bin_factor_y), dtype=float) # create binning kernel (all values within this get averaged)
self.data = convolve2d(self.data, binning_kernel, mode='same') # perform 2D convolution
numberOfValues = convolve2d(numberOfValues, binning_kernel, mode='same') # do the same with the number of values
self.data[ numberOfValues > 1 ] = self.data[ numberOfValues > 1 ] / numberOfValues[ numberOfValues > 1 ] # take average, accounting for how many datapoints went into each point
self.data[ numberOfValues < (bin_factor_x * bin_factor_y * fraction_required_to_keep)] = -1 # if too few values existed for averaging because too many of the pixels were unknown, make the resulting pixel unknown
dimx, dimy = np.shape(self.data) # get dimensions
centerX = dimx//2 # get center in X direction
centerY = dimy//2 # get center in Y direction
# Now take the smaller array from the smoothed large one to obtain the final binned image. The phrase "centerX % bin_factor_x"
# is to ensure that the subarray we take includes the exact center of the big array. For example if our original image is
# 1000x1000 then the central pixel is at position 500 (starting from 0). If we are binning this by 5 we want a 200x200 array
# where the new central pixel at x=100 corresponds to the old array at x=500, so "centerX % bin_factor_x" ->
# 500 % 5 = 0, so we would be indexing 0::5 = [0, 5, 10, 15..., 500, 505...] which is what we want. The same scenario with a
# 1004x1004 image needs the center of the 200x200 array to be at x=502, and 502 % 5 = 2 and we index
# 2::5 = [2,7,12..., 502, 507 ...]
self.data = self.data[ centerX % bin_factor_x :: bin_factor_x, centerY % bin_factor_y :: bin_factor_y ]
评论列表
文章目录