def filter_bank(img, coeff_resolution): """ Calculates the responses of an image to M filters. Returns 2-d array of the vectorial responses """ h, w = img.shape im = np.reshape(img, (h*w, 1)) e1 = np.reshape(entropy(img, disk(coeff_resolution*5)), (h*w, 1)) e2 = np.reshape(entropy(img, disk(coeff_resolution*8)), (h*w, 1)) e3 = np.reshape(entropy(img, disk(coeff_resolution*10)), (h*w, 1)) g1 = np.reshape(gradient(img, disk(1)), (h*w, 1)) g2 = np.reshape(gradient(img, disk(coeff_resolution*3)), (h*w, 1)) g3 = np.reshape(gradient(img, disk(coeff_resolution*5)), (h*w, 1)) m1 = np.reshape(ndi.maximum_filter(256-img, size=coeff_resolution*2, mode='constant'), (h*w, 1)) m2 = np.reshape(ndi.maximum_filter(256-img, size=coeff_resolution*4, mode='constant'), (h*w, 1)) m3 = np.reshape(ndi.maximum_filter(256-img, size=coeff_resolution*7, mode='constant'), (h*w, 1)) #c = np.reshape(canny(img), (h*w, 1)) s = np.reshape(sobel(img), (h*w, 1)) return np.column_stack((im, e1, e2, e3, g1, g2, g3, m1, m2, m3, s))
def canny(image, high_threshold, low_threshold): grad_x = ndimage.sobel(image, 0) grad_y = ndimage.sobel(image, 1) grad_mag = numpy.sqrt(grad_x**2+grad_y**2) grad_angle = numpy.arctan2(grad_y, grad_x) # next, scale the angles in the range [0, 3] and then round to quantize quantized_angle = numpy.around(3 * (grad_angle + numpy.pi) / (numpy.pi * 2)) # Non-maximal suppression: an edge pixel is only good if its magnitude is # greater than its neighbors normal to the edge direction. We quantize # edge direction into four angles, so we only need to look at four # sets of neighbors NE = ndimage.maximum_filter(grad_mag, footprint=_NE) W = ndimage.maximum_filter(grad_mag, footprint=_W) NW = ndimage.maximum_filter(grad_mag, footprint=_NW) N = ndimage.maximum_filter(grad_mag, footprint=_N) thinned = (((grad_mag > W) & (quantized_angle == _N_d )) | ((grad_mag > N) & (quantized_angle == _W_d )) | ((grad_mag > NW) & (quantized_angle == _NE_d)) | ((grad_mag > NE) & (quantized_angle == _NW_d)) ) thinned_grad = thinned * grad_mag # Now, hysteresis thresholding: find seeds above a high threshold, then # expand out until we go below the low threshold high = thinned_grad > high_threshold low = thinned_grad > low_threshold canny_edges = ndimage.binary_dilation(high, structure=numpy.ones((3,3)), iterations=-1, mask=low) return grad_mag, thinned_grad, canny_edges
def test_multiple_modes(): # Test that the filters with multiple mode cababilities for different # dimensions give the same result as applying a single mode. arr = np.array([[1., 0., 0.], [1., 1., 0.], [0., 0., 0.]]) mode1 = 'reflect' mode2 = ['reflect', 'reflect'] assert_equal(sndi.gaussian_filter(arr, 1, mode=mode1), sndi.gaussian_filter(arr, 1, mode=mode2)) assert_equal(sndi.prewitt(arr, mode=mode1), sndi.prewitt(arr, mode=mode2)) assert_equal(sndi.sobel(arr, mode=mode1), sndi.sobel(arr, mode=mode2)) assert_equal(sndi.laplace(arr, mode=mode1), sndi.laplace(arr, mode=mode2)) assert_equal(sndi.gaussian_laplace(arr, 1, mode=mode1), sndi.gaussian_laplace(arr, 1, mode=mode2)) assert_equal(sndi.maximum_filter(arr, size=5, mode=mode1), sndi.maximum_filter(arr, size=5, mode=mode2)) assert_equal(sndi.minimum_filter(arr, size=5, mode=mode1), sndi.minimum_filter(arr, size=5, mode=mode2)) assert_equal(sndi.gaussian_gradient_magnitude(arr, 1, mode=mode1), sndi.gaussian_gradient_magnitude(arr, 1, mode=mode2)) assert_equal(sndi.uniform_filter(arr, 5, mode=mode1), sndi.uniform_filter(arr, 5, mode=mode2))
def LocalMax(self, data, kwidth, scaling, out = None): assert len(data.shape) == 3, \ "Unsupported shape for input data: %s" % (data.shape,) kshape = (kwidth, kwidth) output = np.empty_like(data) for d, o in zip(data, output): maximum_filter(d, kshape, output = o) output_bands = PruneArray(output, kshape, scaling) if out != None: out[:] = output_bands.flat return out return output_bands
def max_diff(self, spec, pos=False, diff_frames=None, max_bins=None): """ Calculates the difference of k-th frequency bin of the magnitude spectrogram relative to the maximum over m bins (e.g. m=3: k-1, k, k+1) of the N-th previous frame. :param spec: the magnitude spectrogram :param pos: only keep positive values [default=False] :param diff_frames: calculate the difference to the N-th previous frame [default=None] :param max_bins: number of bins the maximum is search [default=None] Note: This method works only properly if the number of bands for the filterbank is chosen carefully. A values of 24 (i.e. quarter-tone resolution) usually yields good results. """ # import import scipy.ndimage as sim # init diff matrix diff = np.zeros_like(spec) if diff_frames is None: diff_frames = self.diff_frames assert diff_frames >= 1, 'number of diff_frames must be >= 1' if max_bins is None: max_bins = self.max_bins assert max_bins >= 1, 'search range for the maximum filter must be >= 1' # calculate the diff diff[diff_frames:] = spec[diff_frames:] - sim.maximum_filter(spec, size=[1, max_bins])[0:-diff_frames] # keep only positive values if pos: diff = diff * (diff > 0) return diff
def _detect(self,im): ''' void cvCornerHarris( const CvArr* image, CvArr* harris_responce, int block_size, int aperture_size=3, double k=0.04 ); ''' gray = im.asOpenCVBW() #gray = opencv.cvCreateImage( opencv.cvGetSize(cvim), 8, 1 ); corners = cv.CreateImage( cv.GetSize(gray), 32, 1 ); #opencv.cvCvtColor( cvim, gray, opencv.CV_BGR2GRAY ); cv.CornerHarris(gray,corners,self.block_size,self.aperture_size,self.k) buffer = corners.tostring() corners = numpy.frombuffer(buffer,numpy.float32).reshape(corners.height,corners.width).transpose() footprint = ones((3,3)) mx = maximum_filter(corners, footprint = footprint) local_maxima = (corners == mx) * (corners != zeros(corners.shape)) # make sure to remove completly dark points points = nonzero(local_maxima) del local_maxima points = array([points[0],points[1]]).transpose() L = [] for each in points: L.append((corners[each[0],each[1]],each[0],each[1],None)) return L
def detect_peaks(image): """Detect peaks in an image using a maximum filter. Parameters ---------- TODO Returns ------- TODO """ from scipy.ndimage import maximum_filter from scipy.ndimage.morphology import binary_erosion # Set up 3x3 footprint for maximum filter, can also be a different neighborhood if necessary footprint = np.ones((3, 3)) # Apply maximum filter: All pixel in the neighborhood are set # to the maximal value. Peaks are where image = maximum_filter(image) local_maximum = maximum_filter(image, footprint=footprint) == image # We have false detections, where the image is zero, we call it background. # Create the mask of the background zero_background = (image == 0) # Erode background at the borders, otherwise we would miss the points in the neighborhood eroded_background = binary_erosion(zero_background, structure=footprint, border_value=1) # Remove the background from the local_maximum image detected_peaks = local_maximum - eroded_background return detected_peaks
def detect_peaks_3D(image): """Same functionality as detect_peaks, but works on image cubes. Parameters ---------- TODO Returns ------- TODO """ from scipy.ndimage import maximum_filter from scipy.ndimage.morphology import binary_erosion # Set up 3x3 footprint for maximum filter footprint = np.ones((3, 3, 3)) # Apply maximum filter: All pixel in the neighborhood are set # to the maximal value. Peaks are where image = maximum_filter(image) local_max = maximum_filter(image, footprint=footprint, mode='constant') == image # We have false detections, where the image is zero, we call it background. # Create the mask of the background background = (image == 0) # Erode background at the borders, otherwise we would miss eroded_background = binary_erosion(background, structure=footprint, border_value=1) # Remove the background from the local_max mask detected_peaks = local_max - eroded_background return detected_peaks
def extract_local_max(img_gray): im = img_as_float(img_gray) # image_max is the dilation of im with a 20*20 structuring element # It is used within peak_local_max function image_max = ndimage.maximum_filter(im, size=20, mode='constant') # Comparison between image_max and im to find the coordinates of local maxima coordinates = peak_local_max(im, min_distance=20) # display results fig, ax = plt.subplots(1, 3, figsize=(8, 3)) ax1, ax2, ax3 = ax.ravel() ax1.imshow(im, cmap=plt.cm.gray) ax1.axis('off') ax1.set_title('Original') ax2.imshow(image_max, cmap=plt.cm.gray) ax2.axis('off') ax2.set_title('Maximum filter') ax3.imshow(im, cmap=plt.cm.gray) ax3.autoscale(False) ax3.plot(coordinates[:, 1], coordinates[:, 0], 'r.') ax3.axis('off') ax3.set_title('Peak local max') fig.subplots_adjust(wspace=0.02, hspace=0.02, top=0.9, bottom=0.02, left=0.02, right=0.98) plt.show()
def test_multiple_modes_sequentially(): # Test that the filters with multiple mode cababilities for different # dimensions give the same result as applying the filters with # different modes sequentially arr = np.array([[1., 0., 0.], [1., 1., 0.], [0., 0., 0.]]) modes = ['reflect', 'wrap'] expected = sndi.gaussian_filter1d(arr, 1, axis=0, mode=modes[0]) expected = sndi.gaussian_filter1d(expected, 1, axis=1, mode=modes[1]) assert_equal(expected, sndi.gaussian_filter(arr, 1, mode=modes)) expected = sndi.uniform_filter1d(arr, 5, axis=0, mode=modes[0]) expected = sndi.uniform_filter1d(expected, 5, axis=1, mode=modes[1]) assert_equal(expected, sndi.uniform_filter(arr, 5, mode=modes)) expected = sndi.maximum_filter1d(arr, size=5, axis=0, mode=modes[0]) expected = sndi.maximum_filter1d(expected, size=5, axis=1, mode=modes[1]) assert_equal(expected, sndi.maximum_filter(arr, size=5, mode=modes)) expected = sndi.minimum_filter1d(arr, size=5, axis=0, mode=modes[0]) expected = sndi.minimum_filter1d(expected, size=5, axis=1, mode=modes[1]) assert_equal(expected, sndi.minimum_filter(arr, size=5, mode=modes))
def _count_covertypes_within_window(self, lct, cover_type_list, footprint): """Return integer array indicating the number of different covertypes of interest that are within the moving window (footprint)""" m = zeros(shape=lct.shape, dtype=int32) for cover_type in cover_type_list: m += maximum_filter(equal(lct, cover_type), footprint=footprint) return m
def k_means_classifier(image): n_clusters = 8 # blur and take local maxima blur_image = gaussian(image, sigma=8) blur_image = ndi.maximum_filter(blur_image, size=3) # get texture features feats = local_binary_pattern(blur_image, P=40, R=5, method="uniform") feats_r = feats.reshape(-1, 1) # cluster the texture features km = k_means(n_clusters=n_clusters, batch_size=500) clus = km.fit(feats_r) # copy relevant attributes labels = clus.labels_ clusters = clus.cluster_centers_ # reshape label arrays labels = labels.reshape(blur_image.shape[0], blur_image.shape[1]) # segment shadow img = blur_image.ravel() shadow_seg = img.copy() for i in range(0, n_clusters): # set up array of pixel indices matching cluster mask = np.nonzero((labels.ravel() == i) == True)[0] if len(mask) > 0: thresh = threshold_otsu(img[mask]) shadow_seg[mask] = shadow_seg[mask] < thresh shadow_seg = shadow_seg.reshape(*image.shape) return shadow_seg
def adjacent_labels(labels): m1 = nd.maximum_filter(labels, size=3) m1[m1 == labels] = 0 m2 = nd.minimum_filter(labels, size=3) m2[m2 == labels] = 0 m1[m2 > 0] = m2[m2 > 0] return m1
def local_maxima(array, min_distance = 1, periodic=False, edges_allowed=True): """Find all local maxima of the array, separated by at least min_distance. adapted from = http://old.nabble.com/Finding-local-minima-of-greater-than-a-given-depth-td18988309.html""" array = np.asarray(array) cval = 0 if periodic: mode = 'wrap' elif edges_allowed: mode = 'nearest' else: mode = 'constant' cval = array.max()+1 nbhood=ndimage.morphology.generate_binary_structure(len(array.shape),2) maxima = array == ndimage.maximum_filter(array, footprint=nbhood, mode=mode, cval=cval) background = (array==0) eroded_background = ndimage.morphology.binary_erosion( background, structure=nbhood, border_value=1) maxima = maxima - eroded_background maxpy, maxpx = np.where(maxima) max_points = [(maxpy[i],maxpx[i]) for i in range(len(maxpy))] if not type(max_points)==list: max_points=[max_points] return max_points
def find_corners(im, name): coherence, _, _ = structure.orientation_field(im, 11) pylab.imshow(im, cmap=pylab.cm.gray) pylab.figure() pylab.imshow(coherence) pylab.title('coherence') pylab.colorbar() local_mean = nd.filters.gaussian_filter(im.astype(float), 20) local_variance = nd.filters.gaussian_filter(im.astype(float) ** 2.0, 20) - local_mean ** 2 pylab.figure() pylab.imshow(np.sqrt(local_variance) / local_mean, cmap=pylab.cm.gray) pylab.title('std / mean') pylab.colorbar() potential_corners = coherence / np.sqrt(local_variance) pylab.figure() pylab.imshow(potential_corners, cmap=pylab.cm.gray) pylab.colorbar() # find local max with a suppression window of radius 11 pc_max = nd.minimum_filter(potential_corners, (20, 20)) corners = potential_corners == pc_max print np.sum(corners) corners = nd.maximum_filter(corners, (5, 5)) pylab.show() imtmp = np.dstack((im, im, im)) imtmp[:, :, 2][corners] = 255 cv2.imshow(name, imtmp[::2, ::2])
def find_local_maxima(image, min_distance): """Find maxima in an image. Finds the highest-valued points in an image, such that each point is separted by at least min_distance. If there are flat regions that are all at a maxima, the enter of mass of the region is reported. Large flat regions of more than min_distance in radius will be erroneously returned as maxima even if they are not. Further filtering should be performed to exclude these if needed. Returns the position of the maxima and the value at each maximum. Parameters: image: image of arbitrary dimensionality min_distance: maxima found will be at least this many pixels apart Returns: centroids: list of centers of each maxima values: image value at each maxima """ image_max = ndimage.maximum_filter(image, size=2*min_distance+1, mode='constant') peak_mask = (image == image_max) # NB: some maxima might be marked by multiple contiguous pixels if the image # has "plateaus". So we need to label the mask and get the centroids # of each of the labeled regions. labeled_image, num_regions = ndimage.label(peak_mask) label_indices = numpy.arange(1, num_regions+1) centroids = ndimage.center_of_mass(peak_mask, labeled_image, label_indices) values = ndimage.mean(image, labeled_image, label_indices) return numpy.array(centroids), values
def find_local_maxima(self): ''' Find local maxima in each of the detected blobs ''' ge_labeled_data = self.ge_labeled_data ge_data = self.ge_data cfg = self.cfg logger = self.logger int_scale_factor = self.int_scale_factor number_of_labels = self.number_of_labels min_peak_separation = self.min_peak_separation blobs = self.blobs logger.info("Detecting local maxima") for blob in blobs: slice_x, slice_y, slice_z = blob.slice_x, blob.slice_y, blob.slice_z label_num = blob.blob_label roi = ge_data[slice_x, slice_y, slice_z] write_image('roi' + str(label_num) + '.png', np.amax(roi, 0), vmin=0) max_points = roi == ndimage.maximum_filter(roi, min_peak_separation, mode='nearest', cval=0) max_points[roi < int_scale_factor*cfg.fit_grains.threshold] roi[np.logical_not(max_points)] = 0 write_image('roi' + str(label_num) + '_max.png', np.amax(roi, 0), vmin=0) return blobs
def compute_harris_response(image, eps=1e-6): """ compute the Harris corner detector response function for each pixel in the image""" # derivatives image = ndimage.gaussian_filter(image, 1) imx = ndimage.sobel(image, axis=0, mode='constant') imy = ndimage.sobel(image, axis=1, mode='constant') Wxx = ndimage.gaussian_filter(imx * imx, 1.5, mode='constant') Wxy = ndimage.gaussian_filter(imx * imy, 1.5, mode='constant') Wyy = ndimage.gaussian_filter(imy * imy, 1.5, mode='constant') # determinant and trace Wdet = Wxx * Wyy - Wxy ** 2 Wtr = Wxx + Wyy harris = Wdet / (Wtr + eps) # Non maximum filter of size 3 harris_max = ndimage.maximum_filter(harris, 3, mode='constant') harris *= harris == harris_max # Remove the image corners harris[:3] = 0 harris[-3:] = 0 harris[:, :3] = 0 harris[:, -3:] = 0 return harris
def nonmax_supress(area_img, angles): _NE_d = 0 _W_d = 1 _NW_d = 2 _N_d = 3 quantized_angle = np.around(angles) % 4 NE = ndimage.maximum_filter(area_img, footprint=_NE) W = ndimage.maximum_filter(area_img, footprint=_W) NW = ndimage.maximum_filter(area_img, footprint=_NW) N = ndimage.maximum_filter(area_img, footprint=_N) thinned = (((area_img >= W) & (quantized_angle == _N_d )) | ((area_img >= N) & (quantized_angle == _W_d )) | ((area_img >= NW) & (quantized_angle == _NE_d)) | ((area_img >= NE) & (quantized_angle == _NW_d)) ) thinned_grad = thinned * area_img return thinned_grad
def dom_get(wseries, tpoint, scales): values = (np.abs(wseries)) * (np.abs(wseries)) values = values / (scales * scales) maxoutt = (values == ndimage.maximum_filter(values, 15, mode='reflect')) try: x = np.where( (maxoutt == 1)) # & (np.abs(parr) > scales ** .5)# ((wl >= np.percentile(wl[wl >= 0.5], 90)) & except IndexError: return False try: ind = (x[0])[0] except IndexError: return False scal = scales[ind] wavelet_pos_neg = np.real(wseries)[ind] if (wavelet_pos_neg < 0) : #| (tpoint < -1.) scal = scal * -1 # if values[ind] < 0.02: # scal = np.nan return scal
def non_maximal_edge_suppresion(mag, orient, minEdgeRadius=20, maxEdgeRadius=None): """ Non Maximal suppression of gradient magnitude and orientation. """ t0 = time.time() ## bin orientations into 4 discrete directions abin = ((orient + math.pi) * 4 / math.pi + 0.5).astype('int') % 4 radialsq, angles = getRadialAndAngles(mag.shape) ### create circular mask if maxEdgeRadius is None: maxEdgeRadiusSq = radialsq[mag.shape[0]/2,mag.shape[0]/10] else: maxEdgeRadiusSq = maxEdgeRadius**2 outermask = numpy.where(radialsq > maxEdgeRadiusSq, False, True) ## probably a bad idea here innermask = numpy.where(radialsq < minEdgeRadius**2, False, True) ### create directional filters to go with offsets horz = numpy.where(numpy.abs(angles) < 3*math.pi/4., numpy.abs(angles), 0) horz = numpy.where(horz > math.pi/4., True, False) vert = -horz upright = numpy.where(angles < math.pi/2, False, True) upleft = numpy.flipud(upright) upleft = numpy.fliplr(upleft) upright = numpy.logical_or(upright, upleft) upleft = -upright # for rotational edges filters = [horz, upleft, vert, upright] # for radial edges #filters = [vert, upright, horz, upleft] offsets = ((1,0), (1,1), (0,1), (-1,1)) edge_map = numpy.zeros(mag.shape, dtype='bool') for a in range(4): di, dj = offsets[a] footprint = numpy.zeros((3,3), dtype="int") footprint[1,1] = 0 footprint[1+di,1+dj] = 1 footprint[1-di,1-dj] = 1 ## get adjacent maximums maxfilt = ndimage.maximum_filter(mag, footprint=footprint) ## select points larger than adjacent maximums newedge_map = numpy.where(mag>maxfilt, True, False) ## filter by edge orientation newedge_map = numpy.where(abin==a, newedge_map, False) ## filter by location newedge_map = numpy.where(filters[a], newedge_map, False) ## add to main map edge_map = numpy.where(newedge_map, True, edge_map) ## remove corner edges edge_map = numpy.where(outermask, edge_map, False) edge_map = numpy.where(innermask, edge_map, False) #print time.time() - t0 return edge_map
def on_image_image(self, image_id): #def on_image_image(self, request, image_id): result = self.work.get_image(image_id).copy() seg = self.work.get_segmentation(image_id) border = ndimage.maximum_filter(seg.labels,size=(3,3)) != ndimage.minimum_filter(seg.labels,size=(3,3)) result[border] = 0.0 return image_response(result)
def apply(array, **kwargs): """ Apply a set of standard filter to array data: Call: apply(array-data, <list of key=value arguments>) The list of key-value define the filtering to be done and should be given in the order to be process. Possible key-value are: * smooth: gaussian filtering, value is the sigma parameter (scalar or tuple) * uniform: uniform filtering (2) * max: maximum filtering (1) * min: minimum filtering (1) * median: median filtering (1) * dilate: grey dilatation (1) * erode: grey erosion (1) * close: grey closing (1) * open: grey opening (1) * linear_map: call linear_map(), value is the tuple (min,max) (3) * normalize: call normalize(), value is the method (3) * adaptive: call adaptive(), value is the sigma (3) * adaptive_: call adaptive(), with uniform kernel (3) The filtering is done using standard scipy.ndimage functions. (1) The value given (to the key) is the width of the the filter: the distance from the center pixel (the size of the filter is thus 2*value+1) The neighborhood is an (approximated) boolean circle (up to discretization) (2) Same as (*) but the neighborhood is a complete square (3) See doc of respective function """ for key in kwargs: value = kwargs[key] if key not in ('smooth','uniform'): fp = _kernel.distance(array.ndim*(2*value+1,))<=value # circular filter if key=='smooth' : array = _nd.gaussian_filter(array, sigma=value) elif key=='uniform': array = _nd.uniform_filter( array, size=2*value+1) elif key=='max' : array = _nd.maximum_filter( array, footprint=fp) elif key=='min' : array = _nd.minimum_filter( array, footprint=fp) elif key=='median' : array = _nd.median_filter( array, footprint=fp) elif key=='dilate' : array = _nd.grey_dilation( array, footprint=fp) elif key=='erode' : array = _nd.grey_erosion( array, footprint=fp) elif key=='open' : array = _nd.grey_opening( array, footprint=fp) elif key=='close' : array = _nd.grey_closing( array, footprint=fp) elif key=='linear_map': array = linear_map(array, min=value[0], max=value[1]) elif key=='normalize' : array = normalize( array, method = value) elif key=='adaptive' : array = adaptive( array, sigma = value, kernel='gaussian') elif key=='adaptive_' : array = adaptive( array, sigma = value, kernel='uniform') else: print '\033[031mUnrecognized filter :', key return array
def LocalMax(self, data, kwidth, scaling, out = None): """Convolve maps with local 2-D max filter. data -- (3-D) array of input data kwidth -- (positive int) kernel width scaling -- (positive int) subsampling factor out -- (2-D) array in which to store result """ assert len(data.shape) == 3, \ "Unsupported shape for input data: %s" % (data.shape,) kshape = (kwidth, kwidth) output = np.empty_like(data) for d, o in zip(data, output): maximum_filter(d, kshape, output = o) output_bands = PruneArray(output, kshape, scaling) if out != None: out[:] = output_bands.flat return out return output_bands
def select_region_slices(sci_data, badpix_mask, box_size=256, num_boxes=10): """ Find the optimal regions for calculating the noise autocorrelation (areas with the fewest objects/least signal) :param sci_data: Science image data array :param badpix_mask: Boolean array that is True for bad pixels :param box_size: Size of the (square) boxes to select :param num_boxes: Number of boxes to select. If insufficient good pixels can be found, will return as many boxes as possible :return: List of 2D slices, tuples of (slice_y, slice_x) """ # TODO: For large images this is pretty slow, due to 3 full-size filters img_boxcar = ndimg.uniform_filter(sci_data, size=box_size) # Smooth over mask with min filter, to ignore small areas of bad pixels # One tenth of box size in each dimension means ignoring bad pixel regions # comprising <1% of total box pixels smooth_size = box_size // 10 badpix_mask = ndimg.minimum_filter(badpix_mask, size=smooth_size, mode='constant', cval=False) # Expand zone of avoidance of bad pixels, so we don't pick boxes that # contain them. mode=constant, cval=True means treat all borders as # if they were masked-out pixels badpix_mask = ndimg.maximum_filter(badpix_mask, size=smooth_size + box_size, mode='constant', cval=True) img_boxcar = np.ma.array(img_boxcar, mask=badpix_mask) box_slices = [] for box in range(num_boxes): # Find the location of the minimum value of the boxcar image, excluding # masked areas. This will be a pixel with few nearby sources within one # box width min_loc = img_boxcar.argmin() min_loc = np.unravel_index(min_loc, img_boxcar.shape) lower_left = tuple(int(x - box_size / 2) for x in min_loc) # Negative values of lower_left mean argmin ran out of unmasked pixels if lower_left[0] < 0 or lower_left[1] < 0: warn('Ran out of good pixels when placing RMS calculation regions ' 'for file {}. Only {:d} boxes selected.'.format(sci_data, box)) break min_slice = tuple(slice(x, x + box_size) for x in lower_left) box_slices += [min_slice] # Zone of avoidance (for center) is twice as big, since we are picking # box centers. Use clip to ensure avoidance slice stays within array # bounds lower_left = tuple(int(x - box_size) for x in min_loc) avoid_slice = tuple(slice(np.clip(x, 0, extent), np.clip(x + 2 * box_size, 0, extent)) for x, extent in zip(lower_left, img_boxcar.shape)) # Add this box to the mask img_boxcar[avoid_slice] = np.ma.masked return box_slices
def _detect(self,image): # Asssumes a two dimensional array A = None if isinstance(image,Image): A = image.asMatrix2D() elif isinstance(image,array) and len(image.shape)==2: A = image else: raise TypeError("ERROR Unknown Type (%s) - Only arrays and pyvision images supported."%type(image)) filter = array(self.filter) assert len(filter.shape) == 2 #feature window calculation del_A_1 = conv2(A,filter) del_A_2 = conv2(A,filter.transpose()) del_A_1_1 = del_A_1 * del_A_1 matrix_1_1 = gaussian_filter(del_A_1_1, self.sigma) del del_A_1_1 del_A_2_2 = del_A_2 * del_A_2 matrix_2_2 = gaussian_filter(del_A_2_2, self.sigma) del del_A_2_2 del_A_1_2 = del_A_1 * del_A_2 matrix_1_2 = gaussian_filter(del_A_1_2, self.sigma) del del_A_1_2 del del_A_1,del_A_2 dM = matrix_1_1*matrix_2_2 - matrix_1_2*matrix_1_2 tM = matrix_1_1+matrix_2_2 del matrix_1_1 , matrix_1_2, matrix_2_2 R = dM-self.k*pow(tM,2) footprint = ones((self.radius,self.radius)) mx = maximum_filter(R, footprint = footprint) local_maxima = (R == mx) * (R != zeros(R.shape)) # make sure to remove completly dark points del mx points = nonzero(local_maxima) del local_maxima points = array([points[0],points[1]]).transpose() L = [] for each in points: L.append((R[each[0],each[1]],each[0],each[1],None)) del R return L
def geodesic_dilation(marker,mask): """ Perform geodesic dilation based on algorithm on p. 185 of Soille (2002). """ # Compute the size for the filter based on the shape # of the marker array mshape = len(marker.shape) msize = (3,) * mshape marker_dilation = ndimage.maximum_filter(marker, size=msize) return np.where(mask <= marker_dilation, mask, marker_dilation)
def detect_peaks(img, include_plateaus=True): """ Takes an image and detect the peaks using the local maximum filter. Returns a boolean mask of the peaks (i.e. 1 when the pixel's value is the neighborhood maximum, 0 otherwise) Code taken from http://stackoverflow.com/a/3689710/932593 """ # define an 8-connected neighborhood neighborhood = ndimage.generate_binary_structure(2, 2) if include_plateaus: #apply the local maximum filter; all pixel of maximal value #in their neighborhood are set to 1 img_max = ndimage.maximum_filter(img, footprint=neighborhood) local_max = (img == img_max) #local_max is a mask that contains the peaks we are #looking for, but also the background. #In order to isolate the peaks we must remove the background from the mask. #we create the mask of the background background = (img == 0) #a little technicality: we must erode the background in order to #successfully subtract it form local_max, otherwise a line will #appear along the background border (artifact of the local maximum filter) eroded_background = ndimage.binary_erosion(background, structure=neighborhood, border_value=1) #we obtain the final mask, containing only peaks, #by removing the background from the local_max mask detected_peaks = local_max - eroded_background else: neighborhood[1, 1] = 0 img_max = ndimage.maximum_filter(img, footprint=neighborhood) detected_peaks = (img > img_max) return detected_peaks
def file_loop(f): print('Doing file: ' + f) dic = xr.open_dataset(f) res = [] outt = dic['t_lag0'].values outp = dic['p'].values for nb in range(5): boole = np.isnan(outp) outp[boole] = -1000 gg = np.gradient(outp) outp[boole] = np.nan outp[abs(gg[1]) > 300] = np.nan outp[abs(gg[0]) > 300] = np.nan gradi = np.gradient(outt) grad = gradi[1] maxoutt = (outt == ndimage.minimum_filter(outt, 20, mode='constant', cval=np.amin(outt) - 1)) maxoutt = maxoutt.astype(int) yt, xt = np.where((maxoutt == 1) & (outt < -50)) tstr = ['t'] * len(yt) maxoutp = (outp == ndimage.maximum_filter(outp, 20, mode='constant', cval=np.amax(outp) + 1)) maxoutp = maxoutp.astype(int) yp, xp = np.where((maxoutp == 1) & (outp > 10)) maxoutg = (grad == ndimage.minimum_filter(grad, 20, mode='constant', cval=np.amin(grad) - 1)) maxoutg = maxoutg.astype(int) yg, xg = np.where((maxoutg == 1) & (grad < -10)) gstr = ['g'] * len(yg) tstr.extend(gstr) tglist = tstr tgx = [xt, xg] tgx = [item for sublist in tgx for item in sublist] tgy = [yt, yg] tgy = [item for sublist in tgy for item in sublist] points = np.array(list(zip(tgy, tgx))) for point in zip(yp, xp): try: pos = ua.closest_point(point, points) except ValueError: continue if tglist[pos] == 't': res.append((tglist[pos], outt[tuple(points[pos])], outp[point])) if tglist[pos] == 'g': res.append((tglist[pos], grad[tuple(points[pos])], outp[point])) dic.close() return res
def canny(image, high_threshold, low_threshold): grad_x = sobel(image, 0) grad_y = sobel(image, 1) grad_mag = sqrt(grad_x**2+grad_y**2) grad_angle = arctan2(grad_y, grad_x) # next, scale the angles in the range [0, 3] and then round to quantize quantized_angle = around(3 * (grad_angle + pi) / (pi * 2)) NE = maximum_filter(grad_mag, footprint=_NE) W = maximum_filter(grad_mag, footprint=_W) NW = maximum_filter(grad_mag, footprint=_NW) N = maximum_filter(grad_mag, footprint=_N) thinned = (((grad_mag > W) & (quantized_angle == _N_d )) | ((grad_mag > N) & (quantized_angle == _W_d )) | ((grad_mag > NW) & (quantized_angle == _NE_d)) | ((grad_mag > NE) & (quantized_angle == _NW_d)) ) thinned_grad = thinned * grad_mag # Now, hysteresis thresholding: find seeds above a high threshold, then # expand out until we go below the low threshold high = thinned_grad > high_threshold low = thinned_grad > low_threshold canny_edges = binary_dilation(high, iterations=-1, mask=low) return grad_mag, thinned_grad, canny_edges
def build_part_with_score_fast(score_threshold, local_max_radius, scores): parts = [] num_keypoints = scores.shape[2] lmd = 2 * local_max_radius + 1 # NOTE it seems faster to iterate over the keypoints and perform maximum_filter # on each subarray vs doing the op on the full score array with size=(lmd, lmd, 1) for keypoint_id in range(num_keypoints): kp_scores = scores[:, :, keypoint_id].copy() kp_scores[kp_scores < score_threshold] = 0. max_vals = ndi.maximum_filter(kp_scores, size=lmd, mode='constant') max_loc = np.logical_and(kp_scores == max_vals, kp_scores > 0) max_loc_idx = max_loc.nonzero() for y, x in zip(*max_loc_idx): parts.append((scores[y, x, keypoint_id], keypoint_id, np.array((y, x)))) return parts
def test_indices_with_labels(self): image = np.random.uniform(size=(40, 60)) i, j = np.mgrid[0:40, 0:60] labels = 1 + (i >= 20) + (j >= 30) * 2 i, j = np.mgrid[-3:4, -3:4] footprint = (i * i + j * j <= 9) expected = np.zeros(image.shape, float) for imin, imax in ((0, 20), (20, 40)): for jmin, jmax in ((0, 30), (30, 60)): expected[imin:imax, jmin:jmax] = ndi.maximum_filter( image[imin:imax, jmin:jmax], footprint=footprint) expected = np.stack(np.nonzero(expected == image), axis=-1) expected = expected[np.argsort(image[tuple(expected.T)])[::-1]] result = peak.peak_local_max(image, labels=labels, min_distance=1, threshold_rel=0, footprint=footprint, exclude_border=False) result = result[np.argsort(image[tuple(result.T)])[::-1]] assert (result == expected).all()
def test_reorder_labels(self): image = np.random.uniform(size=(40, 60)) i, j = np.mgrid[0:40, 0:60] labels = 1 + (i >= 20) + (j >= 30) * 2 labels[labels == 4] = 5 i, j = np.mgrid[-3:4, -3:4] footprint = (i * i + j * j <= 9) expected = np.zeros(image.shape, float) for imin, imax in ((0, 20), (20, 40)): for jmin, jmax in ((0, 30), (30, 60)): expected[imin:imax, jmin:jmax] = ndi.maximum_filter( image[imin:imax, jmin:jmax], footprint=footprint) expected = (expected == image) with expected_warnings(["indices argument is deprecated"]): result = peak.peak_local_max(image, labels=labels, min_distance=1, threshold_rel=0, footprint=footprint, indices=False, exclude_border=False) assert (result == expected).all()
def normalize_spec(w, f, w0, f0, ferr0, \ medfilt_width = 10, maxfilt_width = 5, order = 4): # w, f : arrays used to define a continuum function # w0, f0, ferr0: target flux to be normalized # Median filter f_medfilt = ndimage.median_filter(f, size=medfilt_width) # Maximum filter f_maxfilt = ndimage.maximum_filter(f_medfilt, size=maxfilt_width) z = np.polyfit(w, f_maxfilt, order) p = np.poly1d(z) f_norm = f0 / p(w0) ferr_norm = ferr0 / p(w0) return (f_norm, ferr_norm)
def mask_post_processing(thresh_image, kernel_size=5, min_obj_size=100, max_dist=20): '''Post-process a thresholded mask to remove small objects and apply watershed. Keyword arguments: thresh image -- thresholded mask kernel_size -- size of the kernel to adopt for opening operation min_obj_size -- minimum are accepted, smaller objects are removed max_dist -- size parameter for ndimage.maximum_filter function Return: thresh_image -- post-processed mask (uint8) ''' # post-processing to remove holes and small objects kernel = np.ones((kernel_size, kernel_size), np.uint8) opening = cv2.morphologyEx(thresh_image, cv2.MORPH_OPEN, kernel) opening = opening.astype("bool") thresh_image = remove_small_objects(opening, min_size=min_obj_size, connectivity=1, in_place=False) # apply watershed to separate cells better distance = ndimage.distance_transform_edt(thresh_image) maxi = ndimage.maximum_filter(distance, size=max_dist, mode='constant') local_maxi = peak_local_max(maxi, indices=False, footprint=np.ones((3, 3)), labels=thresh_image) markers = ndimage.label(local_maxi)[0] thresh_image = watershed(-distance, markers, mask=thresh_image, watershed_line=True) thresh_image = thresh_image.astype("bool") thresh_image = remove_small_objects(thresh_image, min_size=20, connectivity=1, in_place=False) return (thresh_image.astype("uint8") * 255)
def grow_segmentation_map(seg_file='MACS1149-IR_drz_seg.fits', cat_file='MACS1149-IR.cat', size=30, mag=20): import scipy.ndimage as nd import pyregion import os #import stsci.convolve #seg_file='MACS1149-IR_drz_seg.fits'; cat_file='MACS1149-IR.cat'; size=30; mag=20.5 seg_im = pyfits.open(seg_file) seg = seg_im[0].data*1 cat = threedhst.catIO.Table(cat_file) ok = cat['MAG_APER'] < mag so = np.argsort(cat['MAG_APER'][ok]) idx = np.arange(len(cat))[ok][so] print 'Grow masks:' for i in idx: id = cat['NUMBER'][i] print '%5d (%.2f)' %(id, cat['MAG_APER'][i]) mask = (seg == id)*1 grow_mask = nd.maximum_filter(mask, size=size*2) #grow_mask = nd.convolve(mask, np.ones((size, size))) #grow_mask = stsci.convolve.convolve2d(mask, np.ones((size, size)), output=None, mode='nearest', cval=0.0, fft=1) seg[seg == 0] += grow_mask[seg == 0]*id reg_file = seg_file.replace('.fits', '_mask.reg') if os.path.exists(reg_file): print 'Region mask: %s' %(reg_file) reg = pyregion.open(reg_file).as_imagecoord(seg_im[0].header) N = len(reg) for i in range(N): if 'text=' not in reg[i].comment: continue id = int(reg[i].comment.strip('text={')[:-1]) print '%4d' %(id) mask = reg[i:i+1].get_mask(seg_im[0]) seg[seg == 0] += mask[seg == 0]*id pyfits.writeto(seg_file.replace('seg.fits','seg_grow.fits'), data=seg, header=seg_im[0].header, clobber=True) # End
def peak_local_max_wrap( image, min_distance=1, threshold_abs=None, threshold_rel=None, num_peaks=np.inf, ): """ adapted from skimage to support theta wrap """ if np.all(image == image.flat[0]): return np.empty((0, 2), np.int) # Non maximum filter # if footprint is not None: # image_max = ndi.maximum_filter(image, footprint=footprint, # mode='wrap') # else: # size = 2 * min_distance + 1 # image_max = ndi.maximum_filter(image, size=size, mode='wrap') # maximum filter with gaussian kernel ker = cv2.getGaussianKernel(U.rint(2 * min_distance + 1), sigma=2.0) ker = ker * ker.T image_max = ndi.maximum_filter(image, footprint=ker, mode='wrap') # alternatively, # size = 2 * min_distance + 1 # image_max = ndi.maximum_filter(image, size=size, mode='wrap') mask = image == image_max # find top peak candidates above a threshold thresholds = [] if threshold_abs is None: threshold_abs = image.min() thresholds.append(threshold_abs) if threshold_rel is not None: thresholds.append(threshold_rel * image.max()) if thresholds: mask &= image > max(thresholds) # Select highest intensities (num_peaks) coordinates = _get_high_intensity_peaks(image, mask, num_peaks) return coordinates
def getPPH(dfTors,method='daily',res=10): r""" Calculate PPH density from tornado dataframe Parameters ---------- dfTors : dataframe method : 'total' or 'daily' """ # set up ~80km grid over CONUS latgrid = np.arange(20,55,res/111) longrid = np.arange(-130,-65,res/111/np.cos(35*np.pi/180)) interval = int(80/res) disk = circle_filter(interval) dfTors['SPC_time'] = dfTors['UTC_time'] - timedelta(hours=12) dfTors = dfTors.set_index(['SPC_time']) groups = dfTors.groupby(pd.Grouper(freq="D")) aggregate_grid = [] for group in groups: slon,slat = group[1]['slon'].values,group[1]['slat'].values elon,elat = group[1]['elon'].values,group[1]['elat'].values torlons = [i for x1,x2 in zip(slon,elon) for i in np.linspace(x1,x2, 10)] torlats = [i for y1,y2 in zip(slat,elat) for i in np.linspace(y1,y2, 10)] # get grid count grid, _, _ = np.histogram2d(torlats,torlons, bins=[latgrid,longrid]) grid = (grid>0)*1.0 grid = maximum_filter(grid,footprint=disk) aggregate_grid.append(grid) if method == 'daily': grid = np.mean(aggregate_grid,axis=0) PPH = gfilt(grid,sigma=1.5*interval)*100 if method == 'total': grid = np.sum(aggregate_grid,axis=0) PPH = gfilt((grid>=1)*1.0,sigma=1.5*interval)*100 return PPH,.5*(longrid[:len(longrid)-1]+longrid[1:]),.5*(latgrid[:len(latgrid)-1]+latgrid[1:])
def nms(image,rad=3,thresh=0): image = copy.copy(image) roi = rad size = 2 * roi + 1 image_max = ndimage.maximum_filter(image, size=size, mode='constant') mask = (image == image_max) imin = image.min() image[np.logical_not(mask)] = imin # Optionally find peaks above some threshold image[:roi,:] = imin image[-roi:,:] = imin image[:, :roi] = imin image[:, -roi:] = imin image_t = (image > thresh) * 1 # get coordinates of peaks return np.transpose(image_t.nonzero())
def crFind(img, var, nsig=10., sigfrac=0.3): simg = img / var**0.5 deriv = ndimage.sobel(simg) deriv = ndimage.sobel(deriv) mean, std = clip(deriv[deriv != 0.]) crmask = numpy.where(abs(deriv) > 15 * std, 1, 0) return crmask thresh = nsig * var**0.5 n = 5 blkimg = img.repeat(n, 0).repeat(n, 1) deriv = ndimage.laplace(blkimg) * -1. deriv[deriv < 0] = 0. d = iT.resamp(deriv, n) m = numpy.where((d > thresh) & (img > thresh), 1, 0) bmap = ndimage.maximum_filter(m, 5) cond = (bmap == 1) & (d > thresh * sigfrac) & (img > thresh * sigfrac) m[cond] = 1 return m
def get_peak(hms): coords = {} for k in range(hms.shape[0]): hm = hms[k] mx = maximum_filter(hm, size=5) idx = zip(*np.where((mx == hm) * (hm > 0.1))) candidate_points = [] for (y, x) in idx: candidate_points.append([x, y, hm[y][x]]) if len(candidate_points) == 0: preds, maxvals = get_max_pred(hm[None, :]) candidate_points.append([preds[0, 0], preds[0, 1], maxvals[0, 0]]) candidate_points = np.array(candidate_points) candidate_points = candidate_points[np.lexsort(-candidate_points.T)] candidate_points = torch.Tensor(candidate_points) coords[k] = candidate_points return coords
def findKvecsAuto(self): maxFiltFFT = sciim.maximum_filter(self.rawImageFFT, size=10) locMaxMask = (self.rawImageFFT==maxFiltFFT) maxInds = np.argsort(self.rawImageFFT, axis=None) maxInds = maxInds[::-1] # find four nonzero k-vectors nMaxFound = 0 i = 0 kvecList = np.zeros((2,2)) while nMaxFound < 2: maxCoords = np.unravel_index(maxInds[i], self.rawImageFFT.shape) kvec = np.array([self.rawImageFreqs[0][maxCoords[0]], self.rawImageFreqs[1][maxCoords[1]]]) if locMaxMask[maxCoords]==1 and (kvec[0]**2+kvec[1]**2)>0.05: if nMaxFound == 0: kvecList[0] = kvec nMaxFound += 1 else: if np.abs(np.dot(kvecList[0], kvec)) < 0.05*np.linalg.norm(kvec)**2: kvecList[1] = kvec nMaxFound += 1 i += 1 xKvecInd = np.argmax(np.abs(kvecList[:,0])) yKvecInd = np.argmax(np.abs(kvecList[:,1])) assert xKvecInd!=yKvecInd, 'x and y kvecs are the same!' xKvec = kvecList[xKvecInd] yKvec = kvecList[yKvecInd] if xKvec[0]<0: xKvec *= -1 if yKvec[1]<0: yKvec *= -1 self.xKvec = xKvec self.yKvec = yKvec
def v2_chaos_orig(iso_img, n_levels=30): # GCOVR_EXCL_START # Disable code coverage for this function as it's not prod code """Reimplementation of the chaos metric. I didn't manage to get it to exactly match the original implementation. This one seems to have significantly better dynamic range - it often produces values like 0.6 when the original implementation rarely produces values below 0.95 Original implementation: https://github.com/alexandrovteam/ims-cpp/blob/dcc12b4c50dbfdcde3f765af85fb8b3bb5cd7ec3/ims/image_measures.cpp#L89 Old way: level-thresholding -> dilation -> erosion -> connected component count New way: "dilation" via maximum-filter -> "erosion" via minimum-filter -> level-thresholding -> connected component count """ # Local import of image_manip because numba isn't included in the Lithops Docker image # as it adds ~25MB. If this metric is ever used again, numba will need to be added to the image. # pylint: disable=import-outside-toplevel # Avoid pulling numba into lithops from sm.engine.annotation.image_manip import count_connected_components dilated = maximum_filter(iso_img, footprint=np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]])) # Old way: mode='nearest', new way: mode='constant' iso_img = minimum_filter(dilated, size=(3, 3), mode='nearest') if not iso_img.any(): # Old way - detect this case when the return value is exactly 1.0 return 0.0 # Old way: np.linspace(0, max_ints, n_levels) mask = np.empty(iso_img.shape, dtype='bool') thresholds = np.linspace(0, np.max(iso_img), n_levels) pixel_counts = np.ones(len(thresholds), 'i') component_counts = np.zeros(len(thresholds), 'i') for i, threshold in enumerate(thresholds): np.greater(iso_img, threshold, out=mask) if mask.any(): pixel_counts[i] = np.count_nonzero(mask) component_counts[i] = count_connected_components(mask) mean_count = 1 - np.mean(component_counts) / np.count_nonzero(iso_img) return mean_count
def extract_masked(image, linedesc, pad=5, expand=0, background=None): """Extract a subimage from the image using the line descriptor. A line descriptor consists of bounds and a mask.""" assert amin(image) >= 0 and amax(image) <= 1 if background is None or background=="min": background = amin(image) elif background =="max": background = amax(image) y0,x0,y1,x1 = [int(x) for x in [linedesc.bounds[0].start,linedesc.bounds[1].start, \ linedesc.bounds[0].stop,linedesc.bounds[1].stop]] if pad > 0: mask = pad_image(linedesc.mask, pad, cval=0) else: mask = linedesc.mask line = extract(image, y0 - pad, x0 - pad, y1 + pad, x1 + pad) if expand > 0: mask = ndi.maximum_filter(mask, (expand, expand)) line = where(mask, line, background) return line
def computeLocalMaxima(self, harrisImage): ''' Input: harrisImage -- numpy array containing the Harris score at each pixel. Output: destImage -- numpy array containing True/False at each pixel, depending on whether the pixel value is the local maxima in its 7x7 neighborhood. ''' destImage = np.zeros_like(harrisImage, np.bool) maxArr = ndimage.maximum_filter(harrisImage, size=7) for i in range(harrisImage.shape[0]): for j in range(harrisImage.shape[1]): destImage[i, j] = maxArr[i, j] == harrisImage[i, j] return destImage
def circMaxCFAR(self, diff, nGuard=5, nNoise=2): ''' Tries to highlight spots :param nGuard: radius in pixels of spot :param nNoise: width in pixels of ring where to collect noise beyond spot :returns: diff-filtered ''' # build circular footprint mask size = 2*(nGuard+nNoise)+1 mask = np.zeros((size, size), dtype=bool) v = np.arange(size)-size//2 xx, yy = np.meshgrid(v, v) dist2 = xx**2+yy**2 mask[dist2 > nGuard**2] = True mask[dist2 > (nGuard+nNoise)**2] = False # apply footprint filtered = ndimage.maximum_filter(diff, footprint=mask) return diff-filtered
def computeLocalMaxima(self, harrisImage): ''' Input: harrisImage -- numpy array containing the Harris score at each pixel. Output: destImage -- numpy array containing True/False at each pixel, depending on whether the pixel value is the local maxima in its 7x7 neighborhood. ''' destImage = np.zeros_like(harrisImage, np.bool) # TODO 2: Compute the local maxima image # TODO-BLOCK-BEGIN maxes = ndimage.maximum_filter(harrisImage, 7, mode='nearest') destImage = np.equal(harrisImage, maxes) # TODO-BLOCK-END return destImage
def computeLocalMaxima(self, harrisImage): ''' Input: harrisImage -- numpy array containing the Harris score at each pixel. Output: destImage -- numpy array containing True/False at each pixel, depending on whether the pixel value is the local maxima in its 7x7 neighborhood. ''' destImage = np.zeros_like(harrisImage, np.bool) # TODO 2: Compute the local maxima image # TODO-BLOCK-BEGIN local_max_array = maximum_filter(harrisImage, size = 7, mode = 'reflect') destImage = (harrisImage == local_max_array) # TODO-BLOCK-END return destImage
def get_maxima(image, size, threshold='mean'): """ Find local intensity maxima inside an image. There is no sub-pixel accuracy. Args: image (np.ndarray): a n-dimensional image size (int): the radius of the local region threshold (float or str): the maxima whose intensity is smaller than the threshold will be discarded. Return: np.ndarray: the coordinates of local intensity maxima, shape (dimension, n) """ maxima_img = ndimage.maximum_filter(image, size) == image if threshold == 'mean': maxima_img[image < image[image > 0].mean()] = 0 else: maxima_img[image < threshold] = 0 local_maxima = np.array(np.where(maxima_img > 0)) return local_maxima
def test_four_quadrants(self): image = np.random.uniform(size=(20, 30)) i, j = np.mgrid[0:20, 0:30] labels = 1 + (i >= 10) + (j >= 15) * 2 i, j = np.mgrid[-3:4, -3:4] footprint = (i * i + j * j <= 9) expected = np.zeros(image.shape, float) for imin, imax in ((0, 10), (10, 20)): for jmin, jmax in ((0, 15), (15, 30)): expected[imin:imax, jmin:jmax] = ndi.maximum_filter( image[imin:imax, jmin:jmax], footprint=footprint) expected = (expected == image) with expected_warnings(["indices argument is deprecated"]): result = peak.peak_local_max(image, labels=labels, footprint=footprint, min_distance=1, threshold_rel=0, indices=False, exclude_border=False) assert np.all(result == expected)
def computeLocalMaxima(self, harrisImage): ''' Input: harrisImage -- numpy array containing the Harris score at each pixel. Output: destImage -- numpy array containing True/False at each pixel, depending on whether the pixel value is the local maxima in its 7x7 neighborhood. ''' destImage = np.zeros_like(harrisImage, np.bool) # TODO 2: Compute the local maxima image # TODO-BLOCK-BEGIN # raise Exception("TODO in features.py not implemented") destImage = ndimage.maximum_filter(harrisImage, size=7) == harrisImage # TODO-BLOCK-END return destImage
def getCenterline(mask, smoothing): labels = measure.label(mask) # assume at least 1 CC assert( labels.max() != 0 ) # Find largest connected component bins = np.bincount(labels.flat)[1:] cc = labels == np.argmax(np.bincount(labels.flat)[1:])+1 filt = ndimage.maximum_filter(cc, size=smoothing) # Find skeletonized centerline # cc = morphology.binary_closing(cc) # cc = morphology.binary_erosion(cc) # cc = morphology.binary_dilation(cc) skeleton = skeletonize(filt, method='lee') # skeleton = medial_axis(cc) skeleton = thin(skeleton) return skeleton
def GapFil(input_tif, footprint, output_folder, method='max'): """ Gapfil a raster by filling with the minimum, maximum or median of nearby pixels. Parameters ---------- input_tif : str Raster to be filled. footprint : ndarray Boolean array describing the area in which to look for the filling value. output_folder : str Folder to store gapfilled map. method : str, optional Method to use for gapfilling, options are 'max', 'min' or 'median'. Default is 'max'. Returns ------- fh : str Location of the gapfilled map. """ driver, NDV, xsize, ysize, GeoT, Projection = GetGeoInfo(input_tif) population = OpenAsArray(input_tif, nan_values=True) if method == 'median': population_gaps = ndimage.median_filter(population, footprint=footprint) if method == 'max': population_gaps = ndimage.maximum_filter(population, footprint=footprint) if method == 'min': population_gaps = ndimage.minimum_filter(population, footprint=footprint) population[np.isnan(population)] = population_gaps[np.isnan(population)] fn = os.path.split(input_tif)[1].replace('.tif', '_gapfilled.tif') fh = os.path.join(output_folder, fn) CreateGeoTiff(fh, population, driver, NDV, xsize, ysize, GeoT, Projection) return fh
def detect_peaks(image, detection_area = 2): """ Takes an image and detects the peaks using a local maximum filter. Returns a boolean mask of the peaks (i.e. 1 when the pixel's value is a local maximum, 0 otherwise) Parameters ---------- image: 2D marray the data of one FITS image. detection_area: integer, optional optional argument. The local maxima are found in asquare neighborhood with size (2*detection_area+1)*(2*detection_area+1). Default value is detection_area = 2. Returns ------- detected_peaks: 2D array Numpy array with same size as the input image, with 1 at the image local maxima, 0 otherwise. """ # define an 8-connected neighborhood --> image dimensionality is 2 + there are 8 neighbors for a single pixel neighborhood = np.ones((1+2*detection_area,1+2*detection_area)) # apply the local maximum filter; all pixel of maximal value in their # neighborhood are set to 1 local_max = sn.maximum_filter(image, footprint=neighborhood)==image # local_max is a mask that contains the peaks we are looking for, but also # the background. In order to isolate the peaks we must remove the # background from the mask. We create the mask of the background background = (image==0) # a little technicality: we must erode the background in order to # successfully subtract it from local_max, otherwise a line will appear # along the background border (artifact of the local maximum filter) eroded_background = sn.binary_erosion(background, structure=neighborhood, border_value=1) # we obtain the final mask, containing only peaks, by removing the # background from the local_max mask detected_peaks = local_max - eroded_background return detected_peaks
def lidarCB(self, msg): ''' This callback is called everytime the laserscanner sends us data. This is about 40hz. The message received is a laserscan message ''' #Might want to consider checking what highlevel mux is sending and updating changing looking angle and acceptible distance # this is not implemented yet increment = msg.angle_increment middle = int((-msg.angle_min)/increment) #This is the index in ranges of the laser scan pointing forward start = middle - int(math.radians(self.LOOKING_RANGE)/increment) #index of the scan pointing Looking_Range to right end = middle + int(math.radians(self.LOOKING_RANGE)/increment) #index of the scan pointing Looking_Range to left ranges30 = msg.ranges[start:end] #Only look at ranges in our range #may want to consider making things that are at more of an angle farther away so if we are #kinds off to an angle of something we dont just stop but has not been added #remove any readings that are out of range ranges30 = filter(lambda x: x>msg.range_min and x<msg.range_max,ranges30) #using max filter FILTER_WIDTH = 5 ranges30 = sc.maximum_filter(ranges30,FILTER_WIDTH) ranges30 = ranges30[FILTER_WIDTH/2:-FILTER_WIDTH/2:FILTER_WIDTH/2] #DownSampling #Find the closest object closest = min(ranges30) #If TOO CLOSE STOP if closest < self.DANGER_DISTANCE: stop_msg = AckermannDriveStamped() stop_msg.drive.speed = 0.0 self.pub.publish(stop_msg) #IF CLOSEISH SLOW DOWN elif closest < self.CAUTION_DISTANCE: stop_msg = AckermannDriveStamped() stop_msg.drive.speed = self.SPEED*(closest-self.DANGER_DISTANCE)/(self.CAUTION_DISTANCE-self.DANGER_DISTANCE) stop_msg.drive.steering_angle = self.ANGLE self.pub.publish(stop_msg)
def detect_peaks(image): """Detect peaks in an image using a maximum filter""" #Set up 3x3 footprint for maximum filter footprint = np.ones((3, 3)) #Apply maximum filter: All pixel in the neighborhood are set #to the maximal value. Peaks are where image = maximum_filter(image) local_maximum = maximum_filter(image, footprint=footprint) == image #We have false detections, where the image is zero, we call it background. #Create the mask of the background background = (image == 0) #Erode background at the borders, otherwise we would miss eroded_background = binary_erosion(background, structure=footprint, border_value=1) #Remove the background from the local_maximum image detected_peaks = local_maximum - eroded_background return detected_peaks
def process(data, size=None): if data is None or size is None or "values" not in data: return data radius = int(size // 2) footprint = get_footprint(size)[np.newaxis] # put absolute minimum on no data pixels array = data["values"].copy() minimum = get_dtype_min(array.dtype) no_data_mask = array == data["no_data_value"] array[no_data_mask] = minimum # apply maximum filter filtered = ndimage.maximum_filter(array, footprint=footprint) # replace absolute minimum with original fillvalue filtered[(filtered == minimum) & no_data_mask] = data["no_data_value"] # cut out the result filtered = filtered[:, radius:-radius, radius:-radius] return {"values": filtered, "no_data_value": data["no_data_value"]}
def cell_max(values): r""" Find pairwise max of consecutive elements across all axes of an array. Parameters ---------- values : :class:`numpy.ndarray` An input array of :math:`n` dimensions, :math:`(m_0, m_1, \dots, m_{n-1})`. Returns ------- maxima : :class:`numpy.ndarray` An input array of :math:`n` dimensions, each with a length 1 less than the input array, :math:`(m_0 - 1, m_1 - 1, \dots, m_{n-1} - 1)`. """ maxima = maximum_filter(values, size=2, mode='constant') indices = (slice(1, None), ) * np.ndim(values) return maxima[indices]
def process(self, batch, request: BatchRequest): data = batch[self.array].data if self.threshold is None: data_min = np.min(data) data_med = np.median(data) threshold = (data_min + data_med) / 2 else: threshold = self.threshold voxel_size = batch[self.array].spec.voxel_size window_size = self.window_size / voxel_size window_size = (1,) * (len(data.shape) - len(window_size)) + window_size max_filter = maximum_filter(data, window_size) local_maxima = np.logical_and(max_filter == data, data > threshold) spec = batch[self.array].spec.copy() spec.dtype = bool batch.arrays[self.maxima] = Array(local_maxima, spec)
def find_all_thres_fast(data, thres, msep, find_segs=False): """ Fast version of find_all_thres. See :py:func:`find_all_thres`. """ wsize = tuple([2 * i + 1 for i in msep]) # window size is 2*seperation+1 # find local maxima mask mx = ndimage.maximum_filter(data, size=wsize, mode='constant') == data # find positive threshold mask pthres = np.ma.greater(data, thres) # peaks are bitwise and of maximum mask and threshold mask locations = np.transpose(np.nonzero(np.bitwise_and(pthres, mx))) locations = [tuple(i) for i in locations] if find_segs: seg_slices = [find_pseg_slice(data, l, thres) for l in locations] return locations, seg_slices else: return locations