Python scipy.ndimage.sobel() Examples
The following are 22
code examples of scipy.ndimage.sobel().
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
You may also want to check out all available functions/classes of the module
scipy.ndimage
, or try the search function
.
Example #1
Source File: jacobian.py From rasl with MIT License | 6 votes |
def image_gradient(image, horv): """apply a sobel filter to the image to approximate the gradient Parameters ---------- image : ndarray(h, v) image as an ndarray horv : string "h" or "v", direction of gradient. Returns ------- image_dir : ndarray(h, v) directional gradient magnitude at each pixel """ axis = 1 if horv == 'h' else 0 grad = ndi.sobel(image, axis, mode='constant', cval=np.nan) / 8.0 return np.nan_to_num(grad)
Example #2
Source File: test_ndimage.py From GraphicDesignPatternByPython with MIT License | 5 votes |
def test_sobel02(self): for type_ in self.types: array = numpy.array([[3, 2, 5, 1, 4], [5, 8, 3, 7, 1], [5, 6, 9, 3, 5]], type_) t = ndimage.correlate1d(array, [-1.0, 0.0, 1.0], 0) t = ndimage.correlate1d(t, [1.0, 2.0, 1.0], 1) output = numpy.zeros(array.shape, type_) ndimage.sobel(array, 0, output) assert_array_almost_equal(t, output)
Example #3
Source File: Edgedetect.py From PyRAT with Mozilla Public License 2.0 | 5 votes |
def sobel(*args, **kwargs): return Sobel(*args, **kwargs).run(**kwargs)
Example #4
Source File: Edgedetect.py From PyRAT with Mozilla Public License 2.0 | 5 votes |
def filter(self, array, *args, **kwargs): shp = array.shape array = array.reshape((np.prod(shp[0:-2]),) + shp[-2:]) # reshape to (nch, ny, nx) for k, arr in enumerate(np.abs(array)): # loop over channels dx = ndimage.sobel(arr, 0) # horizontal derivative dy = ndimage.sobel(arr, 1) # vertical derivative array[k, ...] = np.hypot(dx, dy) # magnitude array = array.reshape(shp) # back to original shape return array
Example #5
Source File: image_utils.py From visualqc with Apache License 2.0 | 5 votes |
def dwi_overlay_edges(slice_one, slice_two): """ Makes a composite image with edges from second image overlaid on first. It will be in colormapped (RGB format) already. """ if slice_one.shape != slice_two.shape: raise ValueError("slices' dimensions do not match: " " {} and {} ".format(slice_one.shape, slice_two.shape)) # simple filtering to remove noise, while supposedly keeping edges slice_two = medfilt2d(slice_two, kernel_size=cfg.median_filter_size) # extracting edges edges = med_filter(np.hypot(sobel(slice_two, axis=0, mode='constant'), sobel(slice_two, axis=1, mode='constant'))) edges_color_mapped = hot_cmap(edges, alpha=cfg.alpha_edge_overlay_alignment) composite = gray_cmap(slice_one, alpha=cfg.alpha_background_slice_alignment) composite[edges_color_mapped>0] = edges_color_mapped[edges_color_mapped>0] # mask_rgba = np.dstack([edges>0] * 4) # composite[mask_rgba] = edges_color_mapped[mask_rgba] return composite
Example #6
Source File: image_utils.py From visualqc with Apache License 2.0 | 5 votes |
def overlay_edges(slice_one, slice_two, sharper=True): """ Makes a composite image with edges from second image overlaid on first. It will be in colormapped (RGB format) already. """ if slice_one.shape != slice_two.shape: raise ValueError("slices' dimensions do not match: " " {} and {} ".format(slice_one.shape, slice_two.shape)) # simple filtering to remove noise, while supposedly keeping edges slice_two = medfilt2d(slice_two, kernel_size=cfg.median_filter_size) # extracting edges edges = np.hypot(sobel(slice_two, axis=0, mode='constant'), sobel(slice_two, axis=1, mode='constant')) # trying to remove weak edges if not sharper: # level of removal edges = med_filter(max_filter(min_filter(edges))) else: edges = min_filter(min_filter(max_filter(min_filter(edges)))) edges_color_mapped = hot_cmap(edges, alpha=cfg.alpha_edge_overlay_alignment) composite = gray_cmap(slice_one, alpha=cfg.alpha_background_slice_alignment) composite[edges_color_mapped>0] = edges_color_mapped[edges_color_mapped>0] # mask_rgba = np.dstack([edges>0] * 4) # composite[mask_rgba] = edges_color_mapped[mask_rgba] return composite
Example #7
Source File: test_filters.py From GraphicDesignPatternByPython with MIT License | 5 votes |
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))
Example #8
Source File: test_ndimage.py From GraphicDesignPatternByPython with MIT License | 5 votes |
def test_sobel04(self): for type_ in self.types: array = numpy.array([[3, 2, 5, 1, 4], [5, 8, 3, 7, 1], [5, 6, 9, 3, 5]], type_) t = ndimage.sobel(array, -1) output = ndimage.sobel(array, 1) assert_array_almost_equal(t, output)
Example #9
Source File: test_ndimage.py From GraphicDesignPatternByPython with MIT License | 5 votes |
def test_sobel03(self): for type_ in self.types: array = numpy.array([[3, 2, 5, 1, 4], [5, 8, 3, 7, 1], [5, 6, 9, 3, 5]], type_) t = ndimage.correlate1d(array, [-1.0, 0.0, 1.0], 1) t = ndimage.correlate1d(t, [1.0, 2.0, 1.0], 0) output = numpy.zeros(array.shape, type_) output = ndimage.sobel(array, 1) assert_array_almost_equal(t, output)
Example #10
Source File: test_ndimage.py From GraphicDesignPatternByPython with MIT License | 5 votes |
def test_sobel01(self): for type_ in self.types: array = numpy.array([[3, 2, 5, 1, 4], [5, 8, 3, 7, 1], [5, 6, 9, 3, 5]], type_) t = ndimage.correlate1d(array, [-1.0, 0.0, 1.0], 0) t = ndimage.correlate1d(t, [1.0, 2.0, 1.0], 1) output = ndimage.sobel(array, 0) assert_array_almost_equal(t, output)
Example #11
Source File: test_ndimage.py From Computable with MIT License | 5 votes |
def test_sobel04(self): for type in self.types: array = numpy.array([[3, 2, 5, 1, 4], [5, 8, 3, 7, 1], [5, 6, 9, 3, 5]], type) t = ndimage.sobel(array, -1) output = ndimage.sobel(array, 1) assert_array_almost_equal(t, output)
Example #12
Source File: test_ndimage.py From Computable with MIT License | 5 votes |
def test_sobel03(self): for type in self.types: array = numpy.array([[3, 2, 5, 1, 4], [5, 8, 3, 7, 1], [5, 6, 9, 3, 5]], type) t = ndimage.correlate1d(array, [-1.0, 0.0, 1.0], 1) t = ndimage.correlate1d(t, [1.0, 2.0, 1.0], 0) output = numpy.zeros(array.shape, type) output = ndimage.sobel(array, 1) assert_array_almost_equal(t, output)
Example #13
Source File: test_ndimage.py From Computable with MIT License | 5 votes |
def test_sobel02(self): for type in self.types: array = numpy.array([[3, 2, 5, 1, 4], [5, 8, 3, 7, 1], [5, 6, 9, 3, 5]], type) t = ndimage.correlate1d(array, [-1.0, 0.0, 1.0], 0) t = ndimage.correlate1d(t, [1.0, 2.0, 1.0], 1) output = numpy.zeros(array.shape, type) ndimage.sobel(array, 0, output) assert_array_almost_equal(t, output)
Example #14
Source File: test_ndimage.py From Computable with MIT License | 5 votes |
def test_sobel01(self): for type in self.types: array = numpy.array([[3, 2, 5, 1, 4], [5, 8, 3, 7, 1], [5, 6, 9, 3, 5]], type) t = ndimage.correlate1d(array, [-1.0, 0.0, 1.0], 0) t = ndimage.correlate1d(t, [1.0, 2.0, 1.0], 1) output = ndimage.sobel(array, 0) assert_array_almost_equal(t, output)
Example #15
Source File: preproc_utils.py From Kaggle-DSB with MIT License | 4 votes |
def get_segmented_lungs(image): #Creation of the markers as shown above: marker_internal, marker_external, marker_watershed = generate_markers(image) #Creation of the Sobel-Gradient sobel_filtered_dx = ndimage.sobel(image, 1) sobel_filtered_dy = ndimage.sobel(image, 0) sobel_gradient = np.hypot(sobel_filtered_dx, sobel_filtered_dy) sobel_gradient *= 255.0 / np.max(sobel_gradient) #Watershed algorithm watershed = morphology.watershed(sobel_gradient, marker_watershed) #Reducing the image created by the Watershed algorithm to its outline outline = ndimage.morphological_gradient(watershed, size=(3,3)) outline = outline.astype(bool) #Performing Black-Tophat Morphology for reinclusion #Creation of the disk-kernel and increasing its size a bit blackhat_struct = [[0, 0, 1, 1, 1, 0, 0], [0, 1, 1, 1, 1, 1, 0], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [0, 1, 1, 1, 1, 1, 0], [0, 0, 1, 1, 1, 0, 0]] #blackhat_struct = ndimage.iterate_structure(blackhat_struct, 8) blackhat_struct = ndimage.iterate_structure(blackhat_struct, 14) # <- retains more of the area, 12 works well. Changed to 14, 12 still excluded some parts. #Perform the Black-Hat outline += ndimage.black_tophat(outline, structure=blackhat_struct) #Use the internal marker and the Outline that was just created to generate the lungfilter lungfilter = np.bitwise_or(marker_internal, outline) #Close holes in the lungfilter #fill_holes is not used here, since in some slices the heart would be reincluded by accident lungfilter = ndimage.morphology.binary_closing(lungfilter, structure=np.ones((5,5)), iterations=3) #Apply the lungfilter (note the filtered areas being assigned threshold_min HU) segmented = np.where(lungfilter == 1, image, threshold_min*np.ones(image.shape)) #return segmented, lungfilter, outline, watershed, sobel_gradient, marker_internal, marker_external, marker_watershed return segmented
Example #16
Source File: dsbowl_utils.py From Kaggle-DSB with MIT License | 4 votes |
def get_segmented_lungs(image): #Creation of the markers as shown above: marker_internal, marker_external, marker_watershed = generate_markers(image) #Creation of the Sobel-Gradient sobel_filtered_dx = ndimage.sobel(image, 1) sobel_filtered_dy = ndimage.sobel(image, 0) sobel_gradient = np.hypot(sobel_filtered_dx, sobel_filtered_dy) sobel_gradient *= 255.0 / np.max(sobel_gradient) #Watershed algorithm watershed = morphology.watershed(sobel_gradient, marker_watershed) #Reducing the image created by the Watershed algorithm to its outline outline = ndimage.morphological_gradient(watershed, size=(3,3)) outline = outline.astype(bool) #Performing Black-Tophat Morphology for reinclusion #Creation of the disk-kernel and increasing its size a bit blackhat_struct = [[0, 0, 1, 1, 1, 0, 0], [0, 1, 1, 1, 1, 1, 0], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [0, 1, 1, 1, 1, 1, 0], [0, 0, 1, 1, 1, 0, 0]] #blackhat_struct = ndimage.iterate_structure(blackhat_struct, 8) blackhat_struct = ndimage.iterate_structure(blackhat_struct, 14) # <- retains more of the area, 12 works well. Changed to 14, 12 still excluded some parts. #Perform the Black-Hat outline += ndimage.black_tophat(outline, structure=blackhat_struct) #Use the internal marker and the Outline that was just created to generate the lungfilter lungfilter = np.bitwise_or(marker_internal, outline) #Close holes in the lungfilter #fill_holes is not used here, since in some slices the heart would be reincluded by accident lungfilter = ndimage.morphology.binary_closing(lungfilter, structure=np.ones((5,5)), iterations=3) #Apply the lungfilter (note the filtered areas being assigned threshold_min HU) segmented = np.where(lungfilter == 1, image, threshold_min*np.ones(image.shape)) #return segmented, lungfilter, outline, watershed, sobel_gradient, marker_internal, marker_external, marker_watershed return segmented
Example #17
Source File: LUNA_3d_merge_preproc.py From Kaggle-DSB with MIT License | 4 votes |
def get_segmented_lungs(image): #Creation of the markers as shown above: marker_internal, marker_external, marker_watershed = generate_markers(image) #Creation of the Sobel-Gradient sobel_filtered_dx = ndimage.sobel(image, 1) sobel_filtered_dy = ndimage.sobel(image, 0) sobel_gradient = np.hypot(sobel_filtered_dx, sobel_filtered_dy) sobel_gradient *= 255.0 / np.max(sobel_gradient) #Watershed algorithm watershed = morphology.watershed(sobel_gradient, marker_watershed) #Reducing the image created by the Watershed algorithm to its outline outline = ndimage.morphological_gradient(watershed, size=(3,3)) outline = outline.astype(bool) #Performing Black-Tophat Morphology for reinclusion #Creation of the disk-kernel and increasing its size a bit blackhat_struct = [[0, 0, 1, 1, 1, 0, 0], [0, 1, 1, 1, 1, 1, 0], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [0, 1, 1, 1, 1, 1, 0], [0, 0, 1, 1, 1, 0, 0]] #blackhat_struct = ndimage.iterate_structure(blackhat_struct, 8) blackhat_struct = ndimage.iterate_structure(blackhat_struct, 14) # <- retains more of the area, 12 works well. Changed to 14, 12 still excluded some parts. #Perform the Black-Hat outline += ndimage.black_tophat(outline, structure=blackhat_struct) #Use the internal marker and the Outline that was just created to generate the lungfilter lungfilter = np.bitwise_or(marker_internal, outline) #Close holes in the lungfilter #fill_holes is not used here, since in some slices the heart would be reincluded by accident lungfilter = ndimage.morphology.binary_closing(lungfilter, structure=np.ones((5,5)), iterations=3) #Apply the lungfilter (note the filtered areas being assigned threshold_min HU) segmented = np.where(lungfilter == 1, image, threshold_min*np.ones(image.shape)) #return segmented, lungfilter, outline, watershed, sobel_gradient, marker_internal, marker_external, marker_watershed return segmented
Example #18
Source File: seed.py From ffn with Apache License 2.0 | 4 votes |
def _init_coords(self): logging.info('peaks: starting') # Edge detection. edges = ndimage.generic_gradient_magnitude( self.canvas.image.astype(np.float32), ndimage.sobel) # Adaptive thresholding. sigma = 49.0 / 6.0 thresh_image = np.zeros(edges.shape, dtype=np.float32) ndimage.gaussian_filter(edges, sigma, output=thresh_image, mode='reflect') filt_edges = edges > thresh_image del edges, thresh_image # This prevents a border effect where the large amount of masked area # screws up the distance transform below. if (self.canvas.restrictor is not None and self.canvas.restrictor.mask is not None): filt_edges[self.canvas.restrictor.mask] = 1 logging.info('peaks: filtering done') dt = ndimage.distance_transform_edt(1 - filt_edges).astype(np.float32) logging.info('peaks: edt done') # Use a specifc seed for the noise so that results are reproducible # regardless of what happens before the policy is called. state = np.random.get_state() np.random.seed(42) idxs = skimage.feature.peak_local_max( dt + np.random.random(dt.shape) * 1e-4, indices=True, min_distance=3, threshold_abs=0, threshold_rel=0) np.random.set_state(state) # After skimage upgrade to 0.13.0 peak_local_max returns peaks in # descending order, versus ascending order previously. Sort ascending to # maintain historic behavior. idxs = np.array(sorted((z, y, x) for z, y, x in idxs)) logging.info('peaks: found %d local maxima', idxs.shape[0]) self.coords = idxs
Example #19
Source File: dsbowl_preprocess_2d.py From Kaggle-DSB with MIT License | 4 votes |
def get_segmented_lungs(image): #Creation of the markers as shown above: marker_internal, marker_external, marker_watershed = generate_markers(image) #Creation of the Sobel-Gradient sobel_filtered_dx = ndimage.sobel(image, 1) sobel_filtered_dy = ndimage.sobel(image, 0) sobel_gradient = np.hypot(sobel_filtered_dx, sobel_filtered_dy) sobel_gradient *= 255.0 / np.max(sobel_gradient) #Watershed algorithm watershed = morphology.watershed(sobel_gradient, marker_watershed) #Reducing the image created by the Watershed algorithm to its outline outline = ndimage.morphological_gradient(watershed, size=(3,3)) outline = outline.astype(bool) #Performing Black-Tophat Morphology for reinclusion #Creation of the disk-kernel and increasing its size a bit blackhat_struct = [[0, 0, 1, 1, 1, 0, 0], [0, 1, 1, 1, 1, 1, 0], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [0, 1, 1, 1, 1, 1, 0], [0, 0, 1, 1, 1, 0, 0]] #blackhat_struct = ndimage.iterate_structure(blackhat_struct, 8) blackhat_struct = ndimage.iterate_structure(blackhat_struct, 14) # <- retains more of the area, 12 works well. Changed to 14, 12 still excluded some parts. #Perform the Black-Hat outline += ndimage.black_tophat(outline, structure=blackhat_struct) #Use the internal marker and the Outline that was just created to generate the lungfilter lungfilter = np.bitwise_or(marker_internal, outline) #Close holes in the lungfilter #fill_holes is not used here, since in some slices the heart would be reincluded by accident lungfilter = ndimage.morphology.binary_closing(lungfilter, structure=np.ones((5,5)), iterations=3) #Apply the lungfilter (note the filtered areas being assigned threshold_min HU) segmented = np.where(lungfilter == 1, image, threshold_min*np.ones(image.shape)) #return segmented, lungfilter, outline, watershed, sobel_gradient, marker_internal, marker_external, marker_watershed return segmented
Example #20
Source File: dev_Image.py From NodeEditor with MIT License | 4 votes |
def run_FreeCAD_ImageT(self): from scipy import ndimage fn=self.getData('image') import matplotlib.image as mpimg img=mpimg.imread(fn) (sa,sb,sc)=img.shape red=0.005*(self.getData("red")+100) green=0.005*(self.getData("green")+100) blue=0.005*(self.getData("blue")+100) #blue=0 say("rgb",red,green,blue) # andere filtre #img = ndimage.sobel(img) #img = ndimage.laplace(img) im2=img[:,:,0]*red+img[:,:,1]*green+img[:,:,2]*blue im2=np.round(im2) if self.getData('invert'): im2 = 1- im2 #im2 = ndimage.sobel(im2) ss=int((self.getData('maskSize')+100)/20) say("ss",ss) if ss != 0: mode=self.getData('mode') say("mode",mode) if mode=='closing': im2=ndimage.grey_closing(im2, size=(ss,ss)) elif mode=='opening': im2=ndimage.grey_opening(im2, size=(ss,ss)) elif mode=='erosion': im2=ndimage.grey_erosion(im2, size=(ss,ss)) elif mode=='dilitation': im2=ndimage.grey_dilation(im2, footprint=np.ones((ss,ss))) else: say("NO MODE") nonzes=np.where(im2 == 0) pts = [FreeCAD.Vector(sb+-x,sa-y) for y,x in np.array(nonzes).swapaxes(0,1)] h=10 pts = [FreeCAD.Vector(sb+-x,sa-y,(red*img[y,x,0]+green*img[y,x,1]+blue*img[y,x,2])*h) for y,x in np.array(nonzes).swapaxes(0,1)] colors=[img[y,x] for y,x in np.array(nonzes).swapaxes(0,1)] say("len pts",len(pts)) self.setData("Points_out",pts)
Example #21
Source File: image.py From eht-imaging with GNU General Public License v3.0 | 4 votes |
def grad(self, gradtype='abs'): """Return the gradient image Args: gradtype (str): 'x','y',or 'abs' for the image gradient dimension Returns: Image : an image object containing the gradient image """ # Define the desired gradient function def gradim(imvec): if np.any(np.imag(imvec) != 0): return gradim(np.real(imvec)) + 1j * gradim(np.imag(imvec)) imarr = imvec.reshape(self.ydim, self.xdim) sx = ndi.sobel(imarr, axis=0, mode='constant') sy = ndi.sobel(imarr, axis=1, mode='constant') # TODO: are these in the right order?? if gradtype == 'x': gradarr = sx if gradtype == 'y': gradarr = sy else: gradarr = np.hypot(sx, sy) return gradarr # Find the gradient for the primary image gradarr = gradim(self.imvec) arglist, argdict = self.image_args() arglist[0] = gradarr outim = Image(*arglist, **argdict) # Find the gradient for all polarizations and copy over for pol in list(self._imdict.keys()): if pol == self.pol_prim: continue polvec = self._imdict[pol] if len(polvec): gradarr = gradim(polvec) outim.add_pol_image(gradarr, pol) # Find the spectral index gradients and copy over mflist_out = [] for mfvec in self._mflist: if len(mfvec): mfarr = gradim(mfvec) mfvec_out = mfarr.flatten() else: mfvec_out = np.array([]) mflist_out.append(mfvec_out) outim._mflist = mflist_out return outim
Example #22
Source File: seed.py From ffn with Apache License 2.0 | 4 votes |
def _init_coords(self): logging.info('2d peaks: starting') # Loop over 2d slices. for z in range(self.canvas.image.shape[0]): image_2d = (self.canvas.image[z, :, :]).astype(np.float32) # Edge detection. edges = ndimage.generic_gradient_magnitude( image_2d, ndimage.sobel) # Adaptive thresholding. sigma = 49.0 / 6.0 thresh_image = np.zeros(edges.shape, dtype=np.float32) ndimage.gaussian_filter(edges, sigma, output=thresh_image, mode='reflect') filt_edges = edges > thresh_image del edges, thresh_image # Prevent border effect if (self.canvas.restrictor is not None and self.canvas.restrictor.mask is not None): filt_edges[self.canvas.restrictor.mask[z, :, :]] = 1 # Distance transform dt = ndimage.distance_transform_edt(1 - filt_edges).astype(np.float32) # Use a specifc seed for the noise so that results are reproducible # regardless of what happens before the policy is called. state = np.random.get_state() np.random.seed(42) idxs = skimage.feature.peak_local_max( dt + np.random.random(dt.shape) * 1e-4, indices=True, min_distance=3, threshold_abs=0, threshold_rel=0) zs = np.full((idxs.shape[0], 1), z, dtype=np.int64) idxs = np.concatenate((zs, idxs), axis=1) np.random.set_state(state) # Update self.coords with indices found at this z index logging.info('2d peaks: found %d local maxima at z index %d', idxs.shape[0], z) self.coords = np.concatenate((self.coords, idxs)) if z != 0 else idxs self.coords = np.array( sorted([(z, y, x) for z, y, x in self.coords], reverse=self.sort_reverse)) logging.info('2d peaks: found %d total local maxima', self.coords.shape[0])