def do_tubefitting(im_path=im_test_path, metadata_path=metadata_test_path, output_path=output_path, save_output=False): # todo: fix things so that all operations use a consistent definition of background rather than changing Prefs on the fly... Prefs.blackBackground = False info = PrescreenInfo() info.load_info_from_json(metadata_path) z_xy_ratio = abs( info.get_z_plane_spacing_um()) / info.get_xy_pixel_size_um() #z_xy_ratio = 1.0; bfimp = bf.openImagePlus(im_path) imp = bfimp[0] imp.show() IJ.run(imp, "Set Scale...", "distance=0 known=0 pixel=1 unit=pixel") imp = utils.downsample_for_isotropy(imp, extra_downsample_factor=1.0, info=info) rot_seg_imp, rot_proj_imp, egfp_mch_imps = split_and_rotate(imp, info) depth = rot_seg_imp.getNSlices() if rot_seg_imp.getNSlices( ) > rot_seg_imp.getNFrames() else rot_seg_imp.getNFrames() width = rot_seg_imp.getWidth() height = int(round(rot_seg_imp.getHeight() * z_xy_ratio)) # Apply 3d MEDIAN FILTER to denoise and emphasise vessel-associated voxels fit_basis_imp = threshold_and_binarise(rot_seg_imp, z_xy_ratio) fit_basis_imp.setTitle("fit_basis_imp") fit_basis_imp.show() # plane-wise, use binary-outline # say the non-zero points then make up basis for fitting to be performed per http://nicky.vanforeest.com/misc/fitEllipse/fitEllipse.html rois = [] centres = [] major_axes = [] roi_imp = IJ.createImage("rois", width, height, depth, 32) pts_stack = ImageStack(width, height + 1) IJ.run(imp, "Line Width...", "line=3") for zidx in range(fit_basis_imp.getNSlices()): fit_basis_imp.setZ(zidx + 1) IJ.run(fit_basis_imp, "Outline", "slice") IJ.run(fit_basis_imp, "Create Selection", "") roi = fit_basis_imp.getRoi() fit_basis_imp.killRoi() pts = [(pt.x, pt.y) for pt in roi.getContainedPoints()] clean_pts = convex_hull_pts(pts) clean_pts = [(x, z_xy_ratio * y) for (x, y) in clean_pts] # make a stack of clean points... ip = FloatProcessor(width, height + 1) pix = ip.getPixels() for pt in clean_pts: pix[int(pt[1]) * width + int(pt[0])] = 128 pts_stack.addSlice(ip) centre, angle, axl = ellipse_fitting.fit_ellipse(clean_pts) major_axes.append(max(axl)) centres.append(centre) rot_seg_imp.setZ(zidx + 1) ellipse_roi = ellipse_fitting.generate_ellipse_roi(centre, angle, axl) rois.append(ellipse_roi) IJ.run(imp, "Line Width...", "line=1") cal = imp.getCalibration() smooth_centres, tangent_vecs = generate_smoothed_vessel_axis( centres, pixel_size_um=cal.pixelDepth) for zidx in range(fit_basis_imp.getNSlices()): centre = smooth_centres[zidx] major_axis = major_axes[zidx] ellipse_roi = EllipseRoi(centre[0] - 2, centre[1], centre[0] + 2, centre[1], 1.0) roi_imp.setZ(zidx + 1) roi_imp.setRoi(ellipse_roi) IJ.run(roi_imp, "Set...", "value=" + str(roi_imp.getProcessor().maxValue()) + " slice") pts_stack_imp = ImagePlus("Cleaned points", pts_stack) pts_stack_imp.setTitle("pts_stack_imp") pts_stack_imp.show() rot_seg_imp.changes = False rot_seg_imp.close() egfp_imp = egfp_mch_imps[0] mch_imp = egfp_mch_imps[1] imps_to_combine = [egfp_mch_imps[1], egfp_mch_imps[0], roi_imp] egfp_imp.show() mch_imp.show() roi_imp.show() print("box height um = " + str(roi_imp.getNSlices() * info.get_xy_pixel_size_um())) IJ.run( egfp_imp, "Size...", "width=" + str(width) + " height=" + str(height) + " depth=" + str(depth) + " average interpolation=Bilinear") IJ.run( mch_imp, "Size...", "width=" + str(width) + " height=" + str(height) + " depth=" + str(depth) + " average interpolation=Bilinear") #IJ.run("Merge Channels...", "c1=[" + mch_imp.getTitle() + # "] c2=[" + egfp_imp.getTitle() + # "] c7=[" + roi_imp.getTitle() + "] create keep"); composite_imp = RGBStackMerge().mergeChannels(imps_to_combine, False) print(composite_imp) composite_imp.show() print("end of vessel centerline id step, image dims = ({}x{}x{})".format( composite_imp.getWidth(), composite_imp.getHeight(), composite_imp.getNSlices())) WaitForUserDialog("pause").show() # do qc here? #WM.getImage("Composite").addImageListener(UpdateRoiImageListener(rois)); IJ.run(roi_imp, "8-bit", "") if save_output: FileSaver(composite_imp).saveAsTiffStack( os.path.join(output_path, "segmentation result.tif")) print(roi_imp) FileSaver(roi_imp).saveAsTiff( os.path.join(output_path, "vessel axis.tif")) egfp_imp.changes = False mch_imp.changes = False roi_imp.changes = False fit_basis_imp.changes = False pts_stack_imp.changes = False egfp_imp.close() mch_imp.close() #roi_imp.close(); fit_basis_imp.close() pts_stack_imp.close() zcoords = [i for i in range(composite_imp.getNSlices())] xyz_smooth_centres = [(x, y, z) for ((x, y), z) in zip(smooth_centres, zcoords)] composite_imp2 = straighten_vessel(composite_imp, xyz_smooth_centres, save_output=True) composite_imp3 = straighten_vessel(composite_imp2, xyz_smooth_centres, it=2, save_output=True) return composite_imp3
#Get ROI from cell channel ip1 = cellstack.getProcessor(zslice) ip1.resetMinAndMax() ip1.blurGaussian(parameters['cellsigma']) bp1 = ip1.convertToByte(1) impBin1 = ImagePlus('BinarizedCells ' + str(zslice), bp1) impBin1.show() IJ.run('Auto Threshold', 'method=' + parameters['cellmethod'] + ' white') IJ.run( 'Analyze Particles...', 'size=' + parameters['cellsize'] + ' circularity=' + parameters['cellcircularity'] + ' exclude add') if rmi.getCount() == 0: print 'No cell ROI on slice ' + str(zslice) impBin1.changes = False impBin1.close() continue #Get nuclei ROIs ip2 = nucleistack.getProcessor(zslice) ip2.resetMinAndMax() ip2.blurGaussian(parameters['nucsigma']) bp2 = ip2.convertToByte(1) impBin2 = ImagePlus('BinarizedNuclei', bp2) impBin2.show() rmi.select(impBin2, rmi.getCount() - 1) IJ.setBackgroundColor(0, 0, 0) IJ.run('Clear Outside') impBin2.deleteRoi() IJ.selectWindow('BinarizedNuclei')
ecdOut.append(ecd) con = 1.0-(lMode[j]/iZero) conOut.append(con) cirOut.append(lCirc[j]) arOut.append(lAspRat[j]) rndOut.append(lRound[j]) solOut.append(lSolid[j]) orig.show() outPth = sRptImgPath + strName + ".png" # burn a scale bar and save the image IJ.run(orig, "RGB Color", "") IJ.run(orig, "Add Scale Bar", strBar) IJ.saveAs(orig, "PNG", outPth) orig.changes = False orig.close() print("%d particles detected in image %s" % (nMeas, strNum)) # prepare the output file f=open(sRptCsvPath, 'w') strLine = 'img, part, ecd.nm, contrast, circ, a.r, round, solidity\n' f.write(strLine) for k in range(len(ecdOut)): strLine = "%d, %d, %.2f, %.4f, %.4f, %.4f, %.4f, %.4f\n" % (imgOut[k], parOut[k], ecdOut[k], conOut[k], cirOut[k], arOut[k], rndOut[k], solOut[k] ) f.write(strLine) f.close() toc = time.time()
IJ.run(imp, "Duplicate...", "title=wy") #create wy by rotating wx by 90 degrees IJ.run("Rotate 90 Degrees Left") imp2 = IJ.getImage() imp2.changes = False #integration in the phase domain by shifting Pi/2, see equation 21 in Frankot-Chellapa A = ImageCalculator().run("Multiply create 32-bit stack", DZDX, imp) B = ImageCalculator().run("Multiply create 32-bit stack", DZDY, imp2) # numerator of C = ImageCalculator().run("Add create 32-bit stack", A, B) # eq 21 D = ImageCalculator().run("Multiply create 32-bit", imp, imp) # square wx E = ImageCalculator().run("Multiply create 32-bit", imp2, imp2) # square wy F = ImageCalculator().run("Add create 32-bit", D, E) # demnominator of eq 21 Z = ImageCalculator().run("Divide create 32-bit stack", C, F) # solve eq 21 Z.show() IJ.run("Inverse FFT") #results of integration IJ.run( "Stack to Images" ) #separate real and imaginary... why does imaginary produce result? more reading needed. #clean-up by closing un-necessary images imp2.close() DZDX.close() DZDY.close() imp.changes = False imp.close() A.changes = False A.close() Z.close()
def perform_user_qc(in_imp, edges, alt_edges, fixed_anchors_list, params): """allow the user to intervene to fix erroneously identified membrane edges""" n_frames = in_imp.getNFrames(); n_channels = in_imp.getNChannels(); output_folder = params.output_path; current_edges = edges; rgbstack = ImageStack(in_imp.getWidth(), in_imp.getHeight()); if n_frames > 1: for tidx in range(n_frames): in_imp.setT(tidx+1); ip = in_imp.getProcessor(); rgbip = ip.convertToRGB(); rgbstack.addSlice(rgbip); else: for cidx in range(n_channels): in_imp.setC(cidx+1); ip = in_imp.getProcessor(); rgbip = ip.convertToRGB(); rgbstack.addSlice(rgbip); imp = ImagePlus(("RGB " + in_imp.getTitle()), rgbstack); IJ.run("Colors...", "foreground=red background=white selection=yellow"); for tidx in range(imp.getNSlices()): imp.setSlice(tidx+1); for anchor in params.manual_anchor_positions: imp.setRoi(PointRoi(anchor[0], anchor[1])); IJ.run(imp, "Draw", "slice"); imp.show(); autoset_zoom(imp); imp.setPosition(1); imp.setRoi(current_edges[0]); if n_frames > 1: listener = UpdateRoiImageListener(current_edges); imp.addImageListener(listener); IJ.setTool("freeline"); do_flip = True; while do_flip: dialog = NonBlockingGenericDialog("User quality control"); dialog.enableYesNoCancel("Continue", "Flip all edges"); dialog.setCancelLabel("Cancel analysis"); dialog.addMessage("Please redraw the membrane edges as necessary, \n" + "making sure to draw beyond anchor points at either end...\n" + "Click OK when done. "); p = Panel(); but = Button("Flip this edge"); al = Listener(edges, alt_edges, imp); but.addActionListener(al); p.add(but); dialog.addPanel(p); dialog.showDialog(); if dialog.wasCanceled(): raise KeyboardInterrupt("Run canceled"); elif dialog.wasOKed(): do_flip = False; else: print("flip edges"); do_flip = True; if n_frames > 1: imp.removeImageListener(listener); current_edges = alt_edges if (current_edges == edges) else edges; imp.setPosition(1); imp.setRoi(current_edges[0]); if n_frames > 1: listener = UpdateRoiImageListener(current_edges); imp.addImageListener(listener); last_roi = imp.getRoi(); if n_frames > 1: qcd_edges = listener.getRoiList(); if imp.getNFrames() > imp.getNSlices(): qcd_edges[imp.getT() - 1] = last_roi; else: qcd_edges[imp.getZ() - 1] = last_roi; imp.removeImageListener(listener); else: qcd_edges = [last_roi]; mbio.save_qcd_edges2(qcd_edges, output_folder); # next four lines are a quick and dirty hack... if n_frames > 1: nframes = imp.getNFrames() if imp.getNFrames()>imp.getNSlices() else imp.getNSlices(); else: nframes = n_frames; for fridx in range(0, nframes): if (qcd_edges[fridx].getType()==Roi.FREELINE) or (qcd_edges[fridx].getType()==Roi.POLYLINE): if (fridx == 0) or params.constrain_anchors: anchors = params.manual_anchor_positions; else: anchors = fixed_anchors_list[fridx - 1]; fixed_anchors = mb.fix_anchors_to_membrane(anchors, qcd_edges[fridx], params); fixed_anchors = mb.order_anchors(fixed_anchors, params.manual_anchor_midpoint); fixed_anchors_list[fridx] = fixed_anchors; poly = qcd_edges[fridx].getInterpolatedPolygon(0.25, False); polypoints = [(x,y) for x,y in zip(poly.xpoints, poly.ypoints)]; idx = [polypoints.index(fixed_anchors[0]), polypoints.index(fixed_anchors[1])]; idx.sort(); polypoints = polypoints[idx[0]:idx[1]]; newedge = PolygonRoi([x for (x,y) in polypoints], [y for (x,y) in polypoints], Roi.POLYLINE); newedge = mb.check_edge_order(anchors, newedge); imp.setPosition(fridx + 1); imp.setRoi(newedge); IJ.run(imp, "Interpolate", "interval=1.0 smooth adjust"); IJ.run(imp, "Fit Spline", ""); qcd_edges[fridx] = imp.getRoi(); mbio.save_qcd_edges2(qcd_edges, output_folder); imp.changes = False; imp.close(); return qcd_edges, fixed_anchors_list;
def main(): # ensure consistent preference settings Prefs.blackBackground = False; # get locations for previous and new outputs params = Parameters(); params.loadLastParams(); output_folder_old, output_folder = mbio.rerun_location_chooser(params.input_image_path); params.loadParametersFromJson(os.path.join(output_folder_old, 'parameters used.json')); params.setOutputPath(output_folder); # get original image file (for overlays etc.) if not os.path.isfile(params.input_image_path): mbui.warning_dialog(["The original data can't be found at the location specified in saved parameters. ", "(Possibly something as simple as a change in network drive mapping has occurred)", "Please specify the location of the original image file..."]); params.setInputImagePath(mbio.input_file_location_chooser(params.output_path)); import_opts, params = mbui.choose_series(params.input_image_path, params); imps = bf.openImagePlus(import_opts); imp = imps[0]; if imp.getNSlices() > 1: mbui.warning_dialog(["More than one Z plane detected.", "I will do a maximum projection before proceeding", "Continue?"]); imp = ZProjector.run(imp,"max all"); # prompt user to select ROI original_imp = Duplicator().run(imp); _, crop_params = mbui.crop_to_ROI(imp, params); imp.show(); if crop_params is not None: params.perform_spatial_crop = True; mbui.autoset_zoom(imp); imp.updateAndDraw(); review_crop = mb.check_cropping(output_folder_old, params); keep_crop = not review_crop; if review_crop: keep_crop = mbui.crop_review(); if not keep_crop: imp.changes = False; imp.close(); imp = original_imp; else: original_imp.close(); else: original_imp.close(); # prompt user to do time cropping imp, start_end_tuple = mbui.time_crop(imp, params); params.setTimeCropStartEnd(start_end_tuple); params = mbio.get_metadata(params); params.setCurvatureLengthUm(round(params.curvature_length_um / params.pixel_physical_size) * params.pixel_physical_size); params.persistParameters(); IJ.run(imp, "Set Scale...", "distance=0 known=0 pixel=1 unit=pixel"); imp.show(); if imp.getNChannels() > 1: imp.setPosition(params.membrane_channel_number, 1, 1); mbui.autoset_zoom(imp); IJ.run("Enhance Contrast", "saturated=0.35"); split_channels = mbfs.split_image_plus(imp, params); membrane_test_channel_imp = Duplicator().run(split_channels[0]); segmentation_channel_imp = split_channels[-1]; # import edges imp.hide(); membrane_edges = mbio.load_qcd_edges2(os.path.join(output_folder_old, "user_defined_edges.zip")); dummy_anchors = [params.manual_anchor_positions for _ in membrane_edges] membrane_edges, fixed_anchors = mbui.perform_user_qc(membrane_test_channel_imp, membrane_edges, membrane_edges, dummy_anchors, params); imp.show(); rgbstack = ImageStack(imp.getWidth(), imp.getHeight()); for tidx in range(imp.getNFrames()): imp.setT(tidx+1); ip = imp.getProcessor(); rgbip = ip.convertToRGB(); rgbstack.addSlice(rgbip); rgbimp = ImagePlus(("RGB " + imp.getTitle()), rgbstack); imp.close(); rgbimp.show(); IJ.run("Colors...", "foreground=yellow background=white selection=yellow"); for tidx in range(rgbimp.getNSlices()): rgbimp.setSlice(tidx+1); rgbimp.setRoi(membrane_edges[tidx]); IJ.run(rgbimp, "Draw", "slice"); IJ.run("Colors...", "foreground=red background=white selection=yellow"); for tidx in range(rgbimp.getNSlices()): rgbimp.setSlice(tidx+1); for anchor in params.manual_anchor_positions: rgbimp.setRoi(PointRoi(anchor[0], anchor[1])); IJ.run(rgbimp, "Draw", "slice"); params.saveParametersToJson(os.path.join(params.output_path, "parameters used.json")); params.persistParameters(); rgbimp.changes = False;
#image = IJ.getImage() #image.close() [red_spots, red_spots_dapi] = get_red_spots(rest, z_slices, image_dapi) [green_spots, green_spots_dapi] = get_green_spots(rest, z_slices, image_dapi) [colocalised, colocalised_dapi] = get_colocalised(rest, z_slices, image_dapi) for i in range(z_slices): colocalised[i] = float(colocalised[i] /2) for i in range(z_slices): colocalised_dapi[i] = float(colocalised_dapi[i] /2) print("dapi red: ",red_spots_dapi,"dapi green: ", green_spots_dapi, "dapi coloc: ", colocalised_dapi) image.close() image_green.changes = False image_green.close() fp = open(directory+"/"+filename+"_summary.csv", "w") fp.write("slice, red spots, green spots, colocalised, percentage of red spots colocalising, percentage of green spots colocalising, red spots on DAPI, green spots on DAPI, colocalised on DAPI, percentage of red spots colocalising on DAPI, percentage of green spots colocalising on DAPI\n") for i in range(z_slices): fp.write(str(i)+","+str(red_spots[i])+","+str(green_spots[i])+","+str(colocalised[i])+","+str(safe_div(colocalised[i],red_spots[i]))+","+str(safe_div(colocalised[i],green_spots[i]))) fp.write(","+str(red_spots_dapi[i])+","+str(green_spots_dapi[i])+","+str(colocalised_dapi[i])+","+str(safe_div(colocalised_dapi[i],red_spots_dapi[i]))+","+str(safe_div(colocalised_dapi[i],green_spots_dapi[i]))+"\n") fp.write("\n\n\n") fp.write("total red spots, "+str(sum(red_spots))+"\n") fp.write("total green spots, "+str(sum(green_spots))+"\n") fp.write("total colocalised, "+str(sum(colocalised))+"\n") fp.write("percentage of red spots colocalising, "+str(safe_div(sum(colocalised),sum(red_spots)))+"\n") fp.write("percentage of green spots colocalising, "+str(safe_div(sum(colocalised),sum(green_spots)))+"\n\n\n") fp.write("total red spots on DAPI, "+str(sum(red_spots_dapi))+"\n") fp.write("total green spots on DAPI, "+str(sum(green_spots_dapi))+"\n")
[red_spots, red_spots_dapi] = get_red_spots(rest, z_slices, image_dapi) [green_spots, green_spots_dapi] = get_green_spots(rest, z_slices, image_dapi) [colocalised, colocalised_dapi] = get_colocalised(rest, z_slices, image_dapi) for i in range(z_slices): colocalised[i] = float(colocalised[i] / 2) for i in range(z_slices): colocalised_dapi[i] = float(colocalised_dapi[i] / 2) print("dapi red: ", red_spots_dapi, "dapi green: ", green_spots_dapi, "dapi coloc: ", colocalised_dapi) image.close() image_green.changes = False image_green.close() fp = open(directory + "/" + filename + "_summary.csv", "w") fp.write( "slice, red spots, green spots, colocalised, percentage of red spots colocalising, percentage of green spots colocalising, red spots on DAPI, green spots on DAPI, colocalised on DAPI, percentage of red spots colocalising on DAPI, percentage of green spots colocalising on DAPI\n" ) for i in range(z_slices): fp.write( str(i) + "," + str(red_spots[i]) + "," + str(green_spots[i]) + "," + str(colocalised[i]) + "," + str(safe_div(colocalised[i], red_spots[i])) + "," + str(safe_div(colocalised[i], green_spots[i]))) fp.write("," + str(red_spots_dapi[i]) + "," + str(green_spots_dapi[i]) + "," + str(colocalised_dapi[i]) + "," + str(safe_div(colocalised_dapi[i], red_spots_dapi[i])) + "," +