def mod_step09_regions(composite, mod_id, algorithm): # paths template = composite.templates.get(name='region') # REGION TEMPLATE mask_template = composite.templates.get(name='mask') # get region img set that has the region template region_img_set = composite.gons.filter(channel__name='-regionimg', template__name='region') # channel region_channel, region_channel_created = composite.channels.get_or_create(name='-regions') # iterate for t in range(composite.series.ts): region_img = region_img_set.filter(t=t) if region_img.count()==0: region_img = region_img_set.get(t=t-1) else: region_img = region_img_set.get(t=t) # for each image, determine unique values of labelled array # make gon with label array and save region_gon = composite.gons.create(experiment=composite.experiment, series=composite.series, channel=region_channel, template=template) region_gon.set_origin(0, 0, 0, t) region_gon.set_extent(composite.series.rs, composite.series.cs, 1) # modify image region_array = region_img.load() region_array = region_array[:,:,0] region_array[region_array>0] = 1 region_array, n = label(region_array) region_gon.array = region_array.copy() region_gon.save_array(os.path.join(composite.experiment.mask_path, composite.series.name), template) for unique_value in [u for u in np.unique(region_array) if u>0]: # 1. cut image to single value unique_image = np.zeros(region_array.shape) unique_image[region_array==unique_value] = 1 cut, (r,c,rs,cs) = cut_to_black(unique_image) # 2. make gon with cut image and associate to gon gon = region_gon.gons.create(experiment=composite.experiment, series=composite.series, channel=region_channel, template=mask_template) gon.id_token = generate_id_token('img','Gon') gon.set_origin(r,c,0,t) gon.set_extent(rs,cs,1) gon.array = cut.copy() gon.save_mask(composite.experiment.sub_mask_path) gon.save() # 3. make mask with cut image and associate to gon2 mask = region_gon.masks.create(composite=composite, channel=region_channel, mask_id=unique_value) mask.set_origin(r,c,0) mask.set_extent(rs,cs)
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 mod_step11_masks(composite, mod_id, algorithm): # templates cp_template = composite.templates.get(name='cp') mask_template = composite.templates.get(name='mask') for t in range(composite.series.ts): # get gfp gfp_gon = composite.gons.get(channel__name='0', t=t) smooth_gfp = gf(exposure.rescale_intensity(gfp_gon.load() * 1.0), sigma=3) # mask img set mask_gon_set = composite.gons.filter(channel__name__in=['bfreduced','pmodreduced'], template__name='cp', t=t) for mask_gon in mask_gon_set: # load and get unique values mask_array = mask_gon.load() # unique for unique_value in [u for u in np.unique(mask_array) if u>0]: print('step11 | processing mod_step11_masks... {}: {} masks '.format(mask_gon.paths.get().file_name, unique_value), end='\r') # 1. cut image to single value unique_image = mask_array==unique_value cut, (r,c,rs,cs) = cut_to_black(unique_image) # smaller masked gfp array mini_masked_array = np.ma.array(smooth_gfp[r:r+rs, c:c+cs, :], mask=np.dstack([np.invert(cut)]*smooth_gfp.shape[2]), fill_value=0) # squeeze into column column = np.sum(np.sum(mini_masked_array.filled(), axis=0), axis=0) # details max_z = np.argmax(column) mean = np.mean(column) std = np.std(column) # 3. make mask with cut image and associate to gon2 mask = mask_gon.masks.create(composite=composite, channel=mask_gon.channel, mask_id=unique_value) mask.set_origin(r,c,mask_gon.z) mask.set_extent(rs,cs) mask.set_gfp(max_z, mean, std)
def mod_tile(composite, mod_id, algorithm, **kwargs): tile_path = os.path.join(composite.experiment.video_path, "tile", composite.series.name) if not os.path.exists(tile_path): os.makedirs(tile_path) for t in range(composite.series.ts): zbf_gon = composite.gons.get(t=t, channel__name="-zbf") zcomp_gon = composite.gons.get(t=t, channel__name="-zcomp") zmean_gon = composite.gons.get(t=t, channel__name="-zmean") mask_mask = composite.masks.get(t=t, channel__name__contains=kwargs["channel_unique_override"]) zbf = zbf_gon.load() zcomp = zcomp_gon.load() zmean = zmean_gon.load() mask = mask_mask.load() mask_outline = mask_edge_image(mask) zbf_mask_r = zbf.copy() zbf_mask_g = zbf.copy() zbf_mask_b = zbf.copy() zcomp_mask_r = zcomp.copy() zcomp_mask_g = zcomp.copy() zcomp_mask_b = zcomp.copy() # drawing # 1. draw outlines in red channel zbf_mask_r[mask_outline > 0] = 255 zbf_mask_g[mask_outline > 0] = 0 zbf_mask_b[mask_outline > 0] = 0 zcomp_mask_r[mask_outline > 0] = 255 zcomp_mask_g[mask_outline > 0] = 0 zcomp_mask_b[mask_outline > 0] = 0 markers = composite.markers.filter(track_instance__t=t, track__cell__isnull=False) for marker in markers: if hasattr(marker.track_instance, "cell_instance"): # 2. draw markers in blue channel zbf_mask_r[marker.r - 2 : marker.r + 3, marker.c - 2 : marker.c + 3] = 0 zbf_mask_g[marker.r - 2 : marker.r + 3, marker.c - 2 : marker.c + 3] = 0 zbf_mask_b[marker.r - 2 : marker.r + 3, marker.c - 2 : marker.c + 3] = 255 zcomp_mask_r[marker.r - 2 : marker.r + 3, marker.c - 2 : marker.c + 3] = 0 zcomp_mask_g[marker.r - 2 : marker.r + 3, marker.c - 2 : marker.c + 3] = 0 zcomp_mask_b[marker.r - 2 : marker.r + 3, marker.c - 2 : marker.c + 3] = 255 # 3. draw text in green channel blank_slate = np.zeros(zbf.shape) blank_slate_img = Image.fromarray(blank_slate) draw = ImageDraw.Draw(blank_slate_img) draw.text( (marker.c + 5, marker.r + 5), "{}".format(marker.track.cell.pk), 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] = 255 zbf_mask_b[blank_slate > 0] = 0 zcomp_mask_r[blank_slate > 0] = 0 zcomp_mask_g[blank_slate > 0] = 255 zcomp_mask_b[blank_slate > 0] = 0 # regions region_mask = composite.masks.get(t=t, channel__name__contains=composite.current_region_unique).load() region_mask_edges = mask_edge_image(region_mask) zbf_mask_r[region_mask_edges > 0] = 100 zbf_mask_g[region_mask_edges > 0] = 100 zbf_mask_b[region_mask_edges > 0] = 100 zcomp_mask_r[region_mask_edges > 0] = 100 zcomp_mask_g[region_mask_edges > 0] = 100 zcomp_mask_b[region_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) draw.text( (c0 + 30, r0 + 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 zcomp_mask_r[blank_slate > 0] = 0 zcomp_mask_g[blank_slate > 0] = 0 zcomp_mask_b[blank_slate > 0] = 255 # tile zbf, zbf_mask, zcomp, zcomp_mask top_half = np.concatenate((np.dstack([zbf, zbf, zbf]), np.dstack([zbf_mask_r, zbf_mask_g, zbf_mask_b])), axis=0) bottom_half = np.concatenate( (np.dstack([zmean, zmean, zmean]), np.dstack([zcomp_mask_r, zcomp_mask_g, zcomp_mask_b])), axis=0 ) whole = np.concatenate((top_half, bottom_half), axis=1) imsave( join( tile_path, "tile_{}_s{}_t{}.tiff".format( composite.experiment.name, composite.series.name, str_value(t, composite.series.ts) ), ), whole, )
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()