def qc_background_regions(intensity_imp, bg_rois): """allow the user to view and correct automatically-determined background regions""" imp = Duplicator().run(intensity_imp); imp.setTitle("Background region QC"); imp.show(); imp.setPosition(1); autoset_zoom(imp); imp.setRoi(bg_rois[0]); IJ.setTool("freehand"); notOK = True; while notOK: listener = UpdateRoiImageListener(bg_rois, is_area=True); imp.addImageListener(listener); dialog = NonBlockingGenericDialog("Background region quality control"); dialog.enableYesNoCancel("Continue", "Use this region for all t"); dialog.setCancelLabel("Cancel analysis"); dialog.addMessage("Please redraw background regions as necessary...") dialog.showDialog(); if dialog.wasCanceled(): raise KeyboardInterrupt("Run canceled"); elif not(dialog.wasOKed()): this_roi = imp.getRoi(); bg_rois = [this_roi for _ in listener.getRoiList()]; imp.removeImageListener(listener); else: last_roi = imp.getRoi(); qcd_bg_rois = listener.getRoiList(); if imp.getNFrames() > imp.getNSlices(): qcd_bg_rois[imp.getT() - 1] = last_roi; else: qcd_bg_rois[imp.getZ() - 1] = last_roi; notOK = False; imp.removeImageListener(listener); imp.changes = False; imp.close(); return qcd_bg_rois;
def main(): #print (sys.version_info) # debug #print(sys.path) # debug data_root = r'C:\Users\dougk\Desktop\test' # debug output_root = r'C:\Users\dougk\Desktop\test' #debug #default_directory = r'C:\\Users\\Doug\\Desktop\\test'; #data_root, output_root = file_location_chooser(default_directory); if (data_root is None) or (output_root is None): raise IOError("File location dialogs cancelled!") timestamp = datetime.strftime(datetime.now(), "%Y-%m-%d %H.%M.%S") output_path = os.path.join(output_root, (timestamp + " output")) for file_path in filterByFileType(os.listdir(data_root), '.tif'): subfolder_name = os.path.splitext(file_path)[0] output_subfolder = os.path.join(output_path, subfolder_name) print(output_subfolder) os.makedirs(output_subfolder) imps = bf.openImagePlus(os.path.join(data_root, file_path)) imp = imps[0] imp.show() h = imp.height w = imp.width slices = imp.getNSlices() channels = imp.getNChannels() frames = imp.getNFrames() # rotation step - since using multiples of 90, TransformJ.Turn is more efficient IJ.run("Enhance Contrast", "saturated=0.35") angleZ = 1 while ((angleZ % 90) > 0): gd = GenericDialog("Rotate?") gd.addMessage( "Define rotation angle - increments of 90. Apical at top") gd.addNumericField("Rotation angle", 0, 0) gd.showDialog() angleZ = int(gd.getNextNumber()) if (angleZ > 1): IJ.run("TransformJ Turn", "z-angle=" + str(angleZ) + " y-angle=0 x-angle=0") imp.close() imp = WindowManager.getCurrentImage() imp.setTitle(file_path) # trim time series IJ.run("Enhance Contrast", "saturated=0.35") imp.setDisplayMode(IJ.COLOR) WaitForUserDialog( "Scroll to the first frame of the period of interest and click OK" ).show() start_frame = imp.getT() WaitForUserDialog( "Scroll to the last frame of the period of interest and click OK" ).show() end_frame = imp.getT() trim_imp = Duplicator().run(imp, 1, channels, 1, slices, start_frame, end_frame) imp.close() trim_imp.show() dup_imp = Duplicator().run(trim_imp) # create images to process and find bounds for dup_imps = ChannelSplitter().split(dup_imp) myo_imp = dup_imps[1] mem_imp = dup_imps[0] FileSaver(myo_imp).saveAsTiffStack( os.path.join(output_subfolder, "myosin_channel.tif")) FileSaver(mem_imp).saveAsTiffStack( os.path.join(output_subfolder, "membrane_channel.tif")) # set basal bounds myo_imp.show() ImageConverter(myo_imp).convertToGray8() frames = myo_imp.getNFrames() gb = GaussianBlur() for fridx in range(0, frames): myo_imp.setSliceWithoutUpdate(fridx + 1) ip = myo_imp.getProcessor() gb.blurGaussian(ip, 5.0, 1.0, 0.02) # assymmetrical Gaussian IJ.run(myo_imp, "Convert to Mask", "method=Otsu background=Dark calculate") IJ.run("Despeckle", "stack") title = myo_imp.getTitle() # assume that first frame is good quality image... basal_edges = find_basal_edges(myo_imp) #myo_imp.hide() mem_imp.hide() # draw some edges for checking roim = RoiManager() xs = [x for x in range(1, trim_imp.getWidth() + 1)] trim_imp.show() for fridx in range(0, myo_imp.getNFrames()): trim_imp.setPosition(2, 1, fridx + 1) IJ.run("Enhance Contrast", "saturated=0.35") roi = PolygonRoi(xs, basal_edges[fridx], Roi.POLYLINE) trim_imp.setRoi(roi) roim.addRoi(roi)
def calculate_outputs(params, calculated_objects, split_channels, inner_outer_intensity_data=None, repeat_fraction=1): """generate curvatures, lengths, areas etc.""" membrane_channel_imp = split_channels[0] actin_channel_imp = split_channels[1] segmentation_channel_imp = split_channels[2] # do calculations independent of source of edges actin_profiles = [] curvature_profiles = [] lengths_areas_and_arearois = [ mb.bleb_area(medge, params.manual_anchor_midpoint[0]) for medge in calculated_objects.membrane_edges ] mb_lengths = [ laaroi[0] * params.pixel_physical_size for laaroi in lengths_areas_and_arearois ] full_membrane_lengths = [ params.pixel_physical_size * edge.getLength() for edge in calculated_objects.membrane_edges ] euclidean_membrane_lengths = [ params.pixel_physical_size * mb.vector_length( (edge.getPolygon().xpoints[0], edge.getPolygon().ypoints[0]), (edge.getPolygon().xpoints[-1], edge.getPolygon().ypoints[-1])) for edge in calculated_objects.membrane_edges ] mb_areas = [ laaroi[1] * math.pow(params.pixel_physical_size, 2) for laaroi in lengths_areas_and_arearois ] mb_area_rois = [laaroi[2] for laaroi in lengths_areas_and_arearois] # save membrane channel with original anchors, fixed anchors and membrane edge for assessment of performance mbfig.save_membrane_edge_image(membrane_channel_imp, calculated_objects.fixed_anchors_list, calculated_objects.membrane_edges, mb_area_rois, params) # perform analysis of background regions bg_rois = mb.generate_background_rois(None, params, calculated_objects.membrane_edges, threshold_method='MinError', membrane_imp=membrane_channel_imp) # resegment, allowing more conservative guess at bg region, or... #bg_rois = mb.generate_background_rois(segmentation_channel_imp, params, calculated_objects.membrane_edges); # use existing segmentation # do qc if params.qc_background_rois: bg_rois = mbui.qc_background_regions(actin_channel_imp, bg_rois) mbio.save_qcd_edges2(bg_rois, params.output_path, "background regions.zip") calculated_objects.background_sd_profile = mb.get_stddevs_by_frame_and_region( actin_channel_imp, bg_rois) t0_actin_mean = None for fridx in range(membrane_channel_imp.getNFrames()): # generate curvature - this needs to be looped over slices membrane_edge = calculated_objects.membrane_edges[fridx] curv_profile = mb.calculate_curvature_profile(membrane_edge, params) curvature_profiles.append(curv_profile) # generate actin-channel line profile if actin channel present if actin_channel_imp is None: actin_channel_imp = Duplicator().run(membrane_channel_imp) actin_channel_imp.setPosition(fridx + 1) actin_channel_imp, t0_actin_mean = mb.apply_photobleach_correction_framewise( params, actin_channel_imp, segmentation_channel_imp, t0_value=t0_actin_mean) actin_profile = mb.maximum_line_profile( actin_channel_imp, membrane_edge, int( round(params.intensity_profile_width_um / params.pixel_physical_size))) actin_profiles.append(actin_profile) if params.inner_outer_comparison: mean_intensity = float(sum([a for ( (x, y), a) in actin_profile])) / len(actin_profile) calculated_objects.inner_outer_data.outer_means.append( mean_intensity ) if repeat_fraction == 1 else calculated_objects.inner_outer_data.inner_means.append( mean_intensity) sd = math.sqrt( sum((x - mean_intensity)**2 for ((x, y), a) in actin_profile) / len(actin_profile)) calculated_objects.inner_outer_data.outer_sds.append( sd ) if repeat_fraction == 1 else calculated_objects.inner_outer_data.inner_sds.append( sd) calculated_objects.curvature_profiles = curvature_profiles calculated_objects.actin_profiles = actin_profiles calculated_objects.bleb_perimeter_lengths = mb_lengths calculated_objects.bleb_areas = mb_areas calculated_objects.full_membrane_lengths = full_membrane_lengths calculated_objects.euclidean_membrane_lengths = euclidean_membrane_lengths params.setPhysicalCurvatureUnit(params.pixel_unit + u'\u02C9' + u'\u00B9') return calculated_objects