def process(arg): # el = ndimage.generate_binary_structure(2,1) # eli = astype(np.int) im = np.zeros((64,64)) np.random.seed(2) x, y = (63*np.random.random((2,8))).astype(np.int) im[x,y] = np.arange(8) bigger_points = ndimage.grey_dilation(im, size=(5,5), structure=np.ones((5,5))) square = np.zeros((16,16)) square[4:-4, 4:-4] = 1 dist = ndimage.distance_transform_bf(square) dilate_dist = ndimage.grey_dilation(dist, size=(3,3), structure=np.ones((3,3))) plt.figure(figsize=(12.5,3)) plt.subplot(141) plt.imshow(im, interpolation='nearest', cmap=plt.cm.spectral) plt.axis('off') plt.subplot(142) plt.imshow(bigger_points, interpolation='nearest', cmap=plt.cm.spectral) plt.axis('off') plt.subplot(143) plt.imshow(dist, interpolation='nearest', cmap=plt.cm.spectral) plt.axis('off') plt.subplot(144) plt.imshow(dilate_dist, interpolation='nearest', cmap=plt.cm.spectral) plt.axis('off') plt.subplots_adjust(wspace=0, hspace=0.02, top=0.99, bottom=0.01, left=0.01, right=0.99) plt.show()
def save_variations(img_dir, dilation_size, ind, imgs, fl_flat, nosiy_fl_flat): img = face_recognition.load_image_file(imgs[ind]) fn = imgs[ind].split(".") # for getting them in directory for pix2pix # make sure the folders specified below exist fn = os.path.basename(imgs[ind]) # 1st variation: img with dots f1 = img_dir + "A/" + fn #fn[0] + "_fl." + fn[1] img[tuple(np.vstack((fl_flat[ind][:, 1], fl_flat[ind][:, 0])))] = [255, 0, 0] img[:, :, 0] = ndimage.grey_dilation(img[:, :, 0], size=(dilation_size, dilation_size)) # pretty creative and hacky: dilation over the red dots channel imsave(f1, img) # 2nd variation: black with dots f2 = img_dir + "B1/" + fn #fn[0] + "_b." + fn[1] a = np.zeros(img.shape[0:2]) a[tuple(np.vstack((fl_flat[ind][:, 1], fl_flat[ind][:, 0])))] = 1#[255, 0, 0] a = ndimage.grey_dilation(a, size=(dilation_size,dilation_size)) imsave(f2, a) # 3rd variation: black with noisy dots f3 = img_dir + "B2/" + fn #fn[0] + "_bn." + fn[1] a = np.zeros(img.shape[0:2]) a[tuple(np.vstack((nosiy_fl_flat[ind][:, 1].astype(int), nosiy_fl_flat[ind][:, 0].astype(int))))] = 1#[255, 0, 0] a = ndimage.grey_dilation(a, size=(dilation_size,dilation_size)) imsave(f3, a)
def rotate_image_and_return_optimisation_value(image, rotation_angle, mid_xsum=False, single_peak=True): if not mid_xsum: image_xsum = ndimage.gaussian_filter1d(get_xsum(image), sigma=1) if abs(rotation_angle) <= 0.000000001: rotated_image_xsum = ndimage.grey_dilation(get_xsum(image), structure=np.ones((8))) else: rotated_image_xsum = ndimage.grey_dilation(get_xsum(rotate(image, rotation_angle)), structure=np.ones((8))) else: im_shape = image.shape image_xsum = ndimage.gaussian_filter1d( get_xsum(image[:, (im_shape[1] / 2) - mid_xsum:(im_shape[1] / 2) + mid_xsum]), sigma=1) if abs(rotation_angle) <= 0.000000001: rotated_image_xsum = ndimage.grey_dilation( get_xsum(image[:, (im_shape[1] / 2) - mid_xsum:(im_shape[1] / 2) + mid_xsum]), structure=np.ones((8))) else: rotated_image_xsum = ndimage.grey_dilation(get_xsum( rotate(image[:, (im_shape[1] / 2) - mid_xsum:(im_shape[1] / 2) + mid_xsum], rotation_angle)), structure=np.ones((8))) if not single_peak: corr = Matcher(image_xsum, rotated_image_xsum) corr.convolve_signals_and_get_match_info() reference_peaks = get_peaks_from_xsum(corr.match[0]) reference_peaks = [x for x in reference_peaks if x[0] >= 1000] if reference_peaks == []: return None original_image_peak_value = np.mean([x[0] for x in reference_peaks]) reference_peaks = [x[1] for x in reference_peaks] rotation_image_peak_values =[corr.match[1][x] for x in reference_peaks] return np.mean(rotation_image_peak_values)/original_image_peak_value elif single_peak: return np.max(rotated_image_xsum)
def dilatation_example(): a = np.zeros((5, 5)) a[2, 2] = 1 a_3 = ndimage.binary_dilation(a, structure=np.ones( (3, 3))).astype(a.dtype) a_4 = ndimage.binary_dilation(a, structure=np.ones( (4, 4))).astype(a.dtype) plt.figure() show_images_and_hists([a * 255, a_3 * 255, a_4 * 255]) # Also work for grey values im = np.zeros((64, 64)) x, y = (63 * np.randomsimple_segmentation.random( (2, 8))).astype(np.int) im[x, y] = np.arange(8) bigger_points = ndimage.grey_dilation(im, size=(5, 5), structure=np.ones((5, 5))) smaller_points = ndimage.grey_erosion(im, size=(5, 5), structure=np.ones((5, 5))) plt.figure() show_images_and_hists([im, bigger_points, smaller_points]) square = np.zeros((16, 16)) square[4:-4, 4:-4] = 1 dist = ndimage.distance_transform_bf(square) dilate_dist = ndimage.grey_dilation(dist, size=(3, 3), \ structure=np.ones((3, 3))) erosed_dist = ndimage.grey_erosion(dist, size=(3, 3), \ structure=np.ones((3, 3))) plt.figure() show_images_and_hists([dist, dilate_dist, erosed_dist])
def rolling_ball_filter(data, ball_radius, spacing=None, top=False, **kwargs): """Rolling ball filter implemented with morphology operations This implenetation is very similar to that in ImageJ and uses a top hat transform with a ball shaped structuring element https://en.wikipedia.org/wiki/Top-hat_transform Parameters ---------- data : ndarray image data (assumed to be on a regular grid) ball_radius : float the radius of the ball to roll spacing : int or sequence the spacing of the image data top : bool whether to roll the ball on the top or bottom of the data kwargs : key word arguments these are passed to the ndimage morphological operations Returns ------- data_nb : ndarray data with background subtracted bg : ndarray background that was subtracted from the data """ ndim = data.ndim if spacing is None: spacing = np.ones_like(ndim) else: spacing = _normalize_sequence(spacing, ndim) radius = np.asarray(_normalize_sequence(ball_radius, ndim)) mesh = np.array( np.meshgrid( *[np.arange(-r, r + s, s) for r, s in zip(radius, spacing)], indexing="ij")) structure = 2 * np.sqrt(1 - ((mesh / radius.reshape(-1, *( (1, ) * ndim)))**2).sum(0)) structure[~np.isfinite(structure)] = 0 if not top: # ndi.white_tophat(y, structure=structure, output=background) background = ndi.grey_erosion(data, structure=structure, **kwargs) background = ndi.grey_dilation(background, structure=structure, **kwargs) else: # ndi.black_tophat(y, structure=structure, output=background) background = ndi.grey_dilation(data, structure=structure, **kwargs) background = ndi.grey_erosion(background, structure=structure, **kwargs) return data - background, background
def gradient(self): Type=self.getEdgeType() Size=self.image_temp.shape EdgeImage=np.zeros(Size) if (Type=='S'): EdgeImage=(ndimage.grey_dilation(self.image_temp,footprint=np.ones([3,3]))-ndimage.grey_erosion(self.image_temp,footprint=np.ones([3,3])))/2 if (Type=='I'): EdgeImage=(self.image_temp-ndimage.grey_erosion(self.image_temp,footprint=np.ones([3,3])))/2 if (Type=='E'): EdgeImage=(ndimage.grey_dilation(self.image_temp,footprint=np.ones([3,3]))-self.image_temp)/2 self.showView4(EdgeImage)
def rolling_ball_filter(data, ball_radius, spacing=None, top=False, **kwargs): """Rolling ball filter implemented with morphology operations This implenetation is very similar to that in ImageJ and uses a top hat transform with a ball shaped structuring element https://en.wikipedia.org/wiki/Top-hat_transform Parameters ---------- data : ndarray type uint8 image data (assumed to be on a regular grid) ball_radius : float the radius of the ball to roll spacing : int or sequence the spacing of the image data top : bool whether to roll the ball on the top or bottom of the data kwargs : key word arguments these are passed to the ndimage morphological operations Returns ------- data_nb : ndarray data with background subtracted as uint8 bg : ndarray background that was subtracted from the data """ data = data.astype(np.int16) ndim = data.ndim if spacing is None: spacing = _normalize_sequence(1, ndim) else: spacing = _normalize_sequence(spacing, ndim) radius = np.asarray(_normalize_sequence(ball_radius, ndim)) mesh = np.array(np.meshgrid(*[np.arange(-r, r + s, s) for r, s in zip(radius, spacing)], indexing="ij")) structure = 2 * np.sqrt(2 - ((mesh / radius.reshape(-1, *((1,) * ndim)))**2).sum(0)) structure[~np.isfinite(structure)] = 0 if not top: # ndi.white_tophat(y, structure=structure, output=background) background = ndi.grey_erosion(data, structure=structure, **kwargs) background = ndi.grey_dilation(background, structure=structure, **kwargs) else: # ndi.black_tophat(y, structure=structure, output=background) background = ndi.grey_dilation(data, structure=structure, **kwargs) background = ndi.grey_erosion(background, structure=structure, **kwargs) data_corr = data - background data_corr[data_corr<0] = 0 return data_corr.astype(np.uint8), background.astype(np.uint8)
def fan_structure(median=11): """function to analyse fan sub structure by setting non-fan pixels to 0 and histo-equalizing the remaining img with only fans. Also median-filtering is done to reduce noise.""" xcoords=[388, 449,497] ycoords =[142, 254, 118] x2 = [403,590] y2 = [286,254] x3 = [403,459] y3 = [286,375] x4 = [1372,1420] y4 = [610,680] x5 = [1372,1467] y5 = [610,590] x6 = [1321,1422] y6 = [612,750] x7 = [1321,1439] y7 = [612,585] fig = plt.figure() ax = fig.add_subplot(111) data = get_data('ESP_011931_0945') data = nd.grey_erosion(data,footprint=np.ones((3,3))) data = nd.grey_erosion(data,footprint=np.ones((3,3))) data = nd.grey_dilation(data,footprint=np.ones((3,3))) data = nd.grey_dilation(data,footprint=np.ones((3,3))) threshold=0.045 fans = data < threshold data = data*255/data.max() intfans = np.zeros(data.shape, dtype=np.uint16) intfans[fans] = np.round(data[fans]) filtered = nd.median_filter(intfans,median) equ = hist_equal(filtered) im = ax.imshow(equ,cmap = cm.spectral,aspect='equal') ax.set_title('Fans within fans in Ithaca, filtered, opened and hist-equalized') ax.set_xlabel('0.5 m/pixel') # fig.savefig('Fans_within_fans.png') # cb =plt.colorbar(im,shrink=0.75) # cb.set_label('I/F') plt.plot(xcoords[:-1],ycoords[:-1],[xcoords[0],xcoords[2]],[ycoords[0],ycoords[2]], color='white', hold=True, scalex=False,scaley=False) plt.plot(x2,y2,color='white',hold=True,scalex=False,scaley=False) plt.plot(x3,y3,color='white',hold=True,scalex=False,scaley=False) plt.plot(x4,y4,color='white',hold=True,scalex=False,scaley=False) plt.plot(x5,y5,color='white',hold=True,scalex=False,scaley=False) plt.plot(x6,y6,color='white',hold=True,scalex=False,scaley=False) plt.plot(x7,y7,color='white',hold=True,scalex=False,scaley=False) # plt.close(fig) plt.show()
def morph_dilation(input_image_raster, filter_size): ''' Morphological dilation of raster ''' ndim = 3 if input_image_raster.ndim == 2: input_image_raster = numpy.expand_dims(input_image_raster, axis=0) ndim = 2 if input_image_raster.ndim != 3: raise Exception("Input array has to be 3D") if ndim == 3: return ndimage.grey_dilation(input_image_raster, (1, filter_size, filter_size)) else: return ndimage.grey_dilation(input_image_raster, (1, filter_size, filter_size))[0]
def gray_dilation(): """ 灰度图的形态修改 :return: """ # 灰度值图像 im = np.zeros((64, 64)) np.random.seed(2) x, y = (63 * np.random.random((2, 8))).astype(np.int) im[x, y] = np.arange(8) # print_image_pixel(im) # 灰度膨胀 bigger_points = ndimage.grey_dilation(im, size=(5, 5), structure=np.ones((5, 5))) # print_image_pixel(bigger_points) square = np.zeros((16, 16)) square[4:-4, 4:-4] = 1 dist = ndimage.distance_transform_bf(square) dilate_dist = ndimage.grey_dilation(dist, size=(3, 3), structure=np.ones((3, 3))) images = [im, bigger_points, square, dist, dilate_dist] pil_image_demo.plt_images(images, 3) plt.figure(figsize=(12.5, 3)) plt.subplot(141) plt.imshow(im, interpolation='nearest') plt.axis('off') plt.subplot(142) plt.imshow(bigger_points, interpolation='nearest') plt.axis('off') plt.subplot(143) plt.imshow(dist, interpolation='nearest') plt.axis('off') plt.subplot(144) plt.imshow(dilate_dist, interpolation='nearest') plt.axis('off') plt.subplots_adjust(wspace=0, hspace=0.02, top=0.99, bottom=0.01, left=0.01, right=0.99) plt.show()
def ma_get_region_graph(seg, aff): # input: # output: N*3, (seg_id_1, seg_id_2, mean_aff) mpred = aff.mean(axis=0) # find boundary ws_eroded = grey_erosion(seg, footprint=SIX_CONNECTED) ws_dilated = grey_dilation(seg, footprint=SIX_CONNECTED) different = (ws_eroded != 0) & (ws_eroded != ws_dilated) id1 = ws_eroded[different] id2 = ws_dilated[different] id1id2pred = mpred[different] m = coo_matrix((id1id2pred, (id1, id2))) m.sum_duplicates() ma = coo_matrix((np.ones(len(id1)), (id1, id2))) ma.sum_duplicates() id1a, id2a = m.nonzero() mm = m.tocsr() mma = ma.tocsr() scores = mm[id1a, id2a] / mma[id1a, id2a] scores = scores.A1 order = np.argsort(np.max(scores) - scores) scores = scores[order] # already sorted: id1a < id2a id1a = id1a[order] id2a = id2a[order] rg_ma = np.vstack((id1a, id2a, scores)).transpose(1, 0) return rg_ma
def cal_attmap_np(attmap_prev, optflow): ''' Calculate Motion Flow based attention map input: attmap_prev: attention map of previous frame (stored in history) optflow: optical flow <prev_frame, cur_frame> return: attmap: Motion Flow based attention map for current frame ''' h, w = optflow.shape[:2] x, y = np.meshgrid(np.arange(w), np.arange(h)) new_x = np.rint(x + optflow[:, :, 0]).astype(dtype=np.int64) new_y = np.rint(y + optflow[:, :, 1]).astype(dtype=np.int64) # get valid x and valid y new_x = np.clip(new_x, 0, w - 1) new_y = np.clip(new_y, 0, h - 1) attmap = np.zeros((h, w)) attmap[new_y.flatten(), new_x.flatten()] = attmap_prev[y.flatten(), x.flatten()] # use the dilate operation to make attention area larger attmap = ndimage.grey_dilation(attmap, size=(10, 10)) return attmap
def edge_matrix(labels, connectivity=1): """Generate a COO matrix containing the coordinates of edge pixels. Parameters ---------- labels : array of int An array of labeled pixels (or voxels). connectivity : int in {1, ..., labels.ndim} The square connectivity for considering neighborhood. Returns ------- edges : sparse.coo_matrix A COO matrix where (i, j) indicate neighboring labels and the corresponding data element is the linear index of the edge pixel in the labels array. """ conn = ndi.generate_binary_structure(labels.ndim, connectivity) eroded = ndi.grey_erosion(labels, footprint=conn).ravel() dilated = ndi.grey_dilation(labels, footprint=conn).ravel() labels = labels.ravel() boundaries0 = np.flatnonzero(eroded != labels) boundaries1 = np.flatnonzero(dilated != labels) labels_small = np.concatenate((eroded[boundaries0], labels[boundaries1])) labels_large = np.concatenate((labels[boundaries0], dilated[boundaries1])) n = np.max(labels_large) + 1 data = np.concatenate((boundaries0, boundaries1)) sparse_graph = sparse.coo_matrix((data, (labels_small, labels_large)), dtype=np.int_, shape=(n, n)) return sparse_graph
def gen_data(xsize, ysize, nstars=3, starradius=10, brightness=2000): # 1) lots of stars, big # 2) lots of tiny stars # 3) few stars, big # 4) few stars, tiny footprint = ndimage.generate_binary_structure(2,1) ret = numpy.zeros((xsize, ysize)) for star in xrange(nstars): xcenter = random.randint(0, xsize-1) ycenter = random.randint(0, ysize-1) for x in xrange(xcenter-1, xcenter+2): for y in xrange(ycenter-1, ycenter+2): if x >= 0 and y >= 0 and x < xsize and y < ysize: ret[x,y] = brightness / 3 ret[xcenter, ycenter] = brightness for i in xrange(starradius): ret = ndimage.grey_dilation(ret, footprint=footprint) # add some cosmic rays (single points) for i in xrange(30): xcenter = random.randint(0, xsize-1) ycenter = random.randint(0, ysize-1) ret[xcenter, ycenter] = brightness return ret
def find_local_max(img, d_rad, threshold=1e-15): """ This is effectively a replacement for pkfnd in the matlab/IDL code. The output of this function is meant to be feed into :py:func:`~subpixel_centroid` The magic of numpy means this should work for any dimension data. :param img: an ndarray representing the data to find the local maxes :param d_rad: the radius of the dilation, the smallest possible spacing between local maximum :param threshold: optional, voxels < threshold are ignored. :rtype: (d,N) array of the local maximums. """ d_rad = int(d_rad) img = np.array(np.squeeze(img)) # knock out singleton dimensions img[img < threshold] = -np.inf # mask out pixels below threshold dim = img.ndim # get the dimension of data # make structuring element s = ndimage.generate_binary_structure(dim, 1) # scale it up to the desired size d_struct = ndimage.iterate_structure(s, int(d_rad)) dilated_img = ndimage.grey_dilation(img, footprint=d_struct, cval=0, mode='constant') # do the dilation # find the locations that are the local maximum # TODO clean this up local_max = np.where(np.exp(img - dilated_img) > (1 - 1e-15)) # the extra [::-1] is because matplotlib and ndimage disagree an xy vs yx return np.vstack(local_max[::-1])
def generator_val(Image_Name): while True: for name in Image_Name: name = name.decode('utf-8') #Getting each filename name filename_patch = folder_patch_val + name filename_mask = folder_mask_val + name.replace('patch', 'mask') #Opening each file img_patch = np.array(Image.open(filename_patch)) img_mask = np.array(Image.open(filename_mask)) if classes == 1: # We add one extra dimension to have a shape [size_x, size_y, 1] img_mask = np.expand_dims(img_mask, axis=2) else: # The shape must be [size_x, size_y, classes] img_mask = '' # Normalization of patches and masks img_patch = exposure.adjust_gamma(img_patch, gamma) #img_mask = gaussian(img_mask, sigma=1.5) #img_mask = dilation(img_mask) #img_mask = gaussian(img_mask, sigma=0.1, truncate=1/2) img_mask[:, :, 0] = ndimage.grey_dilation(img_mask[:, :, 0], footprint=filt) yield img_patch / 255.0, np.round(img_mask / 255)
def local_maxima(image, radius, separation, percentile=64): """Find local maxima whose brightness is above a given percentile.""" ndim = image.ndim # Compute a threshold based on percentile. not_black = image[np.nonzero(image)] if len(not_black) == 0: warnings.warn("Image is completely black.", UserWarning) return np.empty((0, ndim)) threshold = stats.scoreatpercentile(not_black, percentile) # The intersection of the image with its dilation gives local maxima. if not np.issubdtype(image.dtype, np.integer): raise TypeError("Perform dilation on exact (i.e., integer) data.") footprint = binary_mask(radius, ndim, separation) dilation = ndimage.grey_dilation(image, footprint=footprint, mode='constant') maxima = np.vstack(np.where((image == dilation) & (image > threshold))).T if not np.size(maxima) > 0: warnings.warn("Image contains no local maxima.", UserWarning) return np.empty((0, ndim)) # Do not accept peaks near the edges. shape = np.array(image.shape) margin = int(separation) // 2 near_edge = np.any((maxima < margin) | (maxima > (shape - margin)), 1) maxima = maxima[~near_edge] if not np.size(maxima) > 0: warnings.warn("All local maxima were in the margins.", UserWarning) # Return coords in as a numpy array shaped so it can be passed directly # to the DataFrame constructor. return maxima
def main(self, niifile, slicerange, labelinclude, labelexclude, labelrange, bottompx, strokepx): nii = nibabel.load(niifile) nii = nibabel.as_closest_canonical(nii) hdr = nii.get_header() img = nii.get_data() pngdir = self.tempdir('png') svgdir = self.tempdir('svg') svxdir = self.tempdir('svx') densdir = self.tempdir('svx/dens') # autodetect slicerange if not specified if slicerange == []: mask = applyMask(img, labelrange, labelinclude, labelexclude) select = numpy.flatnonzero(mask.max(axis=0).max(axis=1)) slicerange = [select[0], select[-1]] srange = range(slicerange[0], slicerange[1]) mask = img[:, srange, :] mask = applyMask(mask, labelrange, labelinclude, labelexclude).astype(float) if strokepx: if bottompx: bottompx = range(0, bottompx) if bottompx > 0 else range( mask.shape[1] + bottompx, mask.shape[1]) solidmask = mask[:, bottompx, :] mask = binaryContour(mask) if bottompx: mask[:, bottompx, :] = solidmask radius = strokepx * math.pi / 3 ball = ball3d(radius) - 1 mask = ndimage.grey_dilation(mask, structure=ball) mask = (mask * 255.999).astype(numpy.uint8) return FancyOutput(mask=mask, slicerange=slicerange)
def find_using_2d_distance(self, probs): '''Find seeds in each plane by distance transform :param probs: the probability volume ''' if (self.dimensionality != 2): print "Wrong dimensionality" return if (self.method != "DistanceTransform"): print "Wrong method" return offset = 0 seeds = [] for plane in probs.astype(np.float32): thresholded = plane < self.threshold distance = distance_transform_edt(thresholded) dilated = grey_dilation(distance, size=self.minimum_distance_xy) mask = (distance == dilated) & (distance >= self.distance_threshold) labels, count = label(mask) labels[labels != 0] += offset offset += count seeds.append(labels) return np.array(seeds)
def layer_mask(echo, gauss_size=(19, 19), med_size=(19, 19), dilate_size=(19, 19), slope_threshold=0.02, echo_threshold=-110): ''' Detect layers on an echogram. Returns a boolean array the same size as echo.data ''' def padded_diff(a): empty_row = np.zeros(a.shape[1]) + np.nan return np.vstack((empty_row, np.diff(a, axis=0))) old_threshold = echo.threshold echo.set_threshold([echo_threshold - 1, 0]) zerodata = np.copy(echo.data.data) zerodata[echo.data.mask] = min(echo.threshold) smoothed = ndi.gaussian_filter(zerodata, gauss_size) d1 = padded_diff(smoothed) d2 = padded_diff(d1) level = ((np.absolute(d1) < slope_threshold) & (d2 < 0) & (zerodata > echo_threshold) & (echo.data.mask == False)) level = ndi.grey_dilation(ndi.median_filter(level, med_size), size=dilate_size) level = np.ma.array(level, mask=echo.bad_data) echo.set_threshold(old_threshold) return level
def generate_trimap(alpha): trimap = np.copy(alpha) k_size = 5 trimap[np.where((ndimage.grey_dilation(alpha[:, :], size=(k_size, k_size)) - ndimage.grey_erosion(alpha[:, :], size=(k_size, k_size))) != 0)] = unknown_code return trimap
def get_bordershadow(bg_arr, colour, borderstate=BorderState()): """ Gets a border/shadow with the movement state [top, right, bottom, left]. Inset or outset is random. """ bs = borderstate.get_sample() outset = bs['outset'] width = bs['width'] position = bs['position'] # make a copy border_arr = bg_arr.copy() # re-colour border_arr[..., 0] = colour if outset: # dilate black (erode white) border_arr[..., 1] = ndimage.grey_dilation(border_arr[..., 1], size=(width, width)) border_arr = arr_scroll(border_arr, position[0], position[1]) # canvas = 255*n.ones(bg_arr.shape) # canvas = grey_blit(border_arr, canvas) # canvas = grey_blit(bg_arr, canvas) # pyplot.imshow(canvas[...,0], cmap=cm.Greys_r) # pyplot.show() return border_arr, bg_arr else: # erode black (dilate white) border_arr[..., 1] = ndimage.grey_erosion(border_arr[..., 1], size=(width, width)) return bg_arr, border_arr
def split_exclusions(image, labels, exclusions, dilation=0, connectivity=1, standard_seeds=False): """Ensure that no segment in 'labels' overlaps more than one exclusion.""" labels = labels.copy() cur_label = labels.max() dilated_exclusions = exclusions.copy() foot = generate_binary_structure(exclusions.ndim, connectivity) for i in range(dilation): dilated_exclusions = grey_dilation(exclusions, footprint=foot) hashed = labels * (exclusions.max() + 1) + exclusions hashed[exclusions == 0] = 0 violations = bincount(hashed.ravel()) > 1 violations[0] = False if sum(violations) != 0: offending_labels = labels[violations[hashed]] mask = zeros(labels.shape, dtype=bool) for offlabel in offending_labels: mask += labels == offlabel if standard_seeds: seeds = label(mask * (image == 0))[0] else: seeds = label(mask * dilated_exclusions)[0] seeds[seeds > 0] += cur_label labels[mask] = watershed(image, seeds, connectivity, mask)[mask] return labels
def img_processing(self): self.processed_image = ndimage.grey_dilation(self.processed_image, size=(self.d_kernel, self.d_kernel)) self.processed_image = ndimage.grey_erosion(self.processed_image, size=(self.e_kernel, self.e_kernel))
def multi_label_edge_detection(data): f = nd.generate_binary_structure(len(data.shape), 1) bound = (nd.grey_erosion(data,footprint=f) != nd.grey_dilation(data,footprint=f)) - \ (nd.binary_dilation(data.astype(np.bool)) - data.astype(np.bool)) # the unwanted thick bounds data=bound.astype(data.dtype) return data
def main(self,niifile,slicerange,labelinclude,labelexclude,labelrange,bottompx,strokepx): nii = nibabel.load(niifile) nii = nibabel.as_closest_canonical(nii) hdr = nii.get_header() img = nii.get_data() pngdir = self.tempdir('png') svgdir = self.tempdir('svg') svxdir = self.tempdir('svx') densdir = self.tempdir('svx/dens') # autodetect slicerange if not specified if slicerange == []: mask = applyMask(img,labelrange,labelinclude,labelexclude) select = numpy.flatnonzero(mask.max(axis=0).max(axis=1)) slicerange = [select[0],select[-1]] srange = range(slicerange[0],slicerange[1]) mask = img[:,srange,:] mask = applyMask(mask,labelrange,labelinclude,labelexclude).astype(float) if strokepx: if bottompx: bottompx = range(0,bottompx) if bottompx>0 else range(mask.shape[1]+bottompx,mask.shape[1]) solidmask = mask[:,bottompx,:] mask = binaryContour(mask) if bottompx: mask[:,bottompx,:] = solidmask radius = strokepx*math.pi/3 ball = ball3d(radius)-1 mask = ndimage.grey_dilation(mask,structure=ball) mask = (mask*255.999).astype(numpy.uint8) return FancyOutput( mask = mask, slicerange = slicerange )
def nonmaxsuppress1D(X, radius=1.5): from scipy.ndimage import grey_dilation footprint = np.ones((1, 1, 2 * int(radius) + 1)) # Small petrubation to avoid adjacent maxima of equal height. n = np.random.rand(*X.shape) * 1e-9 mask = (grey_dilation((X + n), footprint=footprint) == (X + n)) return mask
def coutour_plot(immagine, ax, levels=[], filter_flag=True): mappa = immagine.copy() (dx, dy) = mappa.shape N = dx * dy istogramma = np.zeros(N) istogramma = np.sort(np.reshape(mappa, N)) if not levels: levels = [ istogramma[int(0.2 * N)], istogramma[int(0.6 * N)], istogramma[int(0.8 * N)], istogramma[int(0.9 * N)], istogramma[int(0.95 * N)] ] footprint = np.matrix([[1, 1, 1], [1, 2, 1], [1, 1, 1]]) if filter_flag: mappa = ndimage.gaussian_filter(mappa, sigma=2) mappa = ndimage.grey_erosion(mappa, footprint=footprint) mappa = ndimage.grey_dilation(mappa, footprint=footprint) ax.imshow(mappa, cmap='inferno', alpha=0.5) CS = ax.contour(np.arange(dy), np.arange(dx), mappa, levels, cmap='inferno') ax.clabel(CS, inline=True, fontsize=10) return ax
def rotated_angle(binary_image): # remove noise dots binary_image = ndimage.grey_dilation(binary_image, size=(3,3)) dark_positions = np.where(binary_image == 0) def get_height_dev(angle): dist = dark_positions[1] * math.sin(angle) - dark_positions[0] * math.cos(angle) return np.std(dist) low = -math.pi/6 high = math.pi/6 best_guess = 0 best_guess_val = get_height_dev(best_guess) for magic in xrange(0,20): mid1 = (low*2 + high) / 3 mid2 = (low + high*2) / 3 width1 = get_height_dev(mid1) width2 = get_height_dev(mid2) if width1 < width2: high = mid2 else: low = mid1 best_guess_val, best_guess = min((best_guess_val, best_guess), (width1, mid1)) best_guess_val, best_guess = min((best_guess_val, best_guess), (width2, mid2)) return best_guess
def get_bordershadow(self, bg_arr, colour): """ Gets a border/shadow with the movement state [top, right, bottom, left]. Inset or outset is random. """ bs = self.borderstate.get_sample() outset = bs['outset'] width = bs['width'] position = bs['position'] # make a copy border_arr = bg_arr.copy() # re-colour border_arr[..., 0] = colour if outset: # dilate black (erode white) border_arr[..., 1] = ndimage.grey_dilation(border_arr[..., 1], size=(width, width)) border_arr = self.arr_scroll(border_arr, position[0], position[1]) return border_arr, bg_arr else: # erode black (dilate white) border_arr[..., 1] = ndimage.grey_erosion(border_arr[..., 1], size=(width, width)) return bg_arr, border_arr
def gen_attmaps(pred_filename, flow_filename, target_filename, inv=False): # read optflow with open(str(flow_filename), 'r') as f: header = np.fromfile(f, dtype=np.uint8, count=4) size = np.fromfile(f, dtype=np.int32, count=2) optflow = np.fromfile(f, dtype=np.float32) \ .reshape(config.cropped_height, config.cropped_width, 2)# .transpose(2,0,1) h, w = optflow.shape[:2] mask = cv2.imread(pred_filename, 0) mask = cv2.resize(mask, dsize=(1280, 1024)) # mask = mask[config.h_start:config.h_start + h, config.w_start:config.w_start + w] # mask = (mask > 0) * 255 x, y = np.meshgrid(np.arange(w), np.arange(h)) if inv == True: new_x = np.rint(x - optflow[:, :, 0]).astype(dtype=np.int64) new_y = np.rint(y - optflow[:, :, 1]).astype(dtype=np.int64) else: new_x = np.rint(x + optflow[:, :, 0]).astype(dtype=np.int64) new_y = np.rint(y + optflow[:, :, 1]).astype(dtype=np.int64) # new_x = new_x * ((new_x >= 0) & (new_x < w)) new_x = np.clip(new_x, 0, w - 1) # new_y = new_y * ((new_y >= 0) & (new_y < h)) new_y = np.clip(new_y, 0, h - 1) attmap = np.zeros((h, w)) attmap[new_y.flatten(), new_x.flatten()] = mask[y.flatten(), x.flatten()] attmap = ndimage.grey_dilation(attmap, size=(2, 2)) # save attention map cv2.imwrite(target_filename, attmap)
def grey_dilation(image, separation, percentile=64, margin=None, precise=True): """Find local maxima whose brightness is above a given percentile. Parameters ---------- image : ndarray The algorithm works fastest when image is of integer type. separation : number or tuple of numbers Minimum separation between maxima. See precise for more information. percentile : float in range of [0,100], optional Features must have a peak brighter than pixels in this percentile. This helps eliminate spurious peaks. Default 64. margin : integer or tuple of integers, optional Zone of exclusion at edges of image. Default is ``separation / 2``. precise : boolean, optional Determines whether there will be an extra filtering step (``drop_close``) discarding features that are too close. Degrades performance. Because of the square kernel used, too many features are returned when precise=False. Default True. See Also -------- drop_close : removes features that are too close to brighter features grey_dilation_legacy : local maxima finding routine used until trackpy v0.3 """ ndim = image.ndim separation = validate_tuple(separation, ndim) if margin is None: margin = tuple([int(s / 2) for s in separation]) # Compute a threshold based on percentile. threshold = percentile_threshold(image, percentile) if np.isnan(threshold): return np.empty((0, ndim)) # Find the largest box that fits inside the ellipse given by separation size = [int(2 * s / np.sqrt(ndim)) for s in separation] # The intersection of the image with its dilation gives local maxima. dilation = ndimage.grey_dilation(image, size, mode='constant') maxima = (image == dilation) & (image > threshold) if np.sum(maxima) == 0: return np.empty((0, ndim)) pos = np.vstack(np.where(maxima)).T # Do not accept peaks near the edges. shape = np.array(image.shape) near_edge = np.any((pos < margin) | (pos > (shape - margin - 1)), 1) pos = pos[~near_edge] if len(pos) == 0: return np.empty((0, ndim)) # Remove local maxima that are too close to each other if precise: pos = drop_close(pos, separation, image[maxima][~near_edge]) return pos
def selezione_blob(mappa, flag_limiti, limiti_base=[0, 0, 0, 0], limiti_picco=[0, 0, 0, 0], fattore_scala=0.8): mappa_view = mappa.copy() flag_while = 'n' while flag_while == 'n': if flag_limiti: limiti_base, limiti_picco = seleziona_cordinate_rettangolo( mappa_view) media_base = np.mean(mappa[limiti_base[0]:limiti_base[1], limiti_base[2]:limiti_base[3]]) base_std = np.std(mappa[limiti_base[0]:limiti_base[1], limiti_base[2]:limiti_base[3]]) ### selezione picco # taglio la mappa mappa = mappa[limiti_picco[0]:limiti_picco[1], limiti_picco[2]:limiti_picco[3]] (dx, dy) = mappa.shape N = dx * dy # filtraggio mappa = ndimage.gaussian_filter(mappa, sigma=1) footprint = np.matrix([[1, 1, 1], [1, 2, 1], [1, 1, 1]]) mappa = ndimage.grey_erosion(mappa, footprint=footprint) mappa = ndimage.grey_dilation(mappa, footprint=footprint) # analisi e selezione blob istogramma = np.sort(np.reshape(mappa, N)) mask = np.empty((dx, dy)) flag_mask = 'n' while flag_mask == 'n': #soglia = istogramma[int(fattore_scala*N)] soglia = media_base + fattore_scala * base_std mask = mappa > soglia labels, _ = ndimage.label(mask) fig, ax = plt.subplots(1, 2) plt.gcf().text( 0.5, 0.001, f' blob isolivello per {fattore_scala*100:.{2}f} [%] ', fontsize=14) coutour_plot(mappa, ax[0], levels=[soglia], filter_flag=False) ax[1].imshow(labels) cordinata_picco = RoiSelect.selectROI_point( fig, ax[1], titolo='Seleziona punto picco') try: media_picco = mappa[labels != labels[ cordinata_picco[1], cordinata_picco[0]]].mean() except: media_picco = np.mean(mappa) #while (flag_mask:= input(f"Vanno bene i livelli? (Enter y/n) : ... ").lower()) not in {"y", "n"}: pass flag_mask = 'y' if flag_mask == 'n': scale_livello = float( input("percentile del livello: ... ")) / 100 flag_while = 'y' #while (flag_while:= input(f"Va bene la zona compensazione? (Enter y/n) : ... ").lower()) not in {"y", "n"}: pass return media_base, media_picco
def imagePreProcessing(inputImage): # convert to grey scale and type uint8 inputImage = img_as_ubyte(color.rgb2grey(inputImage)) # dilatrion of radius 5 struct = ndimage.generate_binary_structure(2, 2) # return ndimage.binary_dilation(inputImage, structure=struct, iterations=5).astype(inputImage.dtype) return ndimage.grey_dilation(inputImage, structure=struct, iterations=5).astype(inputImage.dtype)
def generate_trimap(trimap,alpha): k_size = random.choice(trimap_kernel) dilate = ndimage.grey_dilation(alpha[:,:,0],size=(k_size,k_size)) erode = ndimage.grey_erosion(alpha[:,:,0],size=(k_size,k_size)) # trimap[np.where((ndimage.grey_dilation(alpha[:,:,0],size=(k_size,k_size)) - ndimage.grey_erosion(alpha[:,:,0],size=(k_size,k_size)))!=0)] = 128 trimap[np.where(dilate - erode>10)] = 128 return trimap
def multi_label_edge_detection(data): f = nd.generate_binary_structure(len(data.shape), 1) # the unwanted thick bounds bound = (nd.grey_erosion(data,footprint=f) != \ nd.grey_dilation(data,footprint=f)) - \ (nd.binary_dilation(data.astype(np.bool)) - data.astype(np.bool)) data = bound.astype(data.dtype) return data
def generate_trimap(trimap, alpha): k_size = random.choice(trimap_kernel) trimap[np.where( (ndimage.grey_dilation(alpha[:, :, 0], size=(k_size, k_size)) - ndimage.grey_erosion(alpha[:, :, 0], size=(k_size, k_size))) != 0)] = 127.5 return trimap
def fillMinima(img, nullval, boundaryval): """ Fill all local minima in the input img. The input array should be a numpy 2-d array. This function returns an array of the same shape and datatype, with the same contents, but with local minima filled using the reconstruction-by-erosion algorithm. """ (nrows, ncols) = img.shape dtype = img.dtype nullmask = (img == nullval) # Generate mask of no data values nonNullmask = numpy.logical_not(nullmask) # Convert it to a data mask # Find the minimum and maximum values in the data (hMax, hMin) = (int(img[nonNullmask].max()), int(img[nonNullmask].min())) # No longer need the nonNullmask del nonNullmask # Generate an internal image initialized with zeros img2 = numpy.zeros((nrows, ncols), dtype=dtype) # Fill it with the maximum value img2.fill(hMax) # If boundary was set to zero use the maximum value. if boundaryval == 0.0: boundaryval = hMax # If we have no_data(fill) values if nullmask.sum() > 0: # Use only the image boundaries nullmaskDilated = grey_dilation(nullmask, size=(3, 3)) innerBoundary = nullmaskDilated - nullmask (boundaryRows, boundaryCols) = numpy.where(innerBoundary) # No longer need the innerBoundary del innerBoundary else: # Use the entire data file img2[0, :] = img[0, :] img2[-1, :] = img[-1, :] img2[:, 0] = img[:, 0] img2[:, -1] = img[:, -1] (boundaryRows, boundaryCols) = numpy.where(img2 != hMax) varList = [ 'img', 'img2', 'hMin', 'hMax', 'nullmask', 'boundaryval', 'boundaryRows', 'boundaryCols' ] try: weave.inline(mainCcode, arg_names=varList, type_converters=weave.converters.blitz, compiler="gcc", support_code=supportCcode) except Exception, e: print("Error: WEAVE [%s]" % str(e)) raise e
def selectROI(matrice_immagine, titolo='Immagine', contour_plot_flag: bool = False): ''' input: ax --> axis su cui fare la selezione della roi output: (xi,yi,dx,dy) ''' (t_lim_inf, t_lim_sup) = set_cmap(matrice_immagine) _, ax = plt.subplots() if contour_plot_flag: alpha = 0.5 matrice_immagine = matrice_immagine.copy() (dx, dy) = matrice_immagine.shape N = dx * dy istogramma = np.zeros(N) istogramma = np.sort(np.reshape(matrice_immagine, N)) footprint = np.matrix([[1, 1, 1], [1, 2, 1], [1, 1, 1]]) levels = [ istogramma[int(0.2 * N)], istogramma[int(0.6 * N)], istogramma[int(0.8 * N)], istogramma[int(0.9 * N)], istogramma[int(0.95 * N)] ] matrice_immagine = ndimage.gaussian_filter(matrice_immagine, sigma=2) matrice_immagine = ndimage.grey_erosion(matrice_immagine, footprint=footprint) matrice_immagine = ndimage.grey_dilation(matrice_immagine, footprint=footprint) CS = ax.contour(np.arange(dy), np.arange(dx), matrice_immagine, levels, cmap='inferno') ax.clabel(CS, inline=True, fontsize=10) else: alpha = 1 ax.imshow(matrice_immagine, cmap='inferno', clim=[t_lim_inf, t_lim_sup], alpha=alpha) ax.set(title=titolo) __toggle_selector.RS = RectangleSelector( ax, __onselect, drawtype='box', useblit=True, button=[1, 3], # don't use middle button minspanx=5, minspany=5, spancoords='pixels', interactive=True) plt.connect('key_press_event', __toggle_selector) plt.show() return cordinate
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)
def multi_label_edge_detection(data): """Detect the edge in the image with multi-labels.""" f = nd.generate_binary_structure(len(data.shape), 1) # the unwanted thick bounds bound = (nd.grey_erosion(data, footprint=f) != nd.grey_dilation(data, footprint=f)) - ( nd.binary_dilation(data.astype(np.bool)) - data.astype(np.bool) ) data = bound.astype(data.dtype) return data
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 dilation(self): '''Dilate every region by an 8-connected in-plane structure''' struct = ndimage.generate_binary_structure(3,3) struct[0] = False struct[2] = False l = copy.copy(self) l.data = ndimage.grey_dilation(self.data, size=(3,3,3), footprint=struct).astype(self.data.dtype) return l
def outline_segments(self, mask_background=False): """ Outline the labeled segments. The "outlines" represent the pixels *just inside* the segments, leaving the background pixels unmodified. Parameters ---------- mask_background : bool, optional Set to `True` to mask the background pixels (labels = 0) in the returned image. This is useful for overplotting the segment outlines on an image. The default is `False`. Returns ------- boundaries : 2D `~numpy.ndarray` or `~numpy.ma.MaskedArray` An image with the same shape of the segmentation image containing only the outlines of the labeled segments. The pixel values in the outlines correspond to the labels in the segmentation image. If ``mask_background`` is `True`, then a `~numpy.ma.MaskedArray` is returned. Examples -------- >>> from photutils import SegmentationImage >>> segm = SegmentationImage([[0, 0, 0, 0, 0, 0], ... [0, 2, 2, 2, 2, 0], ... [0, 2, 2, 2, 2, 0], ... [0, 2, 2, 2, 2, 0], ... [0, 2, 2, 2, 2, 0], ... [0, 0, 0, 0, 0, 0]]) >>> segm.outline_segments() array([[0, 0, 0, 0, 0, 0], [0, 2, 2, 2, 2, 0], [0, 2, 0, 0, 2, 0], [0, 2, 0, 0, 2, 0], [0, 2, 2, 2, 2, 0], [0, 0, 0, 0, 0, 0]]) """ from scipy.ndimage import grey_erosion, grey_dilation # mode='constant' ensures outline is included on the image borders selem = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]]) eroded = grey_erosion(self.data, footprint=selem, mode='constant', cval=0.) dilated = grey_dilation(self.data, footprint=selem, mode='constant', cval=0.) outlines = ((dilated != eroded) & (self.data != 0)).astype(int) outlines *= self.data if mask_background: outlines = np.ma.masked_where(outlines == 0, outlines) return outlines
def find_local_max(img, d_rad, threshold=1e-15, inplace=False): """ This is effectively a replacement for pkfnd in the matlab/IDL code. The output of this function is meant to be feed into :py:func:`~subpixel_centroid` The magic of numpy means this should work for any dimension data. :param img: an ndarray representing the data to find the local maxes :param d_rad: the radius of the dilation, the smallest possible spacing between local maximum :param threshold: optional, voxels < threshold are ignored. :param inplace: If True, `img` is modified. :rtype: (d,N) array of the local maximums. """ d_rad = int(d_rad) # knock out singleton dimensions, # and prepare to change values in thresholding step. img = np.array(np.squeeze(img)) if not inplace: img = img.copy() # Otherwise we could mess up use of 'img' by subsequent code. img[img < threshold] = -np.inf # mask out pixels below threshold dim = img.ndim # get the dimension of data # make structuring element s = ndimage.generate_binary_structure(dim, 1) # scale it up to the desired size d_struct = ndimage.iterate_structure(s, int(d_rad)) dilated_img = ndimage.grey_dilation(img, footprint=d_struct, cval=0, mode='constant') # do the dilation # find the locations that are the local maximum # TODO clean this up maxima = np.vstack(np.where(np.exp(img - dilated_img) > (1 - 1e-15))).T count=0 while True: duplicates = KDTree(maxima, 30).query_pairs(d_rad) if len(duplicates) == 0: break count += len(duplicates) to_drop = [] for pair in duplicates: # Take the average position. # This is just a starting point, so we won't go into subpx precision here. merged = maxima[pair[0]] merged = maxima[[pair[0], pair[1]]].mean(0).astype(int) maxima[pair[0]] = merged # overwrite one to_drop.append(pair[1]) # queue other to be dropped maxima = np.delete(maxima, to_drop, 0) # the extra [::-1] is because matplotlib and ndimage disagree an xy vs yx. # Finally, there should be nothing within 'd_rad' of the edges of the image print '%i peaks were removed' %count return np.vstack(maxima).T[::-1]
def reconstruction_gray(self): Size=self.image_temp.shape Mark_temp=np.zeros(Size) Mark=np.zeros(Size) Mark[:,112]=self.image_temp[:,112] while ((not np.array_equal(Mark,Mark_temp))): Mark_temp=Mark Mark=ndimage.grey_dilation(Mark,footprint=np.ones([3,3])) logical=Mark >= self.image_temp Mark=Mark-Mark*logical+self.image_temp*logical self.showView4(Mark)
def fillMinima(img, nullval, boundaryval): """ Fill all local minima in the input img. The input array should be a numpy 2-d array. This function returns an array of the same shape and datatype, with the same contents, but with local minima filled using the reconstruction-by-erosion algorithm. """ (nrows, ncols) = img.shape dtype = img.dtype nullmask = (img == nullval) # Generate mask of no data values nonNullmask = numpy.logical_not(nullmask) # Convert it to a data mask # Find the minimum and maximum values in the data (hMax, hMin) = (int(img[nonNullmask].max()), int(img[nonNullmask].min())) # No longer need the nonNullmask del nonNullmask # Generate an internal image initialized with zeros img2 = numpy.zeros((nrows, ncols), dtype=dtype) # Fill it with the maximum value img2.fill(hMax) # If boundary was set to zero use the maximum value. if boundaryval == 0.0: boundaryval = hMax # If we have no_data(fill) values if nullmask.sum() > 0: # Use only the image boundaries nullmaskDilated = grey_dilation(nullmask, size=(3, 3)) innerBoundary = nullmaskDilated - nullmask (boundaryRows, boundaryCols) = numpy.where(innerBoundary) # No longer need the innerBoundary del innerBoundary else: # Use the entire data file img2[0, :] = img[0, :] img2[-1, :] = img[-1, :] img2[:, 0] = img[:, 0] img2[:, -1] = img[:, -1] (boundaryRows, boundaryCols) = numpy.where(img2 != hMax) varList = ['img', 'img2', 'hMin', 'hMax', 'nullmask', 'boundaryval', 'boundaryRows', 'boundaryCols'] try: weave.inline(mainCcode, arg_names=varList, type_converters=weave.converters.blitz, compiler="gcc", support_code=supportCcode) except Exception, e: print ("Error: WEAVE [%s]" % str(e)) raise e
def wiggle_room_precision_recall(pred, boundary, margin=2, connectivity=1): struct = nd.generate_binary_structure(boundary.ndim, connectivity) gtd = nd.binary_dilation(boundary, struct, margin) struct_m = nd.iterate_structure(struct, margin) pred_dil = nd.grey_dilation(pred, footprint=struct_m) missing = np.setdiff1d(np.unique(pred), np.unique(pred_dil)) for m in missing: pred_dil.ravel()[np.flatnonzero(pred==m)[0]] = m prec, _, ts = precision_recall_curve(gtd.ravel(), pred.ravel()) _, rec, _ = precision_recall_curve(boundary.ravel(), pred_dil.ravel()) return zip(ts, prec, rec)
def adaptivethreshold(self, image): '''Uses an adaptive threshold to change image to binary. This is done using the Adaptive Thresholding technique, begins by using Gaussian filtering to remove noise, follows by creating a binary image with Otsu's Method. Reference: https://en.wikipedia.org/wiki/Otsus_method''' # Image is thresholded, inverted, dilated, and has holes filled. thresh = threshold_adaptive(image, 41, offset=10) thresh = np.invert(thresh) thresh = ndimage.grey_dilation(thresh, size=(2,2)) return ndimage.binary_fill_holes(thresh)
def __call__(self, im, dpi): pad = self.pixels ny, nx, depth = im.shape new_im = np.empty([pad*2+ny, pad*2+nx, depth], dtype="d") alpha = new_im[:,:,3] alpha.fill(0) alpha[pad:-pad, pad:-pad] = im[:,:,-1] alpha2 = NI.grey_dilation(alpha, size=(self.pixels, self.pixels)) new_im[:,:,-1] = alpha2 new_im[:,:,:-1] = self.color offsetx, offsety = -pad, -pad return new_im, offsetx, offsety
def local_maxima(image, radius, separation, percentile=64): """Find local maxima whose brightness is above a given percentile.""" ndim = image.ndim # Compute a threshold based on percentile. not_black = image[np.nonzero(image)] if len(not_black) == 0: warnings.warn("Image is completely black.", UserWarning) return np.empty((0, ndim)) threshold = stats.scoreatpercentile(not_black, percentile) # The intersection of the image with its dilation gives local maxima. if not np.issubdtype(image.dtype, np.integer): raise TypeError("Perform dilation on exact (i.e., integer) data.") #footprint = binary_mask(radius, ndim, separation) s = ndimage.generate_binary_structure(ndim, 2) # scale it up to the desired size footprint = ndimage.iterate_structure(s, int(d_rad)) dilation = ndimage.grey_dilation(image, footprint=footprint, mode='constant') maxima = np.vstack(np.where((image == dilation) & (image > threshold))).T if not np.size(maxima) > 0: warnings.warn("Image contains no local maxima.", UserWarning) return np.empty((0, ndim)) # Flat peaks return multiple nearby maxima. Eliminate duplicates. while True: duplicates = cKDTree(maxima, 30).query_pairs(separation) if len(duplicates) == 0: break to_drop = [] for pair in duplicates: # Take the average position. # This is just a starting point, so we won't go into subpx precision here. merged = maxima[pair[0]] merged = maxima[[pair[0], pair[1]]].mean(0).astype(int) maxima[pair[0]] = merged # overwrite one to_drop.append(pair[1]) # queue other to be dropped maxima = np.delete(maxima, to_drop, 0) # Do not accept peaks near the edges. shape = np.array(image.shape) margin = int(separation) // 2 near_edge = np.any((maxima < margin) | (maxima > (shape - margin)), 1) maxima = maxima[~near_edge] if not np.size(maxima) > 0: warnings.warn("All local maxima were in the margins.", UserWarning) # Return coords in as a numpy array shaped so it can be passed directly # to the DataFrame constructor. return maxima
def dilate(im): """`scipy.ndimage.grey_dilation` with size set to 3 on each axis. Parameters ---------- im : np.ndarray, arbitrary type and shape. The input image. Returns ------- out : np.ndarray, same type and shape as `im` The dilated image. """ return nd.grey_dilation(im, size=[3] * im.ndim)
def iter_kernel(image, size=1): """ Yield position, kernel mask, and image for each pixel in the image. The kernel mask has a 2 at the center pixel and 1 around it. The actual width of the kernel is 2*size + 1. """ width = 2*size + 1 for (i, j), pixel in iter_pixels(image): mask = np.zeros(image.shape, dtype='int16') mask[i, j] = 1 mask = grey_dilation(mask, size=width) mask[i, j] = 2 subimage = image[bounded_slice((i, j), image.shape[:2], size=size)] yield (i, j), mask, subimage
def morphological_reconstruction(marker, mask, connectivity=1): """Perform morphological reconstruction of the marker into the mask. See the Matlab image processing toolbox documentation for details: http://www.mathworks.com/help/toolbox/images/f18-16264.html """ sel = generate_binary_structure(marker.ndim, connectivity) diff = True while diff: markernew = grey_dilation(marker, footprint=sel) markernew = minimum(markernew, mask) diff = (markernew-marker).max() > 0 marker = markernew return marker
def local_maxima(self, image, radius, separation, threshold): ndim = image.ndim threshold -= 1 # The intersection of the image with its dilation gives local maxima. if not np.issubdtype(image.dtype, np.integer): raise TypeError("Perform dilation on exact (i.e., integer) data.") #footprint = self.binary_mask(radius, ndim) s = ndimage.generate_binary_structure(ndim, 2) # scale it up to the desired size footprint = ndimage.iterate_structure(s, int(radius)) dilation = ndimage.grey_dilation(image, footprint=footprint, mode='constant') maxima = np.vstack(np.where((image == dilation) & (image > threshold))).T[:,::-1] if not np.size(maxima) > 0: #warnings.warn("Image contains no local maxima.", UserWarning) return np.empty((0, ndim)) # Flat peaks return multiple nearby maxima. Eliminate duplicates. if len(maxima) > 0: while True: duplicates = cKDTree(maxima, 30).query_pairs(separation) if len(duplicates) == 0: break to_drop = [] for pair in duplicates: # Take the average position. # This is just a starting point, so we won't go into subpx precision here. merged = maxima[pair[0]] merged = maxima[[pair[0], pair[1]]].mean(0).astype(int) maxima[pair[0]] = merged # overwrite one to_drop.append(pair[1]) # queue other to be dropped maxima = np.delete(maxima, to_drop, 0) # Do not accept peaks near the edges. shape = np.array(image.shape) margin = int(separation) // 2 near_edge = np.any((maxima < margin) | (maxima > (shape - margin)), 1) maxima = maxima[~near_edge] #if not np.size(maxima) > 0: #warnings.warn("All local maxima were in the margins.", UserWarning) x, y = maxima[:,0], maxima[:,1] max_val = image[x,y].reshape(len(maxima),1) peaks = np.concatenate((maxima,max_val), axis = 1) return peaks
def local_maxima(image, radius, separation, percentile=64): """Find local maxima whose brightness is above a given percentile.""" # Compute a threshold based on percentile. not_black = image[np.nonzero(image)] threshold = stats.scoreatpercentile(not_black, percentile) ndim = image.ndim # The intersection of the image with its dilation gives local maxima. if not np.issubdtype(image.dtype, np.integer): raise TypeError("Perform dilation on exact (i.e., integer) data.") footprint = binary_mask(radius, ndim, separation) dilation = ndimage.grey_dilation(image, footprint=footprint, mode='constant') maxima = np.where((image == dilation) & (image > threshold)) if not np.size(maxima) > 0: _warn_no_maxima() return np.empty((0, ndim)) # Flat peaks, for example, return multiple maxima. Eliminate them. maxima_map = np.zeros_like(image) maxima_map[maxima] = image[maxima] footprint = binary_mask(separation, ndim, separation) maxima_map = ndimage.generic_filter( maxima_map, nullify_secondary_maxima(), footprint=footprint, mode='constant') maxima = np.where(maxima_map > 0) # Do not accept peaks near the edges. margin = int(separation)//2 maxima_map[..., -margin:] = 0 maxima_map[..., :margin] = 0 if ndim > 1: maxima_map[..., -margin:, :] = 0 maxima_map[..., :margin, :] = 0 if ndim > 2: maxima_map[..., -margin:, :, :] = 0 maxima_map[..., :margin, :, :] = 0 if ndim > 3: raise NotImplementedError("I tap out beyond three dimensions.") # TODO Change if into loop using slice(None) as : maxima = np.where(maxima_map > 0) if not np.size(maxima) > 0: warnings.warn("Bad image! All maxima were in the margins.", UserWarning) # Return coords in as a numpy array shaped so it can be passed directly # to the DataFrame constructor. return np.vstack(maxima).T