def get_center_of_mass(img, thr=127, gmax = 255, ksize=(5,5)): img = jpg_to_cv2gray(img) blur = cv2.GaussianBlur(img, ksize=ksize,sigmaX = 0) ret, thresh1 = cv2.threshold(blur, thr, gmax, cv2.THRESH_BINARY) edged = cv2.Canny(blur, 10, 250) cenofmass = com(edged) cenofmass = int(cenofmass[0]), int(cenofmass[1]) return cenofmass[1], cenofmass[0]
def get_z_crops(x, ix, min_pix=1500, n_comps=2, rad_crit=20000): final_slices = [] for six in range(x.shape[0]): tx = np.copy(x[six]) < -600 img_center = np.array(tx.shape) / 2 tx = clear_border(tx) clusters, n_cands = lb(tx) count = np.unique(clusters, return_counts=True) keep_comps = np.array([ ii for ii in np.argwhere((count[1] > min_pix)) if ii > 0 ]).astype(int) if len(keep_comps) > n_comps - 1: coms = com(tx, clusters, index=keep_comps) keep_com = [ ix for ix, ii in enumerate(coms[0]) if ((ii[0] - img_center[0])**2 + (ii[1] - img_center[1])**2 < rad_crit) ] keep_comps = keep_comps[keep_com] if len(keep_comps) > n_comps - 1: final_slices.append(six) # print('appending', six) z_min = np.min(final_slices) - 7 z_max = np.max(final_slices) + 7 dist = z_max - z_min if dist >= 151: print('trying again with min pix', min_pix + 500, rad_crit - 500, ix, dist) z_min, z_max = get_z_crops(x, ix, min_pix=min_pix + 500, rad_crit=rad_crit - 500) if dist <= 43: print('trying again with one component', min_pix - 100, rad_crit + 100, ix, dist) z_min, z_max = get_z_crops(x, ix, n_comps=1, min_pix=min_pix - 100, rad_crit=rad_crit + 100) print(z_min, z_max, z_max - z_min, ix) return z_min, z_max
def mod_region_test(composite, mod_id, algorithm, **kwargs): region_test_path = os.path.join(composite.experiment.video_path, 'regions', composite.series.name) if not os.path.exists(region_test_path): os.makedirs(region_test_path) for t in range(composite.series.ts): zbf = composite.gons.get(t=t, channel__name='-zbf').load() region_mask = composite.masks.get(t=t, channel__name__contains=kwargs['channel_unique_override']).load() mask_edges = mask_edge_image(region_mask) zbf_mask_r = zbf.copy() zbf_mask_g = zbf.copy() zbf_mask_b = zbf.copy() # edges zbf_mask_r[mask_edges>0] = 100 zbf_mask_g[mask_edges>0] = 100 zbf_mask_b[mask_edges>0] = 100 # region labels # prepare drawing blank_slate = np.zeros(zbf.shape) blank_slate_img = Image.fromarray(blank_slate) draw = ImageDraw.Draw(blank_slate_img) for unique in [u for u in np.unique(region_mask) if u>0]: if composite.series.region_instances.filter(region_track_instance__t=t, mode_gray_value_id=unique).count()>0: region = composite.series.region_instances.get(region_track_instance__t=t, mode_gray_value_id=unique).region # get coords (isolate mask, cut to black, use r/c) isolated_mask = region_mask==unique cut, (r0,c0,rs,cs) = cut_to_black(isolated_mask) com_r, com_c = com(isolated_mask) draw.text((com_c+30, com_r+30), '{}'.format(region.name), font=ImageFont.load_default(), fill='rgb(0,0,255)') blank_slate = np.array(blank_slate_img) zbf_mask_r[blank_slate>0] = 0 zbf_mask_g[blank_slate>0] = 0 zbf_mask_b[blank_slate>0] = 255 whole = np.dstack([zbf_mask_r, zbf_mask_g, zbf_mask_b]) imsave(join(region_test_path, 'regions_{}_s{}_t{}.tiff'.format(composite.experiment.name, composite.series.name, str_value(t, composite.series.ts))), whole)
def com_calc(img, max_size, min_size, lung_img): ''' Calculate the center of mass of each of the labeled regions in img, excluding regions that are outside the lung given in lung_img, or the range size [min_size, max_size], which are reported treated as fractions of the input lung. ''' from scipy.ndimage.measurements import center_of_mass as com # pylint: disable=E1101 arr = sitk.GetArrayFromImage(img) lung_arr = sitk.GetArrayFromImage(lung_img) # Take elements from arr only when lung_arr is not zero, i.e. take only # regions in the lung. arr = np.where(lung_arr != 0, arr, np.zeros(arr.shape, dtype=arr.dtype)) counts = np.bincount(np.ravel(arr)) # volume per voxel is encoded in img spacing, with units mm^3 vox_vol = reduce(lambda x, y: x * y, img.GetSpacing()) # the size of the lung is the size of a voxel times the number of voxels lung_size = np.count_nonzero(lung_arr)*vox_vol # print sorted(counts)[-10:], sorted([c for c in counts if c != 0])[0:10] # print np.count_nonzero(lung_arr)*vox_vol logging.debug("Availiable labels and sizes: %s", [p for p in enumerate(counts) if p[1] > 0]) # We gate the deterministic seeds for their regions being of a reasonable # size. labels = [label for (label, n_vox) in enumerate(counts) if min_size*lung_size < n_vox*vox_vol < max_size*lung_size] # we don't want to calculate the COM of the background, no matter what # our min/max sizes are try: labels.remove(0) except ValueError: #Zero wasn't in the list pass # compute the center of mass for each of the elements up to 100 elements com_list = com(np.where(arr != 0, np.ones(arr.shape), np.zeros(arr.shape)), labels=arr, index=labels) logging.debug("Label-COM correspondence: %s", dict(zip(labels, com_list))) # these are array-indexed and we take our seeds to be image-indexed # plus, they're floats and need to be cast back to integers seeds = [[int(k) for k in reversed(s)] for s in com_list if lung_arr[s] == 1] info = {'nseeds': len(seeds), 'max_size': max_size, 'min_size': min_size, 'seeds': [s for s in seeds]} # deep (enough) copy logging.info("%s in-lung of %s seeds from %s watershed labels", len(seeds), len(labels), len(counts)) return (seeds, info)
from util import * img, id = get_img(ret_id=True, denoise=False) img = threshold(img, int(1.2*np.mean(img)), ttype=tz) centroids = load_all_centroids(id) centrs = arr([[c[1], c[0]] for c in centroids]) print '%d centroids' % len(centrs) from skimage.morphology import label comps = label(img > int(1.0*np.mean(img))) #comps = label(img) print '%d components' % (len(np.unique(comps))-1) from scipy.ndimage.measurements import center_of_mass as com comp_centrs = arr(list(map( lambda c: [c[1], c[0]], [com(img * (comps==i)) for i in range(1, len(np.unique(comps))-1)]))) _, ax = plt.subplots(1, 2) gray_imshow(ax[0], img) ax[0].scatter(centrs[:,0], centrs[:,1], s=10, c='r') #gray_imshow(ax[1], comps, cmap='jet') gray_imshow(ax[1], img) ax[1].scatter(comp_centrs[:,0], comp_centrs[:,1], s=10, c='b') #gray_imshow(ax[2], comps, cmap='jet') plt.show()
r"^(?P<experiment>.+)_s(?P<series>.+)_ch(?P<channel>.+)_t(?P<t>[0-9]+)_z(?P<z>[0-9]+)\.(?P<extension>.+)$", n ).group("z") ) load = lambda p, n: exposure.rescale_intensity(imread(join(p, n)) * 1.0) bf = {z(name): {"img": load(bf_path, name), "name": name} for name in os.listdir(bf_path) if ".DS" not in name} zmod = load(t_path, "050714_s13_ch-zmod_t30_z0.tiff") zmean = load(t_path, "050714_s13_ch-zmean_t30_z0.tiff") zbf = load(t_path, "050714_s13_ch-zbf_t30_z0.tiff") marker = load(t_path, "primary_t30.tif") # vars r0, r1 = 360, 475 # bounding box c0, c1 = 230, 305 _C = com(marker != 0) # marker location marker_r, marker_c = int(_C[0]), int(_C[1]) cut = lambda img: img[r0:r1, c0:c1] cut_r, cut_c = marker_r - r0, marker_c - c0 # generate zcomp zcomp = zbf * zmean def binary_edge(binary): return binary - erode(binary) def edges_touching(binary_inside, binary_outside): # 1. get edge of outside binary_outside_edge = binary_edge(binary_outside).astype(int)
c_mask3 = path3.contains_points(points) c_mask3 = np.rot90(np.flip(c_mask3.reshape((y_dim, x_dim)), 1)) c_mask4 = path4.contains_points(points) c_mask4 = np.rot90(np.flip(c_mask4.reshape((y_dim, x_dim)), 1)) ################################################# ################################################# ################################################# weight1 = np.flip(c_mask1 * imghmi, 0) weight2 = np.flip(c_mask2 * imghmi, 0) weight3 = np.flip(c_mask3 * imghmi, 0) weight4 = np.flip(c_mask4 * imghmi, 0) cm1 = np.array(com(weight1)).astype(int) cm2 = np.array(com(weight2)).astype(int) cm3 = np.array(com(weight3)).astype(int) cm4 = np.array(com(weight4)).astype(int) combined = weight1 + weight2 + weight3 + weight4 plt.imshow(combined, cmap="gray", vmin=-120, vmax=120) plt.autoscale(False) plt.plot(cm1[1], cm1[0], 'g+') plt.plot(cm2[1], cm2[0], 'g+') plt.plot(cm3[1], cm3[0], 'g+') plt.plot(cm4[1], cm4[0], 'g+') plt.savefig('resulthmi3.png', bbox_inches='tight', dpi=300) debug()
def report(self, volume=None, threshold=None, out_file='ClusterReport.csv'): # To take care if user has given a 4D contrast if volume != None: self.volume = volume if len(self.brain.shape) > 3: brain = np.array(self.brain[:, :, :, self.volume]) else: brain = np.array(self.brain) if threshold != None: self.thresh = threshold # Total number of brain voxels num_brain_voxels = len(np.where(brain != 0)[0]) """ Brain_zero is used later to calculate the center of gravity of the cluster voxels overlapping with atlas voxels """ brain_zero = np.zeros(brain.shape) # Apply thresholding brain[(brain < self.thresh) & (brain > -self.thresh)] = 0 # Find clusters clusters, num_clusters = lb(brain) df_report = pd.DataFrame() # List to store cluster size information full_cluster_voxels_percentage_list = [] atlas_path = self.atlas_dict['atlas_path'] atlas_labels_path = self.atlas_dict['atlas_labels_path'] atlas_xml_zero_start_index = \ self.atlas_dict['atlas_xml_zero_start_index'] atlas_obj = au.queryAtlas( atlas_path, atlas_labels_path, atlas_xml_zero_start_index=atlas_xml_zero_start_index) for cluster_number in range(1, num_clusters + 1): # Coordinates that are present in cluster given by cluster_number cluster_indices = np.where(clusters == cluster_number) # Number of voxels belonging to the cluster -> cluster_number num_cluster_voxels = len(cluster_indices[0]) # Percentage of total brain voxels in a cluster full_cluster_voxels_percentage = \ num_cluster_voxels * 100 / num_brain_voxels # To create a list to be added to dataframe full_cluster_voxels_percentage_list.append( full_cluster_voxels_percentage) # Find the atlas labels/regions that the cluster spans atlas_regions_labels = np.unique(self.atlas[cluster_indices]) # print(atlas_regions_labels) # iterate over all the labes/regions for label in atlas_regions_labels: # Lists to be used for dataFrame creation cog_value_list = [] number_overlapping_cluster_voxels_list = [] overlapping_cluster_voxels_percentage_list = [] MNI_cog_list = [] cog_region_name_list = [] cog_unweighted_value_list = [] cog_weighted_value_list = [] cog_weighted_value_list = [] MNI_cog_unweighted_list = [] MNI_cog_weighted_list = [] cog_region_name_weighted_list = [] cog_region_name_unweighted_list = [] # Find all the coordinates of the labels # Skipping the Label 0 if label == 0: continue atlas_label_indices = np.where(self.atlas == label) """ Find the cluster coordinates overlapping the label/region under consideration """ # Changing the form of cluster indices to (x,y,z) tuple cluster_indices_zip = zip(cluster_indices[0], cluster_indices[1], cluster_indices[2]) cluster_indices_tuple_list = list(cluster_indices_zip) # Changing the form of atlas indices to (x,y,z) tuple atlas_label_indices_zip = \ zip(atlas_label_indices[0], atlas_label_indices[1], atlas_label_indices[2]) atlas_label_indices_tuple_list = list(atlas_label_indices_zip) # Number of voxels belonging to the atlas region num_atlas_region_voxels = len(atlas_label_indices_tuple_list) # 1. Find intersecion of the above two lists overlapping_coordinates = \ list(set(cluster_indices_tuple_list).intersection( set(atlas_label_indices_tuple_list))) """ 2. Make an brain array and initialize the overlapping coordinates with the values from brain # Transform coordinates list to list of indices as returned by np.where() # Ref: https://stackoverflow.com/questions/12974474/ how-to-unzip-a-list-of-tuples-into-individual-lists """ overlapping_indices_zip = zip(*overlapping_coordinates) overlapping_indices_tuple_list = list(overlapping_indices_zip) # Number of voxels in the overlap of cluster and atlas region number_overlapping_cluster_voxels = \ len(overlapping_coordinates) # Creating list to be added to dataframe number_overlapping_cluster_voxels_list.append( number_overlapping_cluster_voxels) #Percentage of voxels in the overlap of cluster and atlas region overlapping_cluster_voxels_percentage = \ number_overlapping_cluster_voxels*100 / num_atlas_region_voxels # Creating list to be added to dataframe overlapping_cluster_voxels_percentage_list.append( overlapping_cluster_voxels_percentage) # Assigning the overlap to the empty brain to find COG later brain_zero[overlapping_indices_tuple_list] = \ brain[overlapping_indices_tuple_list] """ 3. Then use the already created functions to do the following: a. Find the representative coordinate of the intersection Create a dummy atlas (roi_mask) with just one region and label that as 1 Ref: https://stackoverflow.com/questions/32322281/ numpy-matrix-binarization-using-only-one-expression """ roi_mask_for_unweighted_cog = np.where(brain_zero != 0, 1, 0) roi_mask_for_weighted_cog = brain_zero cog_unweighted = com(roi_mask_for_unweighted_cog) cog_weighted = com(roi_mask_for_weighted_cog) # convert the coordinates to int (math.floor) cog_unweighted = tuple(map(int, cog_unweighted)) cog_weighted = tuple(map(int, cog_weighted)) """ If the COG lies outside the overlapping coordinates then find the coordinate that lies on the overlapping region and is closest to the COG. """ if not roi_mask_for_unweighted_cog[cog_unweighted]: cog_unweighted = \ tuple(self.getNearestVoxel(roi_mask_for_unweighted_cog, cog_unweighted)) if not roi_mask_for_weighted_cog[cog_weighted]: cog_weighted= \ tuple(self.getNearestVoxel(roi_mask_for_weighted_cog, cog_weighted)) # print('COM Unweighted', cog_unweighted) # print('COM Weighted', cog_weighted) # Finding the values at the cluster representative coordinates cog_unweighted_value = brain[cog_unweighted] cog_weighted_value = brain[cog_weighted] # Lists to be added to dataframe cog_unweighted_value_list.append(cog_unweighted_value) cog_weighted_value_list.append(cog_weighted_value) # b. Convert the cartesian coordinates to MNI MNI_cog_unweighted = self._XYZ2MNI(cog_unweighted) MNI_cog_weighted = self._XYZ2MNI(cog_weighted) # Convert the list of coordinates to string to get rid of: # Exception: Data must be 1-dimensional str_cog_unweighted = '' for i in MNI_cog_unweighted: str_cog_unweighted = str_cog_unweighted + ' ' + str(i) str_cog_weighted = '' for i in MNI_cog_weighted: str_cog_weighted = str_cog_weighted + ' ' + str(i) # Lists to be added to dataframe MNI_cog_unweighted_list.append(str_cog_unweighted) MNI_cog_weighted_list.append(str_cog_weighted) # c. Report the name of the region # Names of the regions of COG cog_region_name_weighted = \ atlas_obj.getAtlasRegions(MNI_cog_weighted)[1] cog_region_name_unweighted = \ atlas_obj.getAtlasRegions(MNI_cog_unweighted)[1] # print('Region name weighted COG: ',cog_region_name_weighted) # # print('Region name unweighter COG: ',cog_region_name_unweighted) # List created to be added to dataframe cog_region_name_weighted_list.append(cog_region_name_weighted) cog_region_name_unweighted_list.append( cog_region_name_unweighted) # To choose from weighted and unweighted COG options WEIGHTED = True if WEIGHTED: MNI_cog_list = MNI_cog_weighted_list cog_region_name_list = cog_region_name_weighted_list cog_value_list = cog_weighted_value_list else: pass # Sort the Regions bsed on cog value # Get the indices of elements after they are sorted sorted_indices = np.argsort(cog_value_list) # Sort the lists according to the above sorted_indices cog_value_list = np.array(cog_value_list)[sorted_indices] number_overlapping_cluster_voxels_list = \ np.array(number_overlapping_cluster_voxels_list)[sorted_indices] overlapping_cluster_voxels_percentage_list = \ np.array(overlapping_cluster_voxels_percentage_list)[sorted_indices] MNI_cog_list = np.array(MNI_cog_list)[sorted_indices] cog_region_name_list = np.array( cog_region_name_list)[sorted_indices] """ TODO: Convert MNI coordinates from list to string (x,y,z) The next error that I will have to deal with is unequal length arrays. For that append each list with spaces. Then care about ordering the dictionary. """ # Creating a dictionary to create dataframe df_dict = OrderedDict() df_dict['Cluster Number'] = [cluster_number] df_dict['Max Value'] = cog_value_list df_dict['Num Voxels'] = number_overlapping_cluster_voxels_list df_dict['Percentage of Voxel' ] = \ overlapping_cluster_voxels_percentage_list df_dict['MNI Coordinates'] = MNI_cog_list df_dict['Region Name'] = cog_region_name_list df = pd.DataFrame(df_dict) df_report = df_report.append(df) # Empty the lists to be filled again cog_value_list = [] number_overlapping_cluster_voxels_list = [] overlapping_cluster_voxels_percentage_list = [] MNI_cog_list = [] cog_region_name_list = [] """ TODO: The order of the columns is not maintained Test again about the validity of results. The number of voxels is very low. Check it! DONE: Store each of the coordinates in cog_list, names in name_list, values in value_list, number of voxels etc. Find the max of the value_list and corresponding name in name_list and also calculate other details and store them in lists. Create a distionary with all the above created lists. Create a empty data frame and add the above created dictionary in it. ATLAS NAME SIZE (MM) In one For loop create the details about cluster1 and store them in lists as said above. As said above, add these lists in a dictionary. Then this dictionary is added to a dataframe. The table should look like the following: ROI1 Cluster1 MaxValue COG Region Total_#_voxels %_voxels MaxValue COG Region #_voxels %_voxles_overlap Value2 COG Region #_voxels %_voxles_overlap Value3 COG Region #_voxels %_voxles_overlap . . . . . . Cluster2 MaxValue COG Region Total_#_voxels MaxValue COG Region #_voxels %_voxles_overlap Value2 COG Region #_voxels %_voxles_overlap Value3 COG Region #_voxels %_voxles_overlap . . . . . . """ pass brain_zero.fill(0) # d. Number and Percentage of voxels overlapping the region # e. Peak coordinate of the cluster df_report.to_csv(out_file, index=False) return os.path.abspath(out_file), df_report
def com_calc(img, max_size, min_size, lung_img): ''' Calculate the center of mass of each of the labeled regions in img, excluding regions that are outside the lung given in lung_img, or the range size [min_size, max_size], which are reported treated as fractions of the input lung. ''' from scipy.ndimage.measurements import center_of_mass as com # pylint: disable=E1101 arr = sitk.GetArrayFromImage(img) lung_arr = sitk.GetArrayFromImage(lung_img) # Take elements from arr only when lung_arr is not zero, i.e. take only # regions in the lung. arr = np.where(lung_arr != 0, arr, np.zeros(arr.shape, dtype=arr.dtype)) counts = np.bincount(np.ravel(arr)) # volume per voxel is encoded in img spacing, with units mm^3 vox_vol = reduce(lambda x, y: x * y, img.GetSpacing()) # the size of the lung is the size of a voxel times the number of voxels lung_size = np.count_nonzero(lung_arr) * vox_vol # print sorted(counts)[-10:], sorted([c for c in counts if c != 0])[0:10] # print np.count_nonzero(lung_arr)*vox_vol logging.debug("Availiable labels and sizes: %s", [p for p in enumerate(counts) if p[1] > 0]) # We gate the deterministic seeds for their regions being of a reasonable # size. labels = [ label for (label, n_vox) in enumerate(counts) if min_size * lung_size < n_vox * vox_vol < max_size * lung_size ] # we don't want to calculate the COM of the background, no matter what # our min/max sizes are try: labels.remove(0) except ValueError: #Zero wasn't in the list pass # compute the center of mass for each of the elements up to 100 elements com_list = com(np.where(arr != 0, np.ones(arr.shape), np.zeros(arr.shape)), labels=arr, index=labels) logging.debug("Label-COM correspondence: %s", dict(zip(labels, com_list))) # these are array-indexed and we take our seeds to be image-indexed # plus, they're floats and need to be cast back to integers seeds = [[int(k) for k in reversed(s)] for s in com_list if lung_arr[s] == 1] info = { 'nseeds': len(seeds), 'max_size': max_size, 'min_size': min_size, 'seeds': [s for s in seeds] } # deep (enough) copy logging.info("%s in-lung of %s seeds from %s watershed labels", len(seeds), len(labels), len(counts)) return (seeds, info)
def Workflow_npm1_comb(struct_img, mitotic_stage, rescale_ratio, output_type, output_path, fn, output_func=None): ########################################################################## # PARAMETERS: # note that these parameters are supposed to be fixed for the structure # and work well accross different datasets intensity_norm_param = [20, 25] gaussian_smoothing_sigma = 0.25 gaussian_smoothing_truncate_range = 4.0 dot_2d_sigma = 1 dot_2d_sigma_extra = 3 dot_2d_cutoff = 0.035 dot_2d_cutoff_extra = 0.01 minArea = 2 low_level_min_size = 700 ########################################################################## out_img_list = [] out_name_list = [] ################### # PRE_PROCESSING ################### # intenisty normalization (min/max) struct_img = np.reciprocal(struct_img) # inverting to detect dark spot struct_img = intensity_normalization(struct_img, scaling_param=intensity_norm_param) out_img_list.append(struct_img.copy()) out_name_list.append('im_norm') # rescale if needed # if rescale_ratio>0: # struct_img = resize(struct_img, [1, rescale_ratio, rescale_ratio], method="cubic") # struct_img = (struct_img - struct_img.min() + 1e-8)/(struct_img.max() - struct_img.min() + 1e-8) # gaussian_smoothing_truncate_range = gaussian_smoothing_truncate_range * rescale_ratio # smoothing with gaussian filter structure_img_smooth = image_smoothing_gaussian_3d( struct_img, sigma=gaussian_smoothing_sigma, truncate_range=gaussian_smoothing_truncate_range) out_img_list.append(structure_img_smooth.copy()) out_name_list.append('im_smooth') ################### # core algorithm ################### # step 1: low level thresholding # global_median_1 = np.percentile(structure_img_smooth,35) global_median_2 = np.percentile(structure_img_smooth, 30) # 70 for M6M7, 30 for rest # th_low_level_1 = global_median_1 th_low_level_2 = global_median_2 # bw_low_level = (structure_img_smooth > th_low_level_1) + (structure_img_smooth > th_low_level_2) bw_low_level = structure_img_smooth > th_low_level_2 bw_low_level = remove_small_objects(bw_low_level, min_size=low_level_min_size, connectivity=1, in_place=True) seg = dilation(bw_low_level, selem=ball(2)) seg = np.invert(seg) seg = seg.astype(np.uint8) seg[seg > 0] = 255 #################### # POST-Processing using other segmentations structures #################### other_segs_path = "/allen/aics/assay-dev/computational/data/dna_cell_seg_on_production_data/NPM1/new_dna_mem_segmentation/" mem_segs_path = other_segs_path + fn + "_mem_segmentation.tiff" dna_segs_path = other_segs_path + fn + "_dna_segmentation.tiff" if not os.path.exists(mem_segs_path): mem_segs_path = other_segs_path + fn + ".ome_mem_segmentation.tiff" dna_segs_path = other_segs_path + fn + ".ome_dna_segmentation.tiff" mito_seed_path_root = "/allen/aics/assay-dev/computational/data/NPM1_segmentation_improvement/images_with_mitosis/M67/mito_seg/" mito_seed_path = mito_seed_path_root + fn + ".tiff" # Generate seed for mitotic cell if not os.path.exists(mito_seed_path): mito_seed_path = mito_seed_path_root + fn + ".ome.tiff" mito_seed_3d = imread(mito_seed_path) mito_seed_img = np.amax(mito_seed_3d, axis=0) mito_seed = com(mito_seed_img) # label the segmentations # mem_label, num_feat_mem = labeling(imread(mem_segs_path)) # not labeling correctly dna_label, num_feat_dna = labeling(imread(dna_segs_path)) # label # label_mito = mem_label[int(np.floor(mem_label.shape[0]/2)),int(mito_seed[0]),int(mito_seed[1])] # seg = seg * ((mem_label == label_mito)*1) seg[mito_seed_3d == 0] = 0 seg[dna_label > 0] = 0 out_img_list.append(seg.copy()) out_name_list.append('bw_fine') fn += "_combined" if output_type == 'default': # the default final output save_segmentation(seg, False, output_path, fn) elif output_type == 'AICS_pipeline': # pre-defined output function for pipeline data save_segmentation(seg, True, output_path, fn) elif output_type == 'customize': # the hook for passing in a customized output function output_fun(out_img_list, out_name_list, output_path, fn) else: # the hook for pre-defined RnD output functions (AICS internal) img_list, name_list = NPM1_output(out_img_list, out_name_list, output_type, output_path, fn) if output_type == 'QCB': return img_list, name_list
def get_com(self): datmax = self.datas.max() mask = (self.datas > datmax * 0.25) self.center = com(self.datas.T, mask.T)
from scipy.ndimage.measurements import center_of_mass as com from PIL import Image import numpy as np from math import * from matplotlib.pyplot import imsave import glob paths = glob.glob('*/') print(paths) for path in paths: for filename in glob.glob(path + '*.jpg'): img = Image.open(filename) img_array = np.array(img) x_cen, y_cen, z = com(img_array) dx_cen = floor(64 - x_cen) dy_cen = floor(64 - y_cen) img_out = np.roll(img_array, dx_cen, axis=0) img_out = np.roll(img_out, dy_cen, axis=1) imsave(filename,img_out,format='jpeg',cmap='gray') print(path)
#*************************************# RECORDER.sys_text("Generating AIA304 binary mask [r-mask]") LOW_BRIGHTNESS_THRESHOLD = 400 r_mask = np.logical_and(img304 > LOW_BRIGHTNESS_THRESHOLD, img304 < np.inf) r_mask = r_mask.astype(np.uint8) r_mask = cv.dilate(r_mask, np.ones((3,3)).astype(bool).astype(int), iterations = 1) img304 *= r_mask #*************************************# RECORDER.sys_text("Generating AIA304 elliptical mask [e-mask]") center = com(r_mask) x_center = int(center[0] + 0.5) y_center = int(center[1] + 0.5) dim = img304.shape[0] threshold_percent_1 = 0.98 threshold_percent_2 = 0.96 threshold_percent_3 = 0.94 total = float(len(np.where(r_mask == 1)[0])) rad = 2.0 y, x = np.ogrid[-x_center:dim - x_center, -y_center:dim - y_center] e_mask = None mask_out = None while True: temp_in = x**2 + y**2 <= rad**2
def mod_step13_cell_masks(composite, mod_id, algorithm): # paths template = composite.templates.get(name='mask') # MASK TEMPLATE # create batches batch = 0 max_batch_size = 100 # channel cell_mask_channel, cell_mask_channel_created = composite.channels.get_or_create(name='cellmask') # mean # mask_mean_max = np.max([mask.mean for mask in composite.masks.all()]) # iterate over frames for t in range(composite.series.ts): print('step13 | processing mod_step13_cell_masks t{}... '.format(t), end='\r') # one mask for each marker markers = composite.series.markers.filter(t=t) # 1. get masks mask_gon_set = composite.gons.filter(channel__name__in=['pmodreduced','bfreduced'], t=t) bulk = create_bulk_from_image_set(mask_gon_set) for m, marker in enumerate(markers): print('step13 | processing mod_step13_cell_masks t{}, marker {}/{}... '.format(t, m, len(markers)), end='\r') if composite.gons.filter(marker=marker).count()==0: # marker parameters r, c, z = marker.r, marker.c, marker.z other_marker_positions = [(m.r,m.c) for m in markers.exclude(pk=marker.pk)] # get primary mask primary_mask = np.zeros(composite.series.shape(), dtype=float) # blank image mask_uids = [(i, uid) for i,uid in enumerate(bulk.gon_stack[r,c,:]) if uid>0] for i,uid in mask_uids: gon_pk = bulk.rv[i] mask = composite.masks.get(gon__pk=gon_pk, mask_id=uid) mask_array = (bulk.slice(pk=mask.gon.pk)==mask.mask_id).astype(float) # modify mask array based on parameters mask_z, mask_max_z, mask_mean, mask_std = mask.z, mask.max_z, mask.mean, mask.std z_term = 1.0 / (1.0 + 0.1*np.abs(z - mask_z)) # suppress z levels at increasing distances from marker max_z_term = 1.0 / (1.0 + 0.1*np.abs(z - mask_max_z)) # suppress z levels at increasing distances from marker # mean_term = mask_mean / mask_mean_max # raise mask according to mean std_term = 1.0 mask_array = mask_array * z_term * max_z_term * std_term # add to primary mask primary_mask += mask_array # get secondary mask - get unique masks that touch the edge of the primary mask secondary_mask = np.zeros(composite.series.shape(), dtype=float) # blank image secondary_mask_uids = [] edges = np.where(edge_image(primary_mask>0)) for r, c in zip(*edges): for i,uid in enumerate(bulk.gon_stack[r,c,:]): if (i,uid) not in secondary_mask_uids and (i,uid) not in mask_uids and uid>0: secondary_mask_uids.append((i,uid)) for i,uid in secondary_mask_uids: print('step13 | processing mod_step13_cell_masks t{}, marker {}/{}, secondary {}/{}... '.format(t, m, len(markers), i, len(secondary_mask_uids)), end='\r') gon_pk = bulk.rv[i] mask = composite.masks.get(gon__pk=gon_pk, mask_id=uid) mask_array = (bulk.slice(pk=mask.gon.pk)==mask.mask_id).astype(float) # modify mask array based on parameters mask_z, mask_max_z, mask_mean, mask_std = mask.z, mask.max_z, mask.mean, mask.std z_term = 1.0 / (1.0 + 0.1*np.abs(z - mask_z)) # suppress z levels at increasing distances from marker max_z_term = 1.0 / (1.0 + 0.1*np.abs(z - mask_max_z)) # suppress z levels at increasing distances from marker # mean_term = mask_mean / mask_mean_max # raise mask according to mean std_term = 1.0 foreign_marker_condition = 1.0 # if the mask contains a different marker foreign_marker_match = False foreign_marker_counter = 0 while not foreign_marker_match and foreign_marker_counter!=len(other_marker_positions)-1: r, c = other_marker_positions[foreign_marker_counter] foreign_marker_match = (mask_array>0)[r,c] if foreign_marker_match: foreign_marker_condition = 0.0 foreign_marker_counter += 1 mask_array = mask_array * z_term * max_z_term * std_term * foreign_marker_condition # add to primary mask secondary_mask += mask_array print('step13 | processing mod_step13_cell_masks t{}, marker {}/{}, saving square mask... '.format(t, m, len(markers)), end='\n' if t==composite.series.ts-1 else '\r') cell_mask = primary_mask + secondary_mask # finally, mean threshold mask cell_mask[cell_mask<nonzero_mean(cell_mask)] = 0 cell_mask[cell_mask<nonzero_mean(cell_mask)] = 0 # cut to size # I want every mask to be exactly the same size -> 128 pixels wide # I want the centre of the mask to be in the centre of image # Add black space around even past the borders of larger image # 1. determine centre of mass com_r, com_c = com(cell_mask>0) mask_square = np.zeros((256,256), dtype=float) if not np.isnan(com_r): # 2. cut to black and preserve boundaries cut, (cr, cc, crs, ccs) = cut_to_black(cell_mask) # 3. place cut inside square image using the centre of mass and the cut boundaries to hit the centre dr, dc = int(128 + cr - com_r), int(128 + cc - com_c) # 4. preserve coordinates of square to position gon small_r, small_c = mask_square[dr:dr+crs,dc:dc+ccs].shape mask_square[dr:dr+crs,dc:dc+ccs] = cut[:small_r,:small_c] # check batch and make folders, set url if not os.path.exists(os.path.join(composite.experiment.cp2_path, composite.series.name, str(batch))): os.makedirs(os.path.join(composite.experiment.cp2_path, composite.series.name, str(batch))) if len(os.listdir(os.path.join(composite.experiment.cp2_path, composite.series.name, str(batch))))>=max_batch_size: batch += 1 if not os.path.exists(os.path.join(composite.experiment.cp2_path, composite.series.name, str(batch))): os.makedirs(os.path.join(composite.experiment.cp2_path, composite.series.name, str(batch))) root = os.path.join(composite.experiment.cp2_path, composite.series.name, str(batch)) # CP PATH # cell mask gon cell_mask_gon = composite.gons.create(experiment=composite.experiment, series=composite.series, channel=cell_mask_channel, template=template) cell_mask_gon.set_origin(cr-dr, cc-dc, z, t) cell_mask_gon.set_extent(crs, ccs, 1) id_token = generate_id_token('img','Gon') cell_mask_gon.id_token = id_token file_name = template.rv.format(id_token) url = os.path.join(root, file_name) imsave(url, mask_square.copy()) cell_mask_gon.paths.create(composite=composite, channel=cell_mask_channel, template=template, url=url, file_name=file_name, t=t, z=z) # associate with marker marker.gon = cell_mask_gon cell_mask_gon.marker = marker marker.save() cell_mask_gon.save()