def analyse(im, scales=[4,10,14,40], verbose=True): try: mask = im > im.mean() except: im = im.matrix mask = im > im.mean() granulo = granulometry(mask, sizes=np.arange(2, 19, 4)) print 'granulo:', granulo plt.figure(figsize=(6, 2.2)) plt.subplot(121) plt.imshow(mask, cmap=plt.cm.gray, origin='lower') opened_less = ndimage.binary_opening(mask, structure=disk_structure(scales[0])) opened = ndimage.binary_opening(mask, structure=disk_structure(scales[1])) opened_more = ndimage.binary_opening(mask, structure=disk_structure(scales[2])) opened_even_more = ndimage.binary_opening(mask, structure=disk_structure(scales[3])) plt.contour(opened_less, [0.5], colors='g', linewidths=2) plt.contour(opened, [0.5], colors='b', linewidths=2) plt.contour(opened_more, [0.5], colors='r', linewidths=2) plt.contour(opened_even_more, [0.5], colors='k', linewidths=2) plt.axis('off') plt.subplot(122) plt.plot(np.arange(2, 19, 4), granulo, 'ok', ms=8) plt.subplots_adjust(wspace=0.02, hspace=0.15, top=0.95, bottom=0.15, left=0, right=0.95) if verbose: plt.show() return opened_less, opened, opened_more, opened_even_more
def open_isl(isls, crms): import pylab as pl import scipy.ndimage as nd import numpy as N thr = crms ft1 = N.array(((1,0,1), (0,1,0), (1,0,1)), int) ft2 = N.array(((0,1,0), (1,1,1), (0,1,0)), int) ft3 = N.ones((3,3), int) ft5 = N.ones((5,5), int) for isl in isls: ma = ~isl.mask_active open1 = nd.binary_opening(ma, ft1) open2 = nd.binary_opening(ma, ft2) open3 = nd.binary_opening(ma, ft3) open5 = nd.binary_opening(ma, ft5) pl.figure() pl.suptitle('Island '+str(isl.island_id)) pl.subplot(2,2,1); pl.imshow(N.transpose(isl.image), origin='lower', interpolation='nearest'); pl.title('Image') pl.subplot(2,2,2); pl.imshow(N.transpose(ma), origin='lower', interpolation='nearest'); pl.title('mask') pl.subplot(2,2,3); pl.imshow(N.transpose(open3), origin='lower', interpolation='nearest'); pl.title('open 3x3') pl.subplot(2,2,4); pl.imshow(N.transpose(open5), origin='lower', interpolation='nearest'); pl.title('open 5x5') #pl.subplot(2,2,3); pl.imshow(N.transpose(open1), origin='lower', interpolation='nearest'); pl.title('open diag') #pl.subplot(2,2,4); pl.imshow(N.transpose(open2), origin='lower', interpolation='nearest'); pl.title('open str') pl.savefig('cyga_p_w12_bigisl_'+str(isl.island_id)+'_open.png')
def testRegularizationSmallClamp(self): """Test that large variations between model planes are reduced. This also tests that noise-like pixels are not regularized. """ clampFrequency = 2 regularizationWidth = 2 fluxRange = 10. modelImages = self.makeTestImages(fluxRange=fluxRange) dcrModels = DcrModel(modelImages=modelImages, mask=self.mask, effectiveWavelength=self.effectiveWavelength, bandwidth=self.bandwidth) newModels = [model.clone() for model in dcrModels] templateImage = dcrModels.getReferenceImage(self.bbox) statsCtrl = self.prepareStats() dcrModels.regularizeModelFreq(newModels, self.bbox, statsCtrl, clampFrequency, regularizationWidth) for model, refModel in zip(newModels, dcrModels): # Make sure the test parameters do reduce the outliers self.assertGreater(np.max(refModel.array - templateImage), np.max(model.array - templateImage)) highThreshold = templateImage * clampFrequency highPix = model.array > highThreshold highPix = ndimage.binary_opening(highPix, iterations=regularizationWidth) self.assertFalse(np.all(highPix)) lowThreshold = templateImage / clampFrequency lowPix = model.array < lowThreshold lowPix = ndimage.binary_opening(lowPix, iterations=regularizationWidth) self.assertFalse(np.all(lowPix))
def testRegularizeModelIter(self): """Test that large amplitude changes between iterations are restricted. This also tests that noise-like pixels are not regularized. """ modelClampFactor = 2. regularizationWidth = 2 subfilter = 0 dcrModels = DcrModel(modelImages=self.makeTestImages(), effectiveWavelength=self.effectiveWavelength, bandwidth=self.bandwidth) oldModel = dcrModels[0] xSize, ySize = self.bbox.getDimensions() newModel = oldModel.clone() newModel.array[:] += self.rng.rand(ySize, xSize) * np.max( oldModel.array) newModelRef = newModel.clone() dcrModels.regularizeModelIter(subfilter, newModel, self.bbox, modelClampFactor, regularizationWidth) # Make sure the test parameters do reduce the outliers self.assertGreater(np.max(newModelRef.array), np.max(newModel.array - oldModel.array)) # Check that all of the outliers are clipped highThreshold = oldModel.array * modelClampFactor highPix = newModel.array > highThreshold highPix = ndimage.binary_opening(highPix, iterations=regularizationWidth) self.assertFalse(np.all(highPix)) lowThreshold = oldModel.array / modelClampFactor lowPix = newModel.array < lowThreshold lowPix = ndimage.binary_opening(lowPix, iterations=regularizationWidth) self.assertFalse(np.all(lowPix))
def post(img): img_post = img img_post = ndimage.binary_opening(img_post, structure=morphology.disk(2)).astype(np.int) img_post = ndimage.binary_closing(img_post, structure=morphology.disk(2)).astype(np.int) img_post = ndimage.binary_opening(img_post, structure=morphology.disk(1)).astype(np.int) img_post = ndimage.binary_closing(img_post, structure=morphology.disk(1)).astype(np.int) # Image.fromarray(255*img_post[:512,:512].astype('uint8')).save('postfig-morph.png') distance = ndimage.morphology.distance_transform_edt(img_post) smoothed_distance = ndimage.gaussian_filter(distance, sigma=1) local_maxi = peak_local_max(smoothed_distance, indices=False, footprint=morphology.disk(7), labels=img_post) # morphology.disk(10) markers = ndi.label(local_maxi)[0] # saving distance image with peaks # toplt = np.array(Image.fromarray(255*(smoothed_distance[:512,:512]/np.max(smoothed_distance[:512,:512]))).convert('RGB')) # buffedmaxi = ndimage.binary_dilation(local_maxi, structure=morphology.disk(2)).astype(np.int) # toplt[buffedmaxi[:512,:512]==1] = np.array([255,0,0]) # Image.fromarray(toplt).save('postfig-dist.png') img_post = watershed(-smoothed_distance, markers, mask=img_post) return img_post
def filter_change(image, kernelSize, iterations): (cols, rows) = image.shape positiveChange = np.zeros((rows, cols), dtype=np.uint8) negativeChange = np.zeros((rows, cols), dtype=np.uint8) noChange = np.zeros((rows, cols), dtype=np.uint8) for ii in range(int(cols)): for kk in range(int(rows)): if image[ii, kk] == 1: negativeChange[ii, kk] = 1 elif image[ii, kk] == 2: noChange = 1 elif image[ii, kk] == 3: positiveChange[ii, kk] = 1 image = None positiveChange = ndimage.binary_opening( positiveChange, iterations=iterations, structure=np.ones(kernelSize)).astype(np.uint8) negativeChange = ndimage.binary_opening( negativeChange, iterations=iterations, structure=np.ones(kernelSize)).astype(np.uint8) change = np.full((rows, cols), 2, dtype=np.uint8) for ii in range(int(cols)): for kk in range(int(rows)): if negativeChange[ii, kk] == 1: change[ii, kk] = 1 elif positiveChange[ii, kk] == 1: change[ii, kk] = 3 change *= noChange return change
def fraction_positive(bin_im, positive_im, erode=2, overlap_thresh=0.9, bin_name='nuclei', positive_name='tf'): """Compute fraction of objects in bin_im overlapping positive_im. The purpose of this function is to compute the fraction of nuclei that express a particular transcription factor. By providing the thresholded DAPI channel as `bin_im` and the thresholded TF channel as `positive_im`, this fraction can be computed. Parameters ---------- bin_im : 2D array of bool The image of objects being tested. positive_im : 2D array of bool The image of positive objects. erode : int, optional Radius of structuring element used to smooth input images. overlap_thresh : float, optional The minimum amount of overlap between an object in `bin_im` and the `positive_im` to consider that object "positive". bin_name : string, optional The name of the objects being tested. positive_name : string, optional The name of the property being measured. Returns ------- f : 1D array of float, shape (1,) The feature vector. name : list of string, length 1 The name of the feature. Examples -------- >>> bin_im = np.array([[1, 1, 0], ... [0, 0, 0], ... [1, 1, 1]], dtype=bool) >>> pos_im = np.array([[1, 0, 0], ... [0, 1, 1], ... [0, 1, 1]], dtype=bool) >>> f = fraction_positive(bin_im, pos_im, erode=0, overlap_thresh=0.6) >>> f[0] array([0.5]) >>> f[1][0] 'frac-nuclei-pos-tf-erode-0-thresh-0.60' """ selem = skmorph.disk(erode) if erode > 0: bin_im = nd.binary_opening(bin_im, selem) positive_im = nd.binary_opening(positive_im, selem) lab_im = nd.label(bin_im)[0].ravel() pos_im = positive_im.ravel().astype(int) counts = sparse.coo_matrix((np.ones(lab_im.size), (lab_im, pos_im))).todense() means = counts[:, 1] / np.sum(counts, axis=1) f = np.array([np.mean(means[1:] > overlap_thresh)]) name = ['frac-%s-pos-%s-erode-%i-thresh-%.2f' % (bin_name, positive_name, erode, overlap_thresh)] return f, name
def mesh_dist(image, threshold): newimage = np.zeros_like(image) # the follwing converts the zeros array newimage into a binary array newimage[image < threshold] = 0 newimage[image >= threshold] = 1 print "the binary image threshold is: " + str(threshold) # perform multiple image openings ndimage.binary_opening(newimage, structure=np.ones((3,3,3))).astype(np.int) # the following line consumes a lot of computation time@ newimage2_dist = ndimage.distance_transform_edt(newimage) return newimage2_dist
def destripe(image, min_lenght=20, hard_threshold = 0.4, soft_threshold = 0.2, only_mask=False): ''' Find and remove scan stripes by averaging neighbourhood lines Args: image: 2d numpy array min_lenght: only scars that are as long or longer than this value (in pixels) will be marked hard_threshold: the minimum difference of the value from the neighbouring upper and lower lines to be considered a defect. soft_threshold: values differing at least this much do not form defects themselves, but they are attached to defects obtained from the hard threshold if they touch one. only_mask: wheter returning just the mask (True) or also the corrected data (False, default). Returns: destriped 2d array ''' # Calculate line differences d1 = np.diff(image, axis=0) diff1 = np.empty(image.shape) diff1[-1] = d1[-1] diff1[:-1] = d1 d2 = np.diff(diff1, axis=0) diff2 = np.empty(image.shape) diff2[0] = d2[0] diff2[1:] = d2 # Normalize line differences diff = -2*(diff2 - diff2.mean())/(diff2.max()-diff2.min()) # Calculate masks for hard and soft thresholds m_hard = abs(diff) > hard_threshold m_soft = abs(diff) > soft_threshold # Opening (erosion+dilation) of the masks m_hard = ndimage.binary_opening(m_hard, structure=np.ones((1,min_lenght), dtype=bool)) m_soft = ndimage.binary_opening(m_soft, structure=np.ones((1,3*min_lenght), dtype=bool)) # Addition of hard and soft mask mask = ndimage.binary_opening(m_soft+m_hard, structure=np.ones((1,min_lenght), dtype=bool)) # Filter masked values image_masked = np.ma.array(image, mask = mask, fill_value=np.NaN) filt = ndimage.uniform_filter(image_masked.data, size=(3, 1)) if not only_mask: filtered = image*np.invert(mask) + filt*mask return filtered, mask
def fraction_positive(bin_im, positive_im, erode=2, overlap_thresh=0.9, bin_name='nuclei', positive_name='tf'): """Compute fraction of objects in bin_im overlapping positive_im. The purpose of this function is to compute the fraction of nuclei that express a particular transcription factor. By providing the thresholded DAPI channel as `bin_im` and the thresholded TF channel as `positive_im`, this fraction can be computed. Parameters ---------- bin_im : 2D array of bool The image of objects being tested. positive_im : 2D array of bool The image of positive objects. erode : int, optional Radius of structuring element used to smooth input images. overlap_thresh : float, optional The minimum amount of overlap between an object in `bin_im` and the `positive_im` to consider that object "positive". bin_name : string, optional The name of the objects being tested. positive_name : string, optional The name of the property being measured. Returns ------- f : 1D array of float, shape (1,) The feature vector. name : list of string, length 1 The name of the feature. """ selem = skmorph.disk(erode) if erode > 0: bin_im = nd.binary_opening(bin_im, selem) positive_im = nd.binary_opening(positive_im, selem) lab_im, n_objs = nd.label(bin_im) means = measure.regionprops(lab_im, intensity_image=positive_im.astype(np.float32)) means = np.array([prop.mean_intensity for prop in means], np.float32) f = np.array([np.mean(means > overlap_thresh)]) name = [ 'frac-%s-pos-%s-erode-%i-thresh-%.2f' % (bin_name, positive_name, erode, overlap_thresh) ] return f, name
def opennning_example(): """Opening: erosion + dilation:""" a = np.zeros((5, 5), dtype=np.uint8) a[1:4, 1:4] = 1 a[4, 4] = 1 # Opening removes small objects a_no_small = ndimage.binary_opening(a, structure=np.ones( (3, 3))).astype(np.uint8) # Opening can also smooth corners a_smooth_corners = ndimage.binary_opening(a).astype(np.uint8) plt.figure() show_images_and_hists( [a * 255, a_no_small * 255, a_smooth_corners * 255])
def detect_vortices(cloud, radius=70, showplots=False): """ Detects whether there are vortex-like features within a given radius of the peak density in the TOF image of an expanded BEC """ OD = cloud.get_OD() peak_coord = cloud.results['peak coordinates'] center_region = ROI(center=peak_coord, size=(1.5 * radius, 1.5 * radius)).slices smooth_cloud = ndi.median_filter(OD[center_region], size=4) minOD = smooth_cloud.min() maxOD = smooth_cloud.max() cloud_median = ndi.median_filter(smooth_cloud, size=10) belowthresh = where(smooth_cloud < cloud_median * 0.75, 1, 0) opened = ndi.binary_opening(belowthresh, iterations=1) closed = ndi.binary_closing(opened, iterations=1) vort_found = ndi.label(closed)[1] cloud.results['vort_found'] = vort_found if showplots == True: fig = plt.figure(1999) fig.add_subplot(221, xticks=[], yticks=[]) plt.imshow(smooth_cloud, interpolation='nearest', vmin=minOD, vmax=maxOD) fig.add_subplot(222, xticks=[], yticks=[]) plt.imshow(cloud_median, interpolation='nearest', vmin=minOD, vmax=maxOD) fig.add_subplot(223, xticks=[], yticks=[]) plt.imshow(closed, interpolation='nearest', cmap=plt.cm.get_cmap('binary')) fig.add_subplot(224, xticks=[], yticks=[]) plt.imshow(belowthresh, interpolation='nearest', cmap=plt.cm.get_cmap('binary')) return vort_found
def get_difference_spots(pix): bpix = pix > 20 bpix = ndimage.binary_opening(bpix) bpix = ndimage.binary_closing(bpix) labels, n = ndimage.measurements.label(bpix) clicks = ndimage.measurements.center_of_mass(pix, labels, range(1, n+1)) return clicks
def artifact_mask(imdata, airdata, distance): """Computes a mask of artifacts found in the air region""" import nibabel as nb if not np.issubdtype(airdata.dtype, np.integer): airdata[airdata < .95] = 0 airdata[airdata > 0.] = 1 bg_img = imdata * airdata # Find the background threshold (the most frequently occurring value # excluding 0) # CHANGED - to the 75 percentile bg_threshold = np.percentile(bg_img[airdata > 0], 75) # Apply this threshold to the background voxels to identify voxels # contributing artifacts. qi1_img = np.zeros_like(bg_img) qi1_img[bg_img > bg_threshold] = 1 qi1_img[distance < .10] = 0 # Create a structural element to be used in an opening operation. struc = nd.generate_binary_structure(3, 1) qi1_img = nd.binary_opening(qi1_img, struc).astype(np.uint8) qi1_img[airdata <= 0] = 0 return qi1_img
def estimateThreshold(self, data, subscriber): interest = numpy.zeros(data.shape, dtype=float) maxi = float(data.shape[0]) for i, d in enumerate(data): small = ndimage.affine_transform( d, [self.medianZoom, self.medianZoom], output_shape=[ d.shape[0] / self.medianZoom, d.shape[1] / self.medianZoom ]) smallMedian = ndimage.median_filter(small, size=self.medianSize) median = ndimage.affine_transform( smallMedian, [1.0 / self.medianZoom, 1.0 / self.medianZoom], output_shape=d.shape, mode='nearest') interest[i] = median - d subscriber %= int(float(i + 1) / maxi * 70.0) hist = numpy.histogram(interest, range=(-255.0, 255.0), bins=511) width = numpy.sqrt(numpy.abs((hist[1][:-1] ** 2 * hist[0]).sum() \ / hist[0].sum())) self.threshold = self.significance * width self.binary = interest > self.threshold for i, b in enumerate(self.binary): self.binary[i] = ndimage.binary_fill_holes(b) self.binary[i] = ndimage.binary_opening(self.binary[i], iterations=1) subscriber %= 80
def image2pixelarray(filepath): """ Parameters ---------- filepath : str Path to an image file Returns ------- list A list of lists which make it simple to access the greyscale value by im[y][x] """ im = Image.open(filepath).convert('L') (width, height) = im.size greyscale_map = list(im.getdata()) greyscale_map = numpy.array(greyscale_map) greyscale_map = greyscale_map.reshape((height, width)) greyscale_map = np.where(greyscale_map > 200, 0, 255) greyscale_map = ndimage.binary_opening(greyscale_map) greyscale_map = ndimage.binary_closing(greyscale_map) greyscale_map = ndimage.binary_fill_holes(greyscale_map) return greyscale_map
def binaryOpening(binarydata, structure=None, iterations=3): ''' Opening [R52] is a mathematical morphology operation [R53] that consists in the succession of an erosion and a dilation of the input with the same structuring element. Opening therefore removes objects smaller than the structuring element. Together with closing (binary_closing), opening can be used for noise removal. ''' result = np.empty_like(binarydata) if structure is None: ndimage.binary_opening(binarydata, iterations=iterations, output=result) else: ndimage.binary_opening(binarydata, structure, iterations=iterations, output=result) return result
def check_ion_fullveiw(self, image): image1 = np.full(400 * 400, 0).reshape(400, 400) for i in range(400): for j in range(400): image1[i, j] = image[i + 300, j + 300] image = image1 im = ndimage.gaussian_filter(image, sigma=1) # 平滑 binary_image = im > im.mean() + 8 * im.std() # 二值化 close_img = ndimage.binary_closing( ndimage.binary_opening(binary_image).astype( np.int)) # 去除过小的闭合区域,并圆滑边缘(降低粘连) label_im, num_labels = ndimage.label(close_img) # 标记闭合区域 if num_labels == 0: positions = [200, 200] else: positions = np.average( ndimage.center_of_mass(im, label_im, [i + 1 for i in range(num_labels)]), 0) # 多离子时取离子平均位置 ion_number = num_labels positions[0] += 300 positions[1] += 300 #print(image.shape,close_img.shape) return ion_number, positions, close_img
def get_vert_lines(im): edges = cv2.Sobel(im, ddepth=cv2.CV_64F, dx=1, dy=0, ksize=5) edges[edges < 0] = 0 edges = (255 * (edges / np.max(edges))).astype(np.uint8) edges[edges < 50] = 0 edges[edges != 0] = 255 structure = np.ones((11,1)) edges = nd.binary_closing(edges, structure=structure) structure = np.ones((41,1)) edges = nd.binary_opening(edges, structure=structure) edges = (255 * edges).astype(np.uint8) proj = np.mean(edges, axis=0, dtype=np.float32) proj = np.squeeze(cv2.bilateralFilter(proj[np.newaxis,:], 9, 20, 20)) vert_lines = list() while True: idx = np.argmax(proj) if proj[idx] < 15: break vert_lines.append((idx, proj[idx])) proj[max(0, idx - 50):min(idx + 50, proj.shape[0])] = 0 out = list() for idx, val in vert_lines: if len(vert_lines) > 3 or val > 25: out.append(idx) return out
def findNeuron(bgImage, threshold, xNeuron, yNeuron): """find bright object in small roi image.""" mask = np.where(bgImage > threshold[0], 1, 0) mask = ndimage.binary_opening(mask,structure = np.ones((2,2))) mask = ndimage.binary_closing(mask) # --- Individually label all connected regions and get their center of mass label_im, nb_labels = ndimage.label(mask) centroids = ndimage.measurements.center_of_mass(bgImage, label_im, xrange(1,nb_labels+1)) # --- select brightest object by default (mean brightness) meanBrightness = ndimage.measurements.mean(bgImage, label_im, xrange(1,nb_labels+1)) # # --- Calculate the distance of each new cms to the old neuron position # # --- and select the new neuron position to be the object closest to # # --- the old location # dist = [] # for coords in centroids: # dist.append((coords[0]-yNeuron)**2 + (coords[1]-xNeuron)**2) # if len(dist)==0: # yNewNeuron,xNewNeuron = yNeuron, xNeuron # else: # loc = np.argmin(dist) # yNewNeuron,xNewNeuron = centroids[loc] if nb_labels >1: loc = np.argmax(meanBrightness) yNewNeuron,xNewNeuron = centroids[loc] else: yNewNeuron,xNewNeuron = yNeuron, xNeuron loc = -1 neuronObject = np.where(label_im == loc+1,0,1) neuronArea = np.sum(neuronObject) # --- Get average of the neuron fluoresence --- tmp_neuron = np.ma.masked_array(bgImage, neuronObject) newNeuronAverage = np.ma.average(tmp_neuron[tmp_neuron>threshold[1]]) return yNewNeuron,xNewNeuron, newNeuronAverage,neuronArea, neuronObject
def post_process_prediction(prediction): # find connected components and remove small ones # create structure element (ball) str_el = create_ball_3d(3) img_2 = ndimage.binary_opening(prediction >= 2, str_el) connected_components, n_components = ndimage.label(img_2) # 0 and 1 are background/brain discard_components = [] component_sizes = [] all_components = np.arange(n_components)+1 for component in all_components: size_of_component = np.sum(connected_components == component) if size_of_component < 3000: discard_components.append(component) component_sizes.append(size_of_component) if len(discard_components) == n_components: discard_components = discard_components[discard_components!=np.argmax(component_sizes)] keep_components = [i for i in all_components if i not in discard_components] new_mask = np.zeros(prediction.shape, dtype=bool) for keep_me in keep_components: mask = ndimage.binary_dilation(connected_components == keep_me, create_ball_3d(5)) new_mask = (new_mask | mask) prediction_cleaned = np.zeros(prediction.shape, dtype=np.int32) prediction_cleaned[new_mask] = prediction[new_mask] prediction_cleaned[prediction_cleaned == 1] = 0 prediction_cleaned[prediction_cleaned > 0] -= 1 return prediction_cleaned
def thresholding(img, thresh, size=9): """ Segment using a thresholding algorithm Input: - img ndarray : Image array (ndim=2) - thresh float : Threshold value for pixels selectino - size int : Minimum size a group of pixels must have Output: - regions : Binary array for each segmented region --- """ logging.debug("Threshold: %.2f", thresh) logging.debug("Objects min size: %d", size) # Take the binary image thresholded img_bin = img > thresh # And use (MO) binary opening (erosion + dilation) for cleaning spurious Trues strct = ndi.generate_binary_structure(2, 2) img_bin = ndi.binary_opening(img_bin, strct) # Label each group/region (value==True) of pixels regions, nlbl = ndi.label(img_bin) for i in xrange(1, nlbl + 1): inds = np.where(regions == i) if inds[0].size < size: regions[inds] = 0 logging.debug("Threshold labels: %s", np.unique(regions)) return regions.astype(np.bool)
def segmentAlg(I,frame): n = 10 np.random.seed(1) Nx, Ny = I.size im = np.asarray(I) mask = (im > im.mean()).astype(np.float) mask += 1 * im # Thresholding algorithm #binary_img = white.white(I,Nx,Ny,20,1.15)#mask < 80 binary_img = im > 100 #scipy.misc.imsave('images/outfile'+str(frame)+'_m.jpg', binary_img) binary_img = ndimage.binary_opening(binary_img, structure=np.ones((2,2))).astype(np.int) #scipy.misc.imsave('images/outfile'+str(frame)+'_m2.jpg', binary_img) label_im, nb_labels = ndimage.label(binary_img) sizes = ndimage.sum(mask, label_im, range(nb_labels + 1)) mask_size = sizes > 150000 remove_pixel = mask_size[label_im] label_im[remove_pixel] = 0 #scipy.misc.imsave('images/outfile'+str(frame)+'_m3.jpg', label_im) return binary_img, label_im, nb_labels, sizes
def findCom(self,data): data = data.astype(int) if self.update_counter >= 5: self.update_counter = 0 ########################################################################## ## Update the background image, adding a new image and removing the oldest. ########################################################################## self.background_list.insert(0,data) self.background_list.pop() background = np.zeros((480, 640, 3), dtype=int) for b in self.background_list: background += b self.background = background/len(self.background_list) ############################################################################ ## Detect foreground by looking at difference from mean. ############################################################################ foreground = np.sum(np.abs(np.subtract(self.background,data)),axis=2) falseImage = foreground ## clean foreground image falseImage[falseImage > 100] = 255 falseImage[falseImage < 101] = 0 falseImage = ndimage.binary_opening(falseImage) falseImage = ndimage.binary_closing(falseImage) com = ndimage.measurements.center_of_mass(falseImage) self.update_counter += 1 return com
def check_ion(self, image): """ 采用图像学手段提取离子特征,计算离子位置 方法: 高斯平滑、二值化、去噪点、然后提取闭合区域信息 返回值: 离子数目和离子中心位置,对于多离子,是多个离子的中心位置 """ im = ndimage.gaussian_filter(image, sigma=1) # 平滑 binary_image = im > im.mean() + 4 * im.std() # 二值化 close_img = ndimage.binary_closing( ndimage.binary_opening(binary_image).astype( np.int)) # 去除过小的闭合区域,并圆滑边缘(降低粘连) label_im, num_labels = ndimage.label(close_img) # 标记闭合区域 if num_labels == 0: positions = [50, 50] else: positions = np.average( ndimage.center_of_mass(im, label_im, [i + 1 for i in range(num_labels)]), 0) # 多离子时取离子平均位置 ion_number = num_labels #center_positions = np.ceil(positions) return ion_number, positions, close_img
def __call__(self, output, morph=3, prob4='max'): output = prob42prob3(output, prob4) MAP = np.argmax(output, axis=2) if np.max(MAP) == 3: MAP[MAP == 3] = 0 prediction = (MAP == self.cellclass).astype(int) back = (MAP == 0).astype(int) diff = np.zeros_like(prediction) if morph > 0: prediction1 = ndimage.binary_opening(prediction, structure=np.ones( (morph, morph)), iterations=2).astype(int) diff = prediction - prediction1 prediction = prediction1 if output.shape[2] > 2: divis = (MAP == self.diviclass).astype(int) + diff MAP[divis == 1] = self.diviclass predictionlb = sem2inst(MAP) region, MAP = inst2sem(predictionlb) return predictionlb, MAP, region, output
def clustering(im, pixel_area, area_thr=10, g_fil=0.5, debug=False): # smooth the edges of the data edges im = ndimage.gaussian_filter(im, g_fil) # remove small areas with zeros and small areas with ones open_img = ndimage.binary_opening(im) close_img = ndimage.binary_closing(open_img) # cluster the all the independent areas label_im, nb_labels = ndimage.label(close_img) # calculate the areas of each cluster areas = ndimage.sum(im, label_im, range( nb_labels + 1)) * pixel_area # cos each pixels has an area of dx*dy # remove areas based on their size and the given threshold mask_size = areas < area_thr remove_pixel = mask_size[label_im] label_im[remove_pixel] = 0 # cleas up the IDs and short the areas labels = np.unique(label_im) label_im = np.searchsorted(labels, label_im) labels = np.unique(label_im) return label_im, labels
def artifact_mask(imdata, airdata, distance): """Computes a mask of artifacts found in the air region""" import nibabel as nb if not np.issubdtype(airdata.dtype, np.integer): airdata[airdata < .95] = 0 airdata[airdata > 0.] = 1 bg_img = imdata * airdata # Find the background threshold (the most frequently occurring value # excluding 0) # CHANGED - to the 75 percentile bg_threshold = np.percentile(bg_img[airdata > 0], 75) # Apply this threshold to the background voxels to identify voxels # contributing artifacts. qi1_img = np.zeros_like(bg_img) qi1_img[bg_img > bg_threshold] = 1 qi1_img[distance < .10] = 0 # Create a structural element to be used in an opening operation. struc = nd.generate_binary_structure(3, 1) qi1_img = nd.binary_opening(qi1_img, struc).astype(np.uint8) qi1_img[airdata <= 0] = 0 return qi1_img
def detect_current(cloud, showplots=False): """ Detects whether there is a vortex-like signature of persistent current in the center of a TOF image of an expanded ring BEC """ OD = cloud.get_OD() peak_coord = cloud.results['peak coordinates'] center_region = ROI(center=peak_coord, size=(40, 40)).slices cloud_center = ndi.median_filter(OD[center_region], size=2) minOD = cloud_center.min() maxOD = cloud_center.max() cloud_median = ndi.median_filter(cloud_center, size=10) belowthresh = where(cloud_center < cloud_median * 0.75, 1, 0) opened = ndi.binary_opening(belowthresh, iterations=1) closed = ndi.binary_closing(opened, iterations=3) current_found = ndi.label(closed)[1] cloud.results['current_found'] = current_found if showplots == True: fig = plt.figure(1999) fig.add_subplot(221, xticks=[], yticks=[]) plt.imshow(cloud_center, interpolation='nearest', vmin=minOD, vmax=maxOD) fig.add_subplot(222, xticks=[], yticks=[]) plt.imshow(cloud_median, interpolation='nearest', vmin=minOD, vmax=maxOD) fig.add_subplot(223, xticks=[], yticks=[]) plt.imshow(closed, interpolation='nearest', cmap=plt.cm.get_cmap('binary')) fig.add_subplot(224, xticks=[], yticks=[]) plt.imshow(belowthresh, interpolation='nearest', cmap=plt.cm.get_cmap('binary')) return current_found, asum(closed)
def og_cb(og_msg, param_list): global occupancy_difference_threshold, connected_comonents_size_threshold rospy.loginfo('og_cb called') diff_og = param_list[0] curr_og = rog.og_msg_to_og3d(og_msg, to_binary = False) if diff_og == None: param_list[0] = curr_og return pog.subtract(diff_og, curr_og) param_list[0] = curr_og diff_og.to_binary(occupancy_difference_threshold) # filter the noise connect_structure = np.zeros((3,3,3), dtype=int) connect_structure[1,1,:] = 1 # connect_structure[1,1,0] = 0 diff_og.grid = ni.binary_opening(diff_og.grid, connect_structure, iterations = 1) # diff_og.grid, n_labels = diff_og.connected_comonents(connected_comonents_size_threshold) print 'np.all(diff_og == 0)', np.all(diff_og.grid == 0) diff_og_msg = rog.og3d_to_og_msg(diff_og) diff_og_msg.header.frame_id = og_msg.header.frame_id diff_og_msg.header.stamp = og_msg.header.stamp param_list[1].publish(diff_og_msg)
def cell_to_image(self): # Find x, y coordinate bounds x_res = max(self.pix_list, key=itemgetter(0))[0] y_res = max(self.pix_list, key=itemgetter(1))[1] # Creating labeled_img self.cell_img = NP.zeros([x_res+2, y_res+2], dtype=NP.int_) for (x_pix, y_pix) in self.pix_list: self.cell_img[x_pix-1, y_pix-1] = 1 # Find the pixels that make up the perimeter eroded_image = NDI.binary_erosion(self.cell_img) eroded_image_open = NDI.binary_opening(eroded_image, structure=NP.ones((3,3))) eroded_image_open2 = NDI.binary_erosion(eroded_image_open) # self.perim_img = self.cell_img - eroded_image self.eroded_img = eroded_image_open - eroded_image_open2 self.perim_img = self.cell_img - eroded_image # Create a list of the coordinates of the pixels (use the center of the pixels) perim_image_ind = NP.where(self.perim_img == 1) perim_image_coord = NP.array([perim_image_ind[0], perim_image_ind[1]]) self.perim_coord = NP.transpose(perim_image_coord) return
def og_cb(og_msg, param_list): global occupancy_difference_threshold, connected_comonents_size_threshold rospy.loginfo('og_cb called') diff_og = param_list[0] curr_og = rog.og_msg_to_og3d(og_msg, to_binary=False) if diff_og == None: param_list[0] = curr_og return pog.subtract(diff_og, curr_og) param_list[0] = curr_og diff_og.to_binary(occupancy_difference_threshold) # filter the noise connect_structure = np.zeros((3, 3, 3), dtype=int) connect_structure[1, 1, :] = 1 # connect_structure[1,1,0] = 0 diff_og.grid = ni.binary_opening(diff_og.grid, connect_structure, iterations=1) # diff_og.grid, n_labels = diff_og.connected_comonents(connected_comonents_size_threshold) print 'np.all(diff_og == 0)', np.all(diff_og.grid == 0) diff_og_msg = rog.og3d_to_og_msg(diff_og) diff_og_msg.header.frame_id = og_msg.header.frame_id diff_og_msg.header.stamp = og_msg.header.stamp param_list[1].publish(diff_og_msg)
def normal_to_png(self, destination, morphology=False): """ Convert the normal vector map to monochrome png image. """ # # Make sure there is a proper destination destination_dir = '/'.join(destination.split('/')[:-1]) dir = os.path.dirname(destination_dir) dir = dir.replace('~', os.path.expanduser('~')) if not os.path.exists(dir): raise ValueError('The directory ' + str(dir) + ' does not exist.') destination = destination.replace('~', os.path.expanduser('~')) # # Convert a normal bitmap to a png image normal_array = array(self.nz * 255, dtype=uint8) if morphology: binary_array = normal_array > 128 binary_array = ndimage.binary_opening(binary_array, iterations=2) binary_array = ndimage.binary_closing(binary_array, iterations=2) binary_array = binary_array.astype(np.uint8) normal_array = binary_array * 255 normal_image = Image.fromarray(normal_array) normal_image = normal_image.convert('1') normal_image.save(destination, 'PNG') return
def fix_right_plant(gmask, prevmask): # we assume that the incorrect mask touches top, botton or right border if not (gmask[0].any() or gmask[-1].any() or gmask[:,-1].any()): return gmask gmask = gmask.astype(np.uint8) # detect vertical strips as lines to estimate their angle lines = cv2.HoughLines(gmask, 1, np.pi / 180, int(gmask.shape[0]/2), None, 0, 0) if lines is None: return gmask # convert angles > pi/2 to negative angles = [ll[0][1] if ll[0][1] < np.pi/2 else ll[0][1] - np.pi for ll in lines] rotangle = 180*np.mean(angles)/np.pi # analyze only in the vertical range of nonzero prevmask values nz = np.nonzero(prevmask) pmiy = nz[0].min() pmay = nz[0].max() # align strips vertically gmask = ndi.rotate(gmask,rotangle,reshape=False) # compute foreground pixels in vertical columns, the strips go top to bottom gprof=gmask[pmiy:pmay,:].sum(axis=0) gprof = gprof > 0.8*(pmay-pmiy) if not gprof.any(): # unclear case, return somethinng which would be late classified as failure return gmask cutpos = np.nonzero(gprof)[0].min() # the leftmost value, we hope this is where the plant touches it gmask[:,cutpos:] = 0 # remove noise along the border gmask = ndi.binary_opening(gmask, np.ones((1,5))).astype(np.uint8) #rotate back gmask = ndi.rotate(gmask,-rotangle,reshape=False) return select_overlaps(gmask, prevmask)
def smoothImage(image,disk_size): ''' Smooths the outline of a binary object by using morphological opening with a user-defined kernel size. ''' smoothed = ndimage.binary_opening(image,structure=np.ones((disk_size,disk_size))).astype('uint8') * 255 return smoothed
def find_feature_mask_simple(s_msk, sigma=1, ax=None, x_values=None): """ sigma is estimated globally. """ # find emission features from observed spec. filtered_spec = s_msk - ni.median_filter(s_msk, 15) #filtered_spec = ni.gaussian_filter1d(filtered_spec, 0.5) #smoothed_std = get_smoothed_std(filtered_spec, # rad=3, smooth_length=3) std = filtered_spec.std() for i in [0, 1]: std = filtered_spec[np.abs(filtered_spec) < 3 * std].std() emission_feature_msk_ = filtered_spec > sigma * std #emission_feature_msk_ = ni.binary_closing(emission_feature_msk_) emission_feature_msk = ni.binary_opening(emission_feature_msk_, iterations=1) if ax is not None: if x_values is None: x_values = np.arange(len(s_msk)) #ax.plot(x_values, s_msk) ax.plot(x_values, filtered_spec) #ax.plot(x_values, smoothed_std) ax.axhline(sigma * std) ax.plot(x_values[emission_feature_msk], emission_feature_msk[emission_feature_msk], "ys", mec="none") return emission_feature_msk
def find_feature_mask(s_msk, sigma=1, ax=None, x_values=None): # find emission features from observed spec. filtered_spec = s_msk - ni.median_filter(s_msk, 15) filtered_spec = ni.gaussian_filter1d(filtered_spec, 0.5) smoothed_std = get_smoothed_std(filtered_spec, rad=3, smooth_length=3) emission_feature_msk_ = filtered_spec > sigma * smoothed_std #emission_feature_msk_ = ni.binary_closing(emission_feature_msk_) emission_feature_msk = ni.binary_opening(emission_feature_msk_, iterations=1) if ax is not None: if x_values is None: x_values = np.arange(len(s_msk)) #ax.plot(x_values, s_msk) ax.plot(x_values, filtered_spec) ax.plot(x_values, smoothed_std) ax.plot(x_values[emission_feature_msk], emission_feature_msk[emission_feature_msk], "ys", mec="none") return emission_feature_msk
def find_feature_mask_simple(s_msk, sigma=1, ax=None, x_values=None): """ sigma is estimated globally. """ # find emission features from observed spec. filtered_spec = s_msk - ni.median_filter(s_msk, 15) #filtered_spec = ni.gaussian_filter1d(filtered_spec, 0.5) #smoothed_std = get_smoothed_std(filtered_spec, # rad=3, smooth_length=3) std = np.nanstd(filtered_spec) for i in [0, 1]: std = filtered_spec[np.abs(filtered_spec)<3*std].std() emission_feature_msk_ = filtered_spec > sigma*std #emission_feature_msk_ = ni.binary_closing(emission_feature_msk_) emission_feature_msk = ni.binary_opening(emission_feature_msk_, iterations=1) if ax is not None: if x_values is None: x_values = np.arange(len(s_msk)) #ax.plot(x_values, s_msk) ax.plot(x_values, filtered_spec) #ax.plot(x_values, smoothed_std) ax.axhline(sigma*std) ax.plot(x_values[emission_feature_msk], emission_feature_msk[emission_feature_msk], "ys", mec="none") return emission_feature_msk
def find_feature_mask(s_msk, sigma=1, ax=None, x_values=None): # find emission features from observed spec. filtered_spec = s_msk - ni.median_filter(s_msk, 15) filtered_spec = ni.gaussian_filter1d(filtered_spec, 0.5) smoothed_std = get_smoothed_std(filtered_spec, rad=3, smooth_length=3) emission_feature_msk_ = filtered_spec > sigma*smoothed_std #emission_feature_msk_ = ni.binary_closing(emission_feature_msk_) emission_feature_msk = ni.binary_opening(emission_feature_msk_, iterations=1) if ax is not None: if x_values is None: x_values = np.arange(len(s_msk)) #ax.plot(x_values, s_msk) ax.plot(x_values, filtered_spec) ax.plot(x_values, smoothed_std) ax.plot(x_values[emission_feature_msk], emission_feature_msk[emission_feature_msk], "ys", mec="none") return emission_feature_msk
def morpho_op(BW): s = [[0, 1, 0], [1, 1, 1], [0, 1, 0]] #structuring element (diamond shaped) m_morfo = ndi.binary_opening(BW, structure=s, iterations=1) m_morfo = ndi.binary_closing(m_morfo, structure=s, iterations=1) M_filled = ndi.binary_fill_holes(m_morfo, structure=s) return M_filled
def compute_granulometry_features(img_array, sigma_array, thr_list, gr_sizes=None): X = [] counter = 1 num_img = len(img_array) for img in img_array: print(" -- Features img {}/{}".format(counter, num_img)) counter += 1 gr_features = [] for si, sigma in enumerate(sigma_array): ft_img = cv2.GaussianBlur(img, (0, 0), sigma) # w_name_str = "Pyramid image" # cv2.namedWindow(w_name_str, cv2.WINDOW_NORMAL) # cv2.resizeWindow(w_name_str, 600, 600) # cv2.imshow(w_name_str, ft_img) # cv2.waitKey(0) # cv2.destroyAllWindows() for thr in thr_list: gr_features += [ ndimage.binary_opening( ft_img > thr, structure=disk_structure(g_size)).sum() for g_size in gr_sizes ] X.append(np.array(gr_features)) # print(gr_features) return X
def extract_disc_text(img): # create disc mask and 90% disc mask m, n = img.shape r = m // 2 r90 = int(0.9 * m) // 2 msk = np.uint8(mask_discs(img.shape, {0: (r, r, r, r)})) msk90 = np.uint8(mask_discs(img.shape, {0: (r, r, r90, r90)})) # fill area around mask with mean value to limit mask edge artifacts # from adaptive threshold mean = int(round(np.mean(img[msk > 0]))) inv = 1 - msk fill = (img * msk) + (inv * mean) med = median_filter_sp(fill, 3) med2 = median_filter_sp(img * msk90, 3) vals = med2[msk90 > 0] # apply global threshold to find area of disc where text is located thresh = int(np.mean(vals) - np.std(vals)) t, gth = cv2.threshold(med2, thresh, 255, cv2.THRESH_BINARY) # apply local threshold to find text edges (still noisy outside text area) ath = cv2.adaptiveThreshold(med, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 21, 1) # combine both thresholded images to get sharp text edges without noise txt = (gth == 0) * (ath == 0) * (msk90 > 0) txt = np.uint8(ndimage.binary_opening(txt)) * 255 return txt
def granulometry(data, sizes=None): s = max(data.shape) if sizes == None: sizes = range(1, s/2, 2) granulo = [ndimage.binary_opening(data, \ structure=disk_structure(n)).sum() for n in sizes] return granulo
def parse_df(self, row, which='train'): _ = os.path.join parsed = self.parse_map.copy() img_name = "{}.png".format(row.id) img = (cv2.imread(row.path, 0) / 255).squeeze() is_train = which == 'train' paths = self.train_paths if is_train else self.test_paths if is_train: mask = (cv2.imread(row.mask_path, 0) / 255).squeeze() mask_edge = rank.entropy(mask, disk(1)).round() parsed['edge_counts'], parsed['mid_point'], parsed[ 'distance'] = self.get_edge_details(mask_edge) # io.imsave(_(paths['edges'], img_name), mask_edge) sobel_img = sobel(img) io.imsave(_(paths['sobels'], img_name), sobel_img) sobel_bin = sobel_img < self.sobel_threshold sobel_er = erosion(sobel_bin, disk(self.sobel_disk_size)) sobel_mask = remove_small_objects(ndi.binary_opening(sobel_er)) io.imsave(_(paths['sobels_mask_v1'], img_name), sobel_mask.astype('int8') * 255) combined_image = np.dstack((img, sobel_img, sobel_mask)) io.imsave(_(paths['combined_v1'], img_name), combined_image) return [parsed[k] for k in self.parse_order]
def granulometry(data, sizes=None): s = max(data.shape) if sizes == None: sizes = range(1, s / 2, 2) granulo = [ndimage.binary_opening(data, \ structure=disk_structure(n)).sum() for n in sizes] return granulo
def artifact_mask(imdata, airdata, distance, zscore=10.): """Computes a mask of artifacts found in the air region""" from statsmodels.robust.scale import mad if not np.issubdtype(airdata.dtype, np.integer): airdata[airdata < .95] = 0 airdata[airdata > 0.] = 1 bg_img = imdata * airdata if np.sum((bg_img > 0).astype(np.uint8)) < 100: return np.zeros_like(airdata) # Find the background threshold (the most frequently occurring value # excluding 0) bg_location = np.median(bg_img[bg_img > 0]) bg_spread = mad(bg_img[bg_img > 0]) bg_img[bg_img > 0] -= bg_location bg_img[bg_img > 0] /= bg_spread # Apply this threshold to the background voxels to identify voxels # contributing artifacts. qi1_img = np.zeros_like(bg_img) qi1_img[bg_img > zscore] = 1 qi1_img[distance < .10] = 0 # Create a structural element to be used in an opening operation. struc = nd.generate_binary_structure(3, 1) qi1_img = nd.binary_opening(qi1_img, struc).astype(np.uint8) qi1_img[airdata <= 0] = 0 return qi1_img
def artifact_mask(imdata, airdata, distance, zscore=10.): """Computes a mask of artifacts found in the air region""" from statsmodels.robust.scale import mad if not np.issubdtype(airdata.dtype, np.integer): airdata[airdata < .95] = 0 airdata[airdata > 0.] = 1 bg_img = imdata * airdata if np.sum((bg_img > 0).astype(np.uint8)) < 100: return np.zeros_like(airdata) # Find the background threshold (the most frequently occurring value # excluding 0) bg_location = np.median(bg_img[bg_img > 0]) bg_spread = mad(bg_img[bg_img > 0]) bg_img[bg_img > 0] -= bg_location bg_img[bg_img > 0] /= bg_spread # Apply this threshold to the background voxels to identify voxels # contributing artifacts. qi1_img = np.zeros_like(bg_img) qi1_img[bg_img > zscore] = 1 qi1_img[distance < .10] = 0 # Create a structural element to be used in an opening operation. struc = nd.generate_binary_structure(3, 1) qi1_img = nd.binary_opening(qi1_img, struc).astype(np.uint8) qi1_img[airdata <= 0] = 0 return qi1_img
def post_process_prediction(prediction): # find connected components and remove small ones # create structure element (ball) str_el = create_ball_3d(3) img_2 = ndimage.binary_opening(prediction >= 2, str_el) connected_components, n_components = ndimage.label(img_2) # 0 and 1 are background/brain discard_components = [] component_sizes = [] all_components = np.arange(n_components)+1 for component in all_components: size_of_component = np.sum(connected_components == component) if size_of_component < 3000: discard_components.append(component) component_sizes.append(size_of_component) if len(discard_components) == n_components: discard_components = discard_components[discard_components!=np.argmax(component_sizes)] keep_components = [i for i in all_components if i not in discard_components] new_mask = np.zeros(prediction.shape, dtype=bool) for keep_me in keep_components: mask = ndimage.binary_dilation(connected_components == keep_me, create_ball_3d(5)) new_mask = (new_mask | mask) prediction_cleaned = np.zeros(prediction.shape, dtype=np.int32) prediction_cleaned[new_mask] = prediction[new_mask] prediction_cleaned[prediction_cleaned == 1] = 0 prediction_cleaned[prediction_cleaned > 0] -= 1 return prediction_cleaned
def calculate_local_region_threshold(nuclei: List[Tuple[int, int]], channel: np.ndarray, sigma: float = 2, low_threshold: float = 0.1, high_threshold: float = 0.2) -> np.ndarray: """ Method to threshold nuclei for foci extraction :param nuclei: The points of the nucleus as list :param channel: The corresponding channel :param sigma: Standard deviation of the gaussian kernel :param low_threshold: Lower bound for hysteresis thresholding :param high_threshold: Upper bound for hysteresis thresholding :return: The foci map for the nucleus """ chan = np.zeros(shape=channel.shape) for nuc in nuclei: thresh = [] for p in nuc: thresh.append((p, channel[p[0]][p[1]])) if thresh: thresh_np, offset = Detector.create_numpy_from_point_list(thresh) edges = Detector.detect_edges(thresh_np, sigma, low_threshold, high_threshold) if np.max(edges) > 0: chan_fill = ndi.binary_fill_holes(edges) chan_open = ndi.binary_opening(chan_fill) if np.max(chan_open) > 0: imprint_data_into_channel(chan, chan_open, offset) return chan
def plot_abundance(nh3_cont_fits,nh3_col_hdu,h2_col_hdu,region,plot_pars,maskLim,obsMaskFits): text_size = 14 b18_text_size = 20 if region == 'B18': text_size = b18_text_size # Get protostellar locations ra_prot, de_prot = get_prot_loc(region) # Contour parameters (currently NH3 moment 0) cont_color='0.6' cont_lw = 0.6 cont_levs=2**np.arange( 0,20)*plot_param['w11_step'] # Calculate abundance log_xnh3 = nh3_col_hdu[0].data - np.log10(h2_col_hdu.data) log_xnh3_hdu = fits.PrimaryHDU(log_xnh3,nh3_col_hdu[0].header) log_xnh3_hdu.writeto('../testing/{0}/parameterMaps/{0}_XNH3_{1}.fits'.format(region,file_extension),clobber=True) fig=aplpy.FITSFigure(log_xnh3_hdu,figsize=(plot_param['size_x'], plot_param['size_y'])) fig.show_colorscale(cmap='YlOrRd_r',vmin=plot_param['xnh3_lim'][0],vmax=plot_param['xnh3_lim'][1]) #fig.set_nan_color('0.95') # Observations mask contour fig.show_contour(obsMaskFits,colors='white',levels=1,linewidths=1.5) # NH3 moment contours # Masking of small (noisy) regions selem = np.array([[0,1,0],[1,1,1],[0,1,0]]) LowestContour = cont_levs[0]*0.5 w11_hdu = fits.open(nh3_cont_fits) map = w11_hdu[0].data mask = binary_opening(map > LowestContour, selem) MaskedMap = mask*map w11_hdu[0].data = MaskedMap fig.show_contour(w11_hdu,colors=cont_color,levels=cont_levs,linewidths=cont_lw) # Ticks fig.ticks.set_color('black') fig.tick_labels.set_font(family='sans_serif',size=text_size) fig.tick_labels.set_xformat('hh:mm:ss') fig.tick_labels.set_style('colons') fig.tick_labels.set_yformat('dd:mm') # Scale bar ang_sep = (plot_param['scalebar_size'].to(u.au)/plot_param['distance']).to(u.arcsec, equivalencies=u.dimensionless_angles()) fig.add_colorbar() fig.colorbar.show(box_orientation='horizontal', width=0.1, pad=0.0, location='top', ticks=[-10,-9.5,-9,-8.5,-8,-7.5,-7,-6.5]) fig.colorbar.set_font(family='sans_serif',size=text_size) fig.add_scalebar(ang_sep.to(u.degree)) fig.scalebar.set_font(family='sans_serif',size=text_size) fig.scalebar.set_corner(plot_param['scalebar_pos']) fig.scalebar.set(color='black') fig.scalebar.set_label('{0:4.2f}'.format(plot_param['scalebar_size'])) label_colour = 'black' fig.add_label(plot_param['label_xpos'], plot_param['label_ypos'], '{0}\n{1}'.format(region,r'$\mathrm{log} \ X(\mathrm{NH}_3)$'), relative=True, color=label_colour, horizontalalignment=plot_param['label_align'], family='sans_serif',size=text_size) fig.save( 'figures/{0}_xnh3_image.pdf'.format(region),adjust_bbox=True,dpi=200)#, bbox_inches='tight') # Add protostars fig.show_markers(ra_prot,de_prot,marker='*',s=50, c='white',edgecolors='black',linewidth=0.5,zorder=4) fig.save( 'figures/{0}_xnh3_image_prot.pdf'.format(region),adjust_bbox=True,dpi=200) fig.close()
def compute_epi_mask(mean_epi, lower_cutoff=0.2, upper_cutoff=0.9, connected=True, opening=True, exclude_zeros=False, verbose=0): """ Compute a brain mask from fMRI data in 3D or 4D ndarrays. This is based on an heuristic proposed by T.Nichols: find the least dense point of the histogram, between fractions lower_cutoff and upper_cutoff of the total image histogram. In case of failure, it is usually advisable to increase lower_cutoff. Parameters ---------- mean_epi: 3D ndarray EPI image, used to compute the mask. lower_cutoff : float, optional lower fraction of the histogram to be discarded. upper_cutoff: float, optional upper fraction of the histogram to be discarded. connected: boolean, optional if connected is True, only the largest connect component is kept. opening: boolean, optional if opening is True, an morphological opening is performed, to keep only large structures. This step is useful to remove parts of the skull that might have been included. exclude_zeros: boolean, optional Consider zeros as missing values for the computation of the threshold. This option is useful if the images have been resliced with a large padding of zeros. verbose: integer, optional Returns ------- mask : 3D boolean ndarray The brain mask """ if verbose > 0: print "EPI mask computation" if len(mean_epi.shape) == 4: mean_epi = mean_epi.mean(axis=-1) sorted_input = np.sort(np.ravel(mean_epi)) if exclude_zeros: sorted_input = sorted_input[sorted_input != 0] lower_cutoff = np.floor(lower_cutoff * len(sorted_input)) upper_cutoff = np.floor(upper_cutoff * len(sorted_input)) delta = sorted_input[lower_cutoff + 1:upper_cutoff + 1] \ - sorted_input[lower_cutoff:upper_cutoff] ia = delta.argmax() threshold = 0.5 * (sorted_input[ia + lower_cutoff] + sorted_input[ia + lower_cutoff + 1]) mask = (mean_epi >= threshold) if connected: mask = _largest_connected_component(mask) if opening: mask = ndimage.binary_opening(mask.astype(np.int), iterations=2) return mask.astype(bool)
def compute_mask(mean_volume, reference_volume=None, m=0.2, M=0.9, cc=True, opening=True, exclude_zeros=False): """ Compute a mask file from fMRI data in 3D or 4D ndarrays. Compute and write the mask of an image based on the grey level This is based on an heuristic proposed by T.Nichols: find the least dense point of the histogram, between fractions m and M of the total image histogram. In case of failure, it is usually advisable to increase m. Parameters ---------- mean_volume : 3D ndarray mean EPI image, used to compute the threshold for the mask. reference_volume: 3D ndarray, optional reference volume used to compute the mask. If none is give, the mean volume is used. m : float, optional lower fraction of the histogram to be discarded. M: float, optional upper fraction of the histogram to be discarded. cc: boolean, optional if cc is True, only the largest connect component is kept. opening: boolean, optional if opening is True, an morphological opening is performed, to keep only large structures. This step is useful to remove parts of the skull that might have been included. exclude_zeros: boolean, optional Consider zeros as missing values for the computation of the threshold. This option is useful if the images have been resliced with a large padding of zeros. Returns ------- mask : 3D boolean ndarray The brain mask """ if reference_volume is None: reference_volume = mean_volume sorted_input = np.sort(mean_volume.reshape(-1)) if exclude_zeros: sorted_input = sorted_input[sorted_input != 0] limiteinf = np.floor(m * len(sorted_input)) limitesup = np.floor(M * len(sorted_input)) delta = sorted_input[limiteinf + 1 : limitesup + 1] - sorted_input[limiteinf:limitesup] ia = delta.argmax() threshold = 0.5 * (sorted_input[ia + limiteinf] + sorted_input[ia + limiteinf + 1]) mask = reference_volume >= threshold if cc: mask = largest_cc(mask) if opening: mask = ndimage.binary_opening(mask.astype(np.int), iterations=2) return mask.astype(bool)
def refine_worm(image, initial_area, candidate_edges): # find strong worm edges (roughly equivalent to the edges found by find_initial_worm, # which are in candidate_edges): smooth the image, do canny edge-finding, and # then keep only those edges near candidate_edges smooth_image = restoration.denoise_tv_bregman(image, 140).astype(numpy.float32) smoothed, gradient, sobel = canny.prepare_canny(smooth_image, 8, initial_area) local_maxima = canny.canny_local_maxima(gradient, sobel) candidate_edge_region = ndimage.binary_dilation(candidate_edges, iterations=4) strong_edges = local_maxima & candidate_edge_region # Now threshold the image to find dark blobs as our initial worm region # First, find areas in the initial region unlikely to be worm pixels mean, std = mcd.robust_mean_std(smooth_image[initial_area][::4], 0.85) non_worm = (smooth_image > mean - std) & initial_area # now fit a smoothly varying polynomial to the non-worm pixels in the initial # region of interest, and subtract that from the actual image to generate # an image with a flat illumination field background = polyfit.fit_polynomial(smooth_image, mask=non_worm, degree=2) minus_bg = smooth_image - background # now recalculate a threshold from the background-subtracted pixels mean, std = mcd.robust_mean_std(minus_bg[initial_area][::4], 0.85) initial_worm = (minus_bg < mean - std) & initial_area # Add any pixels near the strong edges to our candidate worm position initial_worm |= ndimage.binary_dilation(strong_edges, iterations=3) initial_worm = mask.fill_small_radius_holes(initial_worm, 5) # Now grow/shrink the initial_worm region so that as many of the strong # edges from the canny filter are in contact with the region edges as possible. ac = active_contour.EdgeClaimingAdvection(initial_worm, strong_edges, max_region_mask=initial_area) stopper = active_contour.StoppingCondition(ac, max_iterations=100) while stopper.should_continue(): ac.advect(iters=1) ac.smooth(iters=1, depth=2) worm_mask = mask.fill_small_radius_holes(ac.mask, 7) # Now, get edges from the image at a finer scale smoothed, gradient, sobel = canny.prepare_canny(smooth_image, 0.3, initial_area) local_maxima = canny.canny_local_maxima(gradient, sobel) strong_sum = strong_edges.sum() highp = 100 * (1 - 1.5*strong_sum/local_maxima.sum()) lowp = max(100 * (1 - 3*strong_sum/local_maxima.sum()), 0) low_worm, high_worm = numpy.percentile(gradient[local_maxima], [lowp, highp]) fine_edges = canny.canny_hysteresis(local_maxima, gradient, low_worm, high_worm) # Expand out the identified worm area to include any of these finer edges closed_edges = ndimage.binary_closing(fine_edges, structure=S) worm = ndimage.binary_propagation(worm_mask, mask=worm_mask|closed_edges, structure=S) worm = ndimage.binary_closing(worm, structure=S, iterations=2) worm = mask.fill_small_radius_holes(worm, 5) worm = ndimage.binary_opening(worm) worm = mask.get_largest_object(worm) # Last, smooth the shape a bit to reduce sharp corners, but not too much to # sand off the tail ac = active_contour.CurvatureMorphology(worm, max_region_mask=initial_area) ac.smooth(depth=2, iters=2) return strong_edges, ac.mask
def adaptive_segment(args): """ Applies an adaptive threshold to reconstructed data. Also known as local or dynamic thresholding where the threshold value is the weighted mean for the local neighborhood of a pixel subtracted by constant. Alternatively the threshold can be determined dynamically by a given function using the 'generic' method. Parameters ---------- data : ndarray, float32 3-D reconstructed data with dimensions: [slices, pixels, pixels] block_size : scalar, int Uneven size of pixel neighborhood which is used to calculate the threshold value (e.g. 3, 5, 7, ..., 21, ...). offset : scalar, float Constant subtracted from weighted mean of neighborhood to calculate the local threshold value. Default offset is 0. Returns ------- output : ndarray Thresholded data. References ---------- - `http://scikit-image.org/docs/dev/auto_examples/plot_threshold_adaptive.html \ <http://scikit-image.org/docs/dev/auto_examples/plot_threshold_adaptive.html>`_ """ # Arguments passed by multi-processing wrapper ind, dshape, inputs = args # Function inputs data = mp.tonumpyarray(mp.shared_arr, dshape) # shared-array block_size, offset = inputs for m in ind: img = data[m, :, :] # Perform scikit adaptive thresholding. img = threshold_adaptive(img, block_size=block_size, offset=offset) # Remove small white regions img = ndimage.binary_opening(img) # Remove small black holes img = ndimage.binary_closing(img) data[m, :, :] = img
def morph_sequence(pix, *param): for oc, wd, ht in param: logi(" Performing Morph : ", oc, wd, ht) structure = np.ones((ht, wd)) if oc == "c": pix = binary_closing(pix, structure) elif oc == "o": pix = binary_opening(pix, structure) return pix
def fraction_positive(bin_im, positive_im, erode=2, overlap_thresh=0.9, bin_name='nuclei', positive_name='tf'): """Compute fraction of objects in bin_im overlapping positive_im. The purpose of this function is to compute the fraction of nuclei that express a particular transcription factor. By providing the thresholded DAPI channel as `bin_im` and the thresholded TF channel as `positive_im`, this fraction can be computed. Parameters ---------- bin_im : 2D array of bool The image of objects being tested. positive_im : 2D array of bool The image of positive objects. erode : int, optional Radius of structuring element used to smooth input images. overlap_thresh : float, optional The minimum amount of overlap between an object in `bin_im` and the `positive_im` to consider that object "positive". bin_name : string, optional The name of the objects being tested. positive_name : string, optional The name of the property being measured. Returns ------- f : 1D array of float, shape (1,) The feature vector. name : list of string, length 1 The name of the feature. """ selem = skmorph.disk(erode) if erode > 0: bin_im = nd.binary_opening(bin_im, selem) positive_im = nd.binary_opening(positive_im, selem) lab_im, n_objs = nd.label(bin_im) means = measure.regionprops(lab_im, intensity_image=positive_im.astype(np.float32)) means = np.array([prop.mean_intensity for prop in means], np.float32) f = np.array([np.mean(means > overlap_thresh)]) name = ['frac-%s-pos-%s-erode-%i-thresh-%.2f' % (bin_name, positive_name, erode, overlap_thresh)] return f, name
def getxy(datas): ok=datas>=datas.mean()+1.5*datas.std() good=nd.binary_opening(ok,structure=np.ones((6,6))) datagood=datas*good structuring_element=np.ones((3,3)) segmentation,segments=nd.label(good,structure=structuring_element) coords=nd.center_of_mass(datagood,segmentation,range(1,segments+1)) xcoords=np.array([x[1] for x in coords]) ycoords=np.array([x[0] for x in coords]) return xcoords,ycoords
def extract_binary_regions(sequence, opening_param = 3, mshape = ((0,1,0),(1,1,1),(0,1,0))): labelblock = np.zeros_like(sequence) for idx in range(sequence.shape[0]): labelblock[idx] = sequence[idx].copy() labelblock[idx] = ndi.binary_opening(labelblock[idx], iterations = opening_param, structure = mshape) labelblock[idx], num_labels = ndi.label(labelblock[idx]) return labelblock, opening_param, mshape
def getContours(self): """ Derive contours using the diskStructure function. """ if not hasattr(self, 'mask'): self.find() self.opened = ndimage.binary_opening(self.mask, structure=self._diskStructure(self.settings['disk_struct'])) return self.opened