def crop(self): self.imp.setRoi(self.outlineRoi) duplicator = Duplicator() self.imp.setHideOverlay(True) self.impCrop = duplicator.run(self.imp) self.impCrop.show() self.imp.setHideOverlay(False)
def select_images(): """ Returns two ImagePlus objects that can be used by the drift correction. If more than two images are available a dialog is used for selection. """ if WindowManager.getImageCount() > 0: imp = WindowManager.getCurrentImage() if imp.getImageStackSize() == 2: dup = Duplicator() img1 = dup.run(imp, 1, 1) img1.setTitle("Slice1") img2 = dup.run(imp, 2, 2) img2.setTitle("Slice2") elif WindowManager.getImageCount() == 2: img1, img2 = [WindowManager.getImage(id) for id in WindowManager.getIDList()] elif WindowManager.getImageCount() > 2: image_ids = WindowManager.getIDList() image_titles = [WindowManager.getImage(id).getTitle() for id in image_ids] try: sel1, sel2 = dialogs.create_selection_dialog(image_titles, range(2)) except TypeError: return(None, None) img1 = WindowManager.getImage(image_ids[sel1]) img2 = WindowManager.getImage(image_ids[sel2]) else: IJ.error("You need two images to run the script.") return(None, None) else: IJ.error("You need two images to run the script.") return(None, None) return (img1, img2)
def threshold(imp, lower, upper): duplicate=Duplicator().run(imp) duplicate.getProcessor().resetMinAndMax() IJ.setAutoThreshold(duplicate, "Default dark"); IJ.setThreshold(duplicate, lower, upper) IJ.run(duplicate, "Convert to Mask", ""); return duplicate
def creating_vor_roi(self): """ runs voronoi on cell to create vor_rois """ rm = RoiManager.getRoiManager() rm.reset() d = Duplicator() nuc_bin_copy = d.run(self.hseg.nuc_bin()) nuc_bin_copy.show() IJ.run(nuc_bin_copy, "Make Binary", "") nuc_bin_copy.setRoi(self.roi()) IJ.run(nuc_bin_copy, "Clear Outside", "") # 1/0 IJ.run(nuc_bin_copy, "Voronoi", "") nuc_bin_copy.setRoi(None) ip = nuc_bin_copy.getProcessor() ip.setMinAndMax(0, 1) IJ.run(nuc_bin_copy, "Apply LUT", "") nuc_bin_copy.setRoi(self.roi()) IJ.run(nuc_bin_copy, "Analyze Particles...", "add") vor_rois = rm.getRoisAsArray() # self.hseg.raw_stack().show() # 10/0 futils.force_close(nuc_bin_copy) return vor_rois
def threshold(imp, threshold): """ Threshold image """ impout = Duplicator().run(imp) IJ.setThreshold(impout, threshold, 1000000000) IJ.run(impout, "Convert to Mask", "stack") impout.setTitle("Threshold"); return impout
def process(self, image, seeds=None): self.objects = None self.labelImage = None duplicator = Duplicator() spots = duplicator.run(image) IJ.setMinAndMax(spots, 0, 1) IJ.run(spots, "16-bit", "") spot3DImage = ImageHandler.wrap(spots) if seeds != None: seed3DImage = ImageHandler.wrap(seeds) else: seed3DImage = self.__computeSeeds(spots) algorithm = Segment3DSpots(spot3DImage, seed3DImage) algorithm.show = False algorithm.setSeedsThreshold(self.seedsThreshold) algorithm.setLocalThreshold(self.localBackground) algorithm.setWatershed(self.watershed) algorithm.setVolumeMin(self.volumeMin) algorithm.setVolumeMax(self.volumeMax) algorithm.setMethodLocal(Segment3DSpots.LOCAL_CONSTANT) algorithm.setMethodSeg(Segment3DSpots.SEG_MAX) algorithm.segmentAll() self.objects = algorithm.getObjects() self.labelImage = ImagePlus("OM_" + spots.getTitle(), algorithm.getLabelImage().getImageStack()) return self.labelImage
def blurImage(ip): #duplicate imp_dup = Duplicator().run(ip) #blur it imp_dup.show() IJ.run(imp_dup, "Gaussian Blur...", "sigma=1") imp_GB = IJ.getImage() return (imp_GB)
def runSimulation(options, image): print "Testing segmentation with blur" + \ " x=" + "%f" % options['gaussXY'] + \ " y=" + "%f" % options['gaussXY'] + \ " z=" + "%f" % options['gaussZ'] + \ " localBackground=" + "%i" % options['localBackground'] + \ " seedRadius=" + "%i" % options['seedRadius'] duplicator = Duplicator() inputPM = duplicator.run(image) inputPM.setTitle("Gauss_segment_input") inputName = image.getTitle() inputName = inputName[:inputName.rfind('.')] ### Blur nuclei probability map to smoothen segmentation IJ.run(inputPM, "Gaussian Blur 3D...", " x=" + "%f" % options['gaussXY'] + \ " y=" + "%f" % options['gaussXY'] + \ " z=" + "%f" % options['gaussZ']) ### Segment image using nuclear probability map print ">>> Segmenting image..." segmentator = Segmentator(options, "Segmented") segmentedImage = segmentator.process(inputPM) outputName = "OM_XY" + ("%f" % options['gaussXY']) + "_Z" + ("%f" % options['gaussZ']) + \ "_TH" + ("%i" % options['localBackground']) + \ "_SR" + ("%i" % options['seedRadius']) + \ "_" + inputName segmentator.save(segmentedImage, outputName) ### Get object measurements print ">>> Measuring objects..." results = {'all':0, '0':0, '250':0, '500':0, '750':0, '1000':0, '1500':0, 'edge':0} analyzer = Analyzer(options, segmentator.objects, "Results") segmented = ImageInt.wrap(segmentedImage) for objectV in analyzer.objects.getObjectsList(): if (options['edgeXY'] and options['edgeZ']) or \ (not objectV.edgeImage(segmented, not options['edgeXY'], not options['edgeZ'])): results['all'] = results['all'] + 1 volume = objectV.getVolumePixels() if volume <= 250: results['0'] = results['0'] + 1 elif volume > 250 and volume <= 500: results['250'] = results['250'] + 1 elif volume > 500 and volume <= 750: results['500'] = results['500'] + 1 elif volume > 750 and volume <= 1000: results['750'] = results['750'] + 1 elif volume > 1000 and volume <= 1500: results['1000'] = results['1000'] + 1 else: results['1500'] = results['1500'] + 1 else: results['edge'] = results['edge'] + 1 return results
def vor_cell(nuc_bin_imp, cell): """creates the voronoi for one cell, cell is assumed to have nucs""" rm = RoiManager.getRoiManager() rm.reset() d = Duplicator() nuc_bin_copy = d.run(nuc_bin_imp) IJ.run(nuc_bin_copy, "Make Binary", "") nuc_bin_copy.setRoi(cell.roi) IJ.run(nuc_bin_copy, "Clear Outside", "") IJ.run(nuc_bin_copy, "Voronoi", "") nuc_bin_copy.setRoi(None) ip = nuc_bin_copy.getProcessor() ip.setMinAndMax(0, 1) IJ.run(nuc_bin_copy, "Apply LUT", "") IJ.run(nuc_bin_copy, "Invert", "") nuc_bin_copy.setRoi(cell.roi) IJ.run(nuc_bin_copy, "Analyze Particles...", "add") vor_rois = rm.getRoisAsArray() nuc_inds = [x for x in range(len(cell.nucs))] for vor_roi in vor_rois: temp = None for i, nuc_ind in enumerate(nuc_inds): nuc_roi = cell.nucs[nuc_ind].roi nuc_cent = roi_cent(nuc_roi, integer=True) if vor_roi.contains(*nuc_cent): cell.nucs[nuc_ind].vor_roi = vor_roi ## I don't think I need to do this, I could just use i outside of loop but it feels so insecure or something temp = i break else: IJ.log('cell: {}, issue with voronoi nuc match up'.format( cell.name)) rm.reset() for i, nuc in enumerate(cell.nucs): x = int(nuc.roi.getXBase()) y = int(nuc.roi.getYBase()) IJ.log('{}. ({},{})'.format(i, x, y)) add_roi(Roi(x, y, 10, 10), str(i)) IJ.log(str(nuc_inds)) add_roi(vor_roi, "vor_roi") ## raise RuntimeError('cell: {}, issue with voronoi nuc match up'.format(cell.name)) if temp is not None: del nuc_inds[temp] force_close(nuc_bin_copy)
return SpotDetectionLog(imgBgs32, data, ops, thresholdmethod, dimensions2D, factory) def SpotDetection2(imp): imp=Duplicator().run(imp) # subtract background
return SpotDetectionLog(imgBgs32, data, ops, thresholdmethod, dimensions2D, factory) def SpotDetection2(imp): imp=Duplicator().run(imp) # subtract background bgs=BackgroundSubtracter()
def Smooth(_img, mpar={"width": 1}, _gui=False): imp = Duplicator().run(_img) # imp.show() print "sigma=%s" % mpar["width"] IJ.run(imp, "Gaussian Blur...", "sigma=%s stack" % mpar["width"]) # imp = IJ.getImage(); imp.setTitle("Smooth") # imp.hide() return (imp,)
def ExtractChannel(imp, channel): imp_height = imp.getHeight() imp_width = imp.getWidth() channelnumber = imp.getNChannels() slicenumber = imp.getNSlices() timepoints = imp.getNFrames() ExtractedChannel = Duplicator().run(imp, channel, channel, 1, slicenumber, 1, timepoints) ExtractedChannel.setTitle("Gallery_Channel_" + str(channel)) return ExtractedChannel
def DistanceMap(_img, mpar={}, _gui=False): imp = Duplicator().run(_img) IJ.run(imp, "Exact Euclidean Distance Transform (3D)", "") imp = IJ.getImage() IJ.setMinAndMax(imp, 0, 65535) IJ.run(imp, "16-bit", "") imp.setTitle("DistanceMap") imp.hide() return (imp,)
def threshold(_img, threshold): imp = Duplicator().run(_img) #imp.show(); time.sleep(0.2) #IJ.setThreshold(imp, mpar['lthr'], mpar['uthr']) IJ.setThreshold(imp, threshold, 1000000000) IJ.run(imp, "Convert to Mask", "stack") imp.setTitle("Threshold"); #IJ.run(imp, "Divide...", "value=255 stack"); #IJ.setMinAndMax(imp, 0, 1); return imp
def extractRIM(impbin, iteration): IJ.run(imp, "Options...", "iterations=1 count=1 edm=Overwrite do=Nothing"); impErode = Duplicator().run(impbin) impDilate = Duplicator().run(impbin) # resized = CanvasResizer().expandStack(impDilate.getStack(), impDilate.getWidth()+2*iteration, impDilate.getHeight()+2*iteration, iteration, iteration) # impDilate.setStack(None, resized); for j in range(impErode.getStackSize()): ipe = impErode.getStack().getProcessor(j+1) ipe.setBackgroundValue(0) ipd = impDilate.getStack().getProcessor(j+1) ipd.setBackgroundValue(0) for i in range(iteration): ipe.erode() ipd.dilate() # IJ.run(impErode, "Dilate", "stack") # IJ.run(impDilate, "Erode", "stack") # resized = CanvasResizer().expandStack(impDilate.getStack(), impDilate.getWidth()-2*iteration, impDilate.getHeight()-2*iteration, -1*iteration, -1*iteration) # impDilate.setStack(None, resized); # impErode.show() # Duplicator().run(impDilate).show() for i in range(1, impbin.getStackSize()+1): impDilate.setSlice(i) impErode.setSlice(i) ImageCalculator().calculate("XOR", impDilate, impErode) return impDilate;
def Duplicate(imp): imp_name = imp.getTitle() imp_height = imp.getHeight() imp_width = imp.getWidth() channelnumber = imp.getNChannels() slicenumber = imp.getNSlices() timepoints = imp.getNFrames() ExtractedChannel = Duplicator().run(imp, 1, channelnumber, 1, slicenumber, 1, timepoints) ExtractedChannel.setTitle("Duplicate_" + str(imp_name)) return ExtractedChannel
def Threshold(_img, mpar={"threshold": 15}, _gui=False): print "Threshold" imp = Duplicator().run(_img) # imp.show(); time.sleep(0.2) # IJ.setThreshold(imp, mpar['lthr'], mpar['uthr']) IJ.setThreshold(imp, mpar["threshold"], 1000000000) IJ.run(imp, "Convert to Mask", "stack") imp.setTitle("Threshold") # IJ.run(imp, "Divide...", "value=255 stack"); # IJ.setMinAndMax(imp, 0, 1); return imp, _img.duplicate()
IJ.run(imp, "Auto Threshold", "method=Triangle white"); return imp def SpotDetection3(imp, invert=False): # operate on a duplicate as not to change the original imp=Duplicator().run(imp) if (invert): IJ.run(imp, "Invert", ""); # subtract background bgs=BackgroundSubtracter() bgs.rollingBallBackground(imp.getProcessor(), 50.0, False, False, True, True, True)
bgs.rollingBallBackground(imp.getProcessor(), 50.0, False, False, True, True, True) IJ.run(imp, "Auto Threshold", "method=Triangle white"); return imp def SpotDetection3(imp, invert=False): # operate on a duplicate as not to change the original imp=Duplicator().run(imp) if (invert): IJ.run(imp, "Invert", ""); # subtract background bgs=BackgroundSubtracter()
def getMask(imp, chan): dup = Duplicator() mask = dup.run(imp, chan, chan, 1,1, 1,1) sigma = 0.2 IJ.run(mask, "Gaussian Blur...", "sigma="+str(sigma)+" scaled") if chan==1: method = "Otsu" else: method = "MaxEntropy" IJ.setAutoThreshold(mask, method+" dark") Prefs.blackBackground = True IJ.run(mask, "Convert to Mask", "") IJ.run(mask, "Close-", "") IJ.run(mask, "Watershed", "") return mask
def z_crop(imp): """trim a z stack based on interactively-defined start and end points""" WaitForUserDialog("Choose first z plane and click OK...").show() start_z = imp.getZ() WaitForUserDialog("Now choose last z plane and click OK...").show() end_z = imp.getZ() frames = imp.getNFrames() channels = imp.getNChannels() #current_channel = imp.getC(); dupimp = Duplicator().run(imp, 1, channels, start_z, end_z, 1, frames) imp.changes = False imp.close() dupimp.show() #autoset_zoom(dupimp); return dupimp, (start_z, end_z)
def z_crop(imp): """trim a z stack based on interactively-defined start and end points""" IJ.setTool("zoom") IJ.run("Brightness/Contrast...") imp.setZ(1) WaitForUserDialog("Choose first z plane and click OK...").show() start_z = imp.getZ() WaitForUserDialog("Now choose last z plane and click OK...").show() end_z = imp.getZ() frames = imp.getNFrames() channels = imp.getNChannels() imp.killRoi() dupimp = Duplicator().run(imp, 1, channels, start_z, end_z, 1, frames) imp.hide() dupimp.show() return dupimp, (start_z, end_z)
def crop_to_ROI(imp, params): """prompt user to select ROI for subsequent analysis""" roi = None; if params.perform_spatial_crop: if params.spatial_crop is not None: roi = params.parse_roistr_to_roi(); imp.setRoi(roi); else: IJ.setTool("rect"); MyWaitForUser("Crop", "If desired, select an area ROI to crop to..."); roi = imp.getRoi(); crop_params = None; original_imp = Duplicator().run(imp); if roi is not None: if not roi.isArea(): raise TypeError("selected ROI should be an area"); if roi.getType(): crop_params = str([(x, y) for x, y in zip(roi.getPolygon().xpoints, roi.getPolygon().ypoints)]); IJ.run(imp, "Make Inverse", ""); roi = imp.getRoi(); fill_val = mb.calculate_percentile(imp, roi, 25); IJ.run(imp, "Set...", "value=" + str(round(fill_val)) + " stack"); IJ.run(imp, "Make Inverse", ""); else: crop_params = roi.getBounds().toString(); IJ.run(imp, "Crop", ""); imp.killRoi(); params.setSpatialCrop(crop_params) else: params.setSpatialCrop(None); return original_imp, crop_params;
def main(): imp = WindowManager.getCurrentImage() width, height, nChannels, nSlices, nFrames = imp.getDimensions() canny_stack = ImageStack() for i in range(nFrames): slice = Duplicator().run( imp, 1, # firstC 1, # lastC 1, # firstZ 1, # lastZ i, # firstT i) # lastT proc = i / nFrames IJ.log("Processing slice {}/{}...".format(i, nFrames)) canny_slice = _singleCanny(slice) ip = canny_slice.getProcessor() canny_stack.addSlice(ip) canny_stack = ImagePlus("canny_stack", canny_stack) canny_stack.show() IJ.log("Canny edge detection finished.") return
def get_nuclei_locations(nuc_imp, cal, distance_threshold_um=10, size_threshold_um2=50): """get centroids of nuclei. blobs closer than distance_threshold_um and smaller than size_threshold_um2 are merged""" size_limit_pix = size_threshold_um2 // (cal.pixelWidth**2) distance_limit_pix = distance_threshold_um // (cal.pixelWidth) IJ.run(nuc_imp, "Make Binary", "method=Moments background=Dark calculate") dilate_count = 2 for _ in range(dilate_count): IJ.run(nuc_imp, "Dilate", "") IJ.run(nuc_imp, "Fill Holes", "") nuc_imp = keep_blobs_bigger_than(nuc_imp, min_size_pix=math.ceil( float(size_limit_pix) / 3)) nuc_imp.killRoi() pre_watershed_nuc_imp = Duplicator().run(nuc_imp) IJ.run(nuc_imp, "Watershed", "") ws_seed_imp, centroids = merge_incorrect_splits_and_get_centroids( nuc_imp, centroid_distance_limit=distance_limit_pix, size_limit=size_limit_pix) full_nuclei_imp = generate_cell_masks(ws_seed_imp, pre_watershed_nuc_imp, find_edges=False) return centroids, full_nuclei_imp, ws_seed_imp
def _cropSingleTrack(ispots): """Nested function to crop the spots of a single TRACK_ID. Args: ispots (list): List of getresults() dictionaries belonging to a single track. Returns: list: A list of ImagePlus stacks of the cropped timeframes. """ outstacks = [] for j in ispots: # Extract all needed row values. j_id = int(j[trackid]) j_x = int(j[trackxlocation] * xScaleMultiplier) j_y = int(j[trackylocation] * yScaleMultiplier) j_t = int(j[tracktlocation]) # Now set an ROI according to the track's xy position in the hyperstack. imp.setRoi( j_x, j_y, roi_x, roi_y ) # upper left x, upper left y, roi x dimension, roi y dimension # Optionally, set the correct time position in the stack. This provides cool feedback but is sloooow! # imp.setPosition(1, 1, j_t) # Crop the ROI on the corresponding timepoint and add to output stack. crop = Duplicator().run( imp, 1, dims[2], 1, dims[3], j_t, j_t) # firstC, lastC, firstZ, lastZ, firstT, lastT outstacks.append(crop) return outstacks
def ExtractTimpepointChannel(imp, channel, timepoint): imp_height = imp.getHeight() imp_width = imp.getWidth() channelnumber = imp.getNChannels() slicenumber = imp.getNSlices() ExtractedChannel = Duplicator().run(imp, channel, channel, 1, slicenumber, timepoint, timepoint) return ExtractedChannel
def croproi(imp, tracks, outdir, trackindex="TRACK_INDEX", trackx="TRACK_X_LOCATION", tracky="TRACK_Y_LOCATION", trackstart="TRACK_START", trackstop="TRACK_STOP", roi_x=150, roi_y=150): """Function cropping ROIs from an ImagePlus stack based on a ResultsTable object. This function crops square ROIs from a hyperstack based on locations defined in the ResultsTable. The ResultsTable should, however make sense. The following headings are required: "TRACK_INDEX", "TRACK_X_LOCATION", "TRACK_Y_LOCATION", "TRACK_START", "TRACK_STOP" Args: imp: An ImagePlus hyperstack (timelapse). tracks: A getresults(ResultsTable) object (from Track statistics.csv) with the proper column names. outdir: The primary output directory. trackindex: A unique track identifier. Defaults to "TRACK_INDEX" trackxlocation: Defaults to "TRACK_X_LOCATION". trackylocation: Defaults to "TRACK_Y_LOCATION". trackstart: Defaults to "TRACK_START". trackstop: Defaults to "TRACK_STOP". roi_x: Width of the ROI. roi_y: Height of the ROI. """ # Loop through all the tracks, extract the track position, set an ROI and crop the hyperstack. for i in tracks: # This loops through all tracks. Use a custom 'tracks[0:5]' to test and save time! # Extract all needed row values. i_id = int(i[trackindex]) i_x = int(i[trackx] * 5.988) # TODO fix for calibration. i_y = int(i[tracky] * 5.988) # TODO fix for calibration. i_start = int(i[trackstart] / 15) i_stop = int(i[trackstop] / 15) # Now set an ROI according to the track's xy position in the hyperstack. imp.setRoi( i_x - roi_x / 2, i_y - roi_y / 2, # upper left x, upper left y roi_x, roi_y) # roi x dimension, roi y dimension # Retrieve image dimensions. width, height, nChannels, nSlices, nFrames = imp.getDimensions() # And then crop (duplicate, actually) this ROI for the track's time duration. IJ.log("Cropping image with TRACK_INDEX: {}/{}".format( i_id + 1, int(len(tracks)))) # Duplicator().run(firstC, lastC, firstZ, lastZ, firstT, lastT) imp2 = Duplicator().run(imp, 1, nChannels, 1, nSlices, i_start, i_stop) # Save the substack in the output directory outfile = os.path.join(outdir, "TRACK_ID_{}.tif".format(i_id)) IJ.saveAs(imp2, "Tiff", outfile)
def open_dapi_image(self, e): sender = e.getSource() IJ.run("Close All") if not e.getValueIsAdjusting(): self.name = sender.getSelectedValue() print self.name dapi_filename = path.join(self.input_path, self.name + '_DAPI.tif') #print dapi_filename if not path.exists(dapi_filename): print "I don't find the DAPI file, which is weird as I just found it before" else: #open stack and make the reslice self.dapi_image = ImagePlus(dapi_filename) #read the image # duplicate image to play with that one, and do the real processing in the background self.imp_main = Duplicator().run(self.dapi_image) self.imp_main.setTitle(self.name) self.imp_main.show() #show image on the left
def get_no_nuclei_fully_enclosed(roi, full_nuclei_imp, overlap_threshold=0.65): """for a given cell roi and ImagePlus with binary nuclei, return how many nuclei lie ENTIRELY within the cell""" bbox = roi.getBounds() full_nuclei_imp.setRoi(roi) cropped_nuc_imp = full_nuclei_imp.crop() roi.setLocation(0, 0) cropped_nuc_imp.setRoi(roi) cropped_nuc_imp.killRoi() roim = RoiManager(False) mxsz = cropped_nuc_imp.getWidth() * cropped_nuc_imp.getHeight() pa = ParticleAnalyzer( ParticleAnalyzer.ADD_TO_MANAGER, ParticleAnalyzer.AREA | ParticleAnalyzer.SLICE | ParticleAnalyzer.CENTROID, None, 0, mxsz) pa.setRoiManager(roim) pa.analyze(cropped_nuc_imp) cell_imp = IJ.createImage("Cell binary", cropped_nuc_imp.getWidth(), cropped_nuc_imp.getHeight(), 1, 8) IJ.run(cell_imp, "Select All", "") IJ.run(cell_imp, "Set...", "value=0 slice") cell_imp.setRoi(roi) IJ.run(cell_imp, "Set...", "value=255 slice") no_enclosed_nuclei = 0 for idx, nuc_roi in enumerate(roim.getRoisAsArray()): test_imp = Duplicator().run(cell_imp) test_imp.setRoi(nuc_roi) IJ.run(test_imp, "Set...", "value=255 slice") test_imp.killRoi() IJ.run(test_imp, "Create Selection", "") IJ.run(test_imp, "Make Inverse", "") test_roi = test_imp.getRoi() test_roi_stats = test_roi.getStatistics() cell_roi_stats = roi.getStatistics() nuc_roi_stats = nuc_roi.getStatistics() if test_roi_stats.area < ( cell_roi_stats.area + (1 - overlap_threshold) * nuc_roi_stats.area ): # i.e. if more than (100*overlap_threshold)% of nucleus is inside cell... no_enclosed_nuclei += 1 test_imp.changes = False test_imp.close() roi.setLocation(bbox.getX(), bbox.getY()) cropped_nuc_imp.changes = False cropped_nuc_imp.close() cell_imp.changes = False cell_imp.close() return no_enclosed_nuclei
def gfp_analysis(imp, file_name, output_folder): """perform analysis based on gfp intensity thresholding""" cal = imp.getCalibration() channel_imps = ChannelSplitter.split(imp) gfp_imp = channel_imps[0] gfp_imp.setTitle("GFP") threshold_imp = Duplicator().run(gfp_imp) threshold_imp.setTitle("GFP_threshold_imp") ecad_imp = channel_imps[1] ecad_imp.setTitle("E-cadherin") nuc_imp = channel_imps[2] IJ.run(threshold_imp, "Make Binary", "method=Otsu background=Dark calculate") IJ.run(threshold_imp, "Fill Holes", "") erode_count = 2 for _ in range(erode_count): IJ.run(threshold_imp, "Erode", "") threshold_imp = keep_blobs_bigger_than(threshold_imp, min_size_pix=1000) threshold_imp = my_kill_borders(threshold_imp) rois = generate_cell_rois(threshold_imp) out_stats = generate_cell_shape_results(rois, gfp_imp, cal, file_name) print("Number of cells identified = {}".format(len(out_stats))) threshold_imp.changes = False threshold_imp.close() # save output save_qc_image( imp, rois, "{}_plus_overlay.tiff".format( os.path.join(output_folder, os.path.splitext(file_name)[0]))) save_cell_rois(rois, output_folder, os.path.splitext(file_name)[0]) imp.changes = False imp.close() save_output_csv(out_stats, output_folder) return out_stats
def correct_drift(img1, img2, display_cc=False): ''' Returns two ImagePlus objects that are drift corrected to each other. The first image is not changed. The second image is a new image that is shifted using ImageJ's Translate. :param img1: The reference image. :param img2: The image to be shifted. :param display_cc: Activate displaying the CrossCorrelation image (default False). ''' img1_cc, img2_cc = cc.scale_to_power_of_two([img1, img2]) result = cc.perform_correlation(img1_cc, img2_cc) x_off, y_off = cc.get_shift(result) # style after maximum detection if not display_cc: result.hide() else: result.copyScale(img1) cc.style_cc(result) if x_off == 0 and y_off == 0: print('No drift has been detected.') return img1, img2 title = img2.getTitle() img2_dk = Duplicator().run(img2) img2_dk.setTitle('DK-' + title) IJ.run(img2_dk, 'Translate...', 'x=%d y=%d interpolation=None' % (-x_off, -y_off)) img2_dk.copyScale(img2) img2_dk.show() return img1, img2_dk
def make_and_clean_binary(imp, threshold_method): """convert the membrane identification channel into binary for segmentation""" if "Local: " in threshold_method: dup = Duplicator() imp1 = dup.run(imp) imp2 = dup.run(imp) imp.changes = False imp.close() threshold_method = threshold_method.split("Local: ")[1] IJ.run(imp1, "8-bit", "") IJ.run( imp1, "Auto Local Threshold", "method=" + threshold_method + " radius=15 parameter_1=0 parameter_2=0 white stack") IJ.run(imp2, "Make Binary", "method=MinError background=Dark calculate") ic = ImageCalculator() imp = ic.run("AND create stack", imp1, imp2) IJ.run(imp, "Invert", "stack") IJ.run(imp, "Make Binary", "method=Default background=Default calculate") elif "Edge" in threshold_method: IJ.run(imp, "Find Edges", "stack") IJ.run(imp, "Make Binary", "method=Mean background=Dark calculate") else: IJ.run(imp, "Make Binary", "method=" + threshold_method + " background=Dark calculate") # "calculate" ensures that threshold is calculated image-wise IJ.run(imp, "Open", "stack") IJ.run(imp, "Close-", "stack") IJ.run(imp, "Close-", "stack") IJ.run(imp, "Open", "stack") IJ.run(imp, "Fill Holes", "stack") IJ.run(imp, "Erode", "stack") IJ.run(imp, "Erode", "stack") keep_largest_blob(imp) IJ.run(imp, "Dilate", "stack") IJ.run(imp, "Dilate", "stack") IJ.run(imp, "Open", "stack") if "Edge" in threshold_method: IJ.run(imp, "Erode", "stack") IJ.run(imp, "Erode", "stack") return imp
def save_copy(path, base_dir): copy_dir = base_dir + 'copy/' name = os.path.basename(path) copy_name = name[:-4] + 'copy' copy_path = copy_dir + copy_name img = IJ.openImage(path) copy = Duplicator().run(img) IJ.saveAs(copy, "tiff", copy_path)
def split_image_plus(imp, params): """split original ImagePlus by channel, and assign an image to segment on""" split_channels = ChannelSplitter.split(imp) membrane_channel_imp = split_channels[params.membrane_channel_number - 1] segmentation_channel_imp = Duplicator().run(membrane_channel_imp) if params.use_single_channel: actin_channel = params.membrane_channel_number actin_channel_imp = Duplicator().run(membrane_channel_imp) else: if imp.getNChannels() >= 2: actin_channel = (params.membrane_channel_number + 1) % imp.getNChannels() actin_channel_imp = split_channels[actin_channel - 1] else: actin_channel = params.membrane_channel_number actin_channel_imp = Duplicator().run(membrane_channel_imp) split_channels = [ membrane_channel_imp, actin_channel_imp, segmentation_channel_imp ] return split_channels
IJ.run(imp, "Auto Local Threshold", "method=MidGrey radius=15 parameter_1=0 parameter_2=0 white"); return imp def SpotDetectionDark(imp): imp=Duplicator().run(imp) IJ.run(imp, "8-bit", ""); IJ.run(imp, "Auto Local Threshold", "method=Niblack radius=50 parameter_1=0 parameter_2=0"); Prefs.blackBackground = True; IJ.run(imp, "Erode", ""); IJ.run(imp, "Fill Holes", ""); IJ.run(imp, "Open", "");
def save_separate_tif(f): if f is not None: save_dir, pre_save_path = get_presave_path(f, dir_name="Separate") imp = IJ.openImage(f) for i in range(imp.getNFrames()): imp.setT(i + 1) new_imp = Duplicator().crop(imp) IJ.saveAsTiff(new_imp, pre_save_path + "_{}.tif".format(i + 1))
def segmentNuc(impc2): impdup = Duplicator().run(impc2) IJ.run(impdup, "8-bit", "") IJ.run(impdup, "Gaussian Blur...", "sigma=1.5 stack") # AutoThresholder().getThreshold(AutoThresholder.Method.valuOf('Otsu'), int[] histogram) IJ.setAutoThreshold(impdup, "Otsu dark") IJ.run(impdup, "Convert to Mask", "stack") #IJ.setAutoThreshold(impdup, "Otsu dark") #opt = PA.SHOW_MASKS + PA.SHOW_RESULTS + PA.EXCLUDE_EDGE_PARTICLES + PA.INCLUDE_HOLES # option for stack missing opt = PA.SHOW_MASKS + PA.EXCLUDE_EDGE_PARTICLES + PA.INCLUDE_HOLES # option for stack missing ##area mean centroid bounding integrated stack redirect=None decimal=4 meas = Meas.AREA + Meas.MEAN + Meas.CENTROID + Meas.RECT + Meas.INTEGRATED_DENSITY + Meas.STACK_POSITION rt = ResultsTable().getResultsTable() pa = PA(opt, meas, rt, 10.0, 300000.0, 0, 1.0) PA.processStack = True pa.setHideOutputImage(True) ##run("Analyze Particles...", "size=800-Infinity circularity=0.00-1.00 pixel show=Masks display exclude include stack"); outstack = ImageStack(impdup.getWidth(), impdup.getHeight()) for i in range(1,impdup.getStackSize()+1): impdup.setSlice(i) pa.analyze(impdup) impbin = pa.getOutputImage() outstack.addSlice(impbin.getProcessor()) impbin = ImagePlus("out", outstack) IJ.run(impbin, "Invert LUT", "") #IJ.run(impbin, "Fill Holes", "stack") return impbin, rt
def getZstackfrom5d(imp, metadata, chindex=1, tindex=1): firstC = chindex lastC = chindex firstZ = 1 lastZ = metadata['SizeZ'] firstT = 1 lastT = metadata['SizeT'] zstack = newstack = Duplicator().run(imp, firstC, lastC, firstZ, lastZ, firstT, lastT) return zstack
def getstackfrom5d(imp, metadata, firstC=1, lastC=1, firstZ=1, lastZ=1, firstT=1, lastT=1): substack = Duplicator().run(imp, firstC, lastC, firstZ, lastZ, firstT, lastT) return substack
distMin = dist return centPart, (x, y) def isSpecialParticle(image, roim, iParticle, boundariesNuc, boundariesMito, pixelSize, z): try: image.setSlice(int(round(z))) image2 = ImagePlus("slice",image.getProcessor()) roim.select(image2, iParticle) image3 = Duplicator().run(image2); image3.show() sp = segment_Particles() image3 = sp.preprocessImage(image3, "MAX", "C1", 0, 0) image3 = sp.segmentParticles(image3, "Triangle", boundariesNuc[0], boundariesNuc[1], 0, 0) if roim.getCount() > 0: roim.select(image3, 0) stats = image3.getStatistics(Measurements.AREA + Measurements.SHAPE_DESCRIPTORS) IJ.log("Area (um2) " + str(stats.area*pixelSize*pixelSize) + "; Aspect Ratio " + str(stats.major/stats.minor)) if stats.area > boundariesMito[0] and stats.area < boundariesMito[1] and stats.major/stats.minor > boundariesMito[2]: return 1 else: return 0 except BaseException, err:
def cut(event): roi = imp.getRoi() if roi != None: newRoi = roi.clone() Dup = Duplicator().run(imp, 1, imp.getNChannels(), 1, imp.getNSlices(), 1, imp.getNFrames()) newRoi.setLocation(0,0) Dup.setRoi(newRoi) Dup.setTitle(Men.getTextField() + str(Men.getCounter())) Dup.show() #Men.setCounter() Men.addOlay(roi) imp.setOverlay(Men.getOverlay()) #setOverlay(Roi roi, java.awt.Color strokeColor, int strokeWidth, java.awt.Color fillColor) imp.getOverlay().drawLabels(True) # drawNumbers imp.deleteRoi() #make cell instance and add to position instance p.addCell(cell(p.getMainPath(), p, Men.getCounter(), Dup)) # cell(mainPath, position, ID, imp): Dup.close() Men.increaseCounter()
def creatResultsCompisite(pathdict, impbin, impsig): impbin.killRoi() impsig.killRoi() impid = Duplicator().run(impbin) IJ.run(impbin, "Red", "") for i in range(impid.getStackSize()): impid.getStack().getProcessor(i+1).setColor(0) impid.getStack().getProcessor(i+1).fill() impid.getStack().getProcessor(i+1).setColor(255) for pathid, path in pathdict.iteritems(): for nuc in path.nucs: ip = impid.getStack().getProcessor(int(nuc.frame)) ip.setColor(255) ip.drawString(str(pathid), int(nuc.x), int(nuc.y)) #print 'Draw Path ID:',str(pathid) images = jarray.array([impbin, impsig, impid], ImagePlus) comb = RGBStackMerge().mergeHyperstacks(images, False) comb.setTitle('Measurement Map.tif') return comb
def boxed_intensities(imp1, width, height): """Create a new image with averaged intensity regions. Parameters ---------- imp1 : ImagePlus width, height : int The width and height of the rectangles. Returns ------- imp2 : ImagePlus The resulting ImagePlus, same dimensions as imp1. """ imp2 = Duplicator().run(imp1) imp2.setTitle('heatmap-' + imp1.getTitle()) imw = imp1.getWidth() imh = imp1.getHeight() ip1 = imp1.getProcessor() ip2 = imp2.getProcessor() if (imw % width + imh % height) > 0: msg = "WARNING: image size (%dx%d) not dividable by box (%dx%d)!" log.warn(msg % (imw, imh, width, height)) for box_y in range(0, imh / height): start_y = box_y * height for box_x in range(0, imw / width): start_x = box_x * width # print "%d %d" % (start_x, start_y) bavg = rect_avg(ip1, start_x, start_y, width, height) # print bavg rect_set(ip2, start_x, start_y, width, height, bavg) return imp2
def boxed_intensities(imp1, width, height): """Create a new image with averaged intensity regions. Parameters ---------- imp1 : ImagePlus width, height : int The width and height of the rectangles. Returns ------- imp2 : ImagePlus The resulting ImagePlus, same dimensions as imp1. """ imp2 = Duplicator().run(imp1) imp2.setTitle('heatmap-' + imp1.getTitle()) imw = imp1.getWidth() imh = imp1.getHeight() ip1 = imp1.getProcessor() ip2 = imp2.getProcessor() if (imw % width + imh % height) > 0: msg = "WARNING: image size (%dx%d) not dividable by box (%dx%d)!" IJ.log(msg % (imw, imh, width, height)) for box_y in range(0, imh / height): start_y = box_y * height for box_x in range(0, imw / width): start_x = box_x * width # print "%d %d" % (start_x, start_y) bavg = rect_avg(ip1, start_x, start_y, width, height) # print bavg rect_set(ip2, start_x, start_y, width, height, bavg) return imp2
def poreDetectionUV(inputImp, inputDataset, inputRoi, ops, data, display, detectionParameters): title = inputImp.getTitle() title=title.replace('UV', 'SD') print title #trueColorImp= WindowManager.getImage(title) #print type( trueColorImp) # calculate are of roi stats=inputImp.getStatistics() inputRoiArea=stats.area print inputRoi # get the bounding box of the active roi inputRec = inputRoi.getBounds() x1=long(inputRec.getX()) y1=long(inputRec.getY()) x2=x1+long(inputRec.getWidth())-1 y2=y1+long(inputRec.getHeight())-1 print x1 print y1 print x2 print y2 # crop the roi interval=FinalInterval( array([x1, y1 ,0], 'l'), array([x2, y2, 2], 'l') ) cropped=ops.crop(interval, None, inputDataset.getImgPlus() ) datacropped=data.create(cropped) display.createDisplay("cropped", datacropped) croppedPlus=IJ.getImage() duplicator=Duplicator() substackMaker=SubstackMaker() # duplicate the roi duplicate=duplicator.run(croppedPlus) #duplicate.show() # convert duplicate of roi to HSB and get brightness IJ.run(duplicate, "HSB Stack", ""); brightnessPlus=substackMaker.makeSubstack(duplicate, "3-3") brightness=ImgPlus(ImageJFunctions.wrapByte(brightnessPlus)) brightnessPlus.setTitle("Brightness") #brightnessPlus.show() # make another duplicate, split channels and get red duplicate=duplicator.run(croppedPlus) channels=ChannelSplitter().split(duplicate) redPlus=channels[0] red=ImgPlus(ImageJFunctions.wrapByte(redPlus)) redPlus.show() # convert to lab IJ.run(croppedPlus, "Color Transformer", "colour=Lab") IJ.selectWindow('Lab') labPlus=IJ.getImage() # get the A channel APlus=substackMaker.makeSubstack(labPlus, "2-2") APlus.setTitle('A') APlus.show() APlus.getProcessor().resetMinAndMax() APlus.updateAndDraw() AThresholded=threshold(APlus, -10, 50) # get the B channel BPlus=substackMaker.makeSubstack(labPlus, "3-3") BPlus.setTitle('B') BPlus.show() BPlus.getProcessor().resetMinAndMax() BPlus.updateAndDraw() BThresholded=threshold(BPlus, -10, 50) # AND the Athreshold and Bthreshold to get a map of the red pixels ic = ImageCalculator(); redMask = ic.run("AND create", AThresholded, BThresholded); IJ.run(redMask, "Divide...", "value=255"); #redMask.show() labPlus.close() # threshold the spots from the red channel thresholdedred=SpotDetectionGray(red, data, display, ops, False) display.createDisplay("thresholdedred", data.create(thresholdedred)) impthresholdedred = ImageJFunctions.wrap(thresholdedred, "wrapped") # threshold the spots from the brightness channel thresholded=SpotDetectionGray(brightness, data, display, ops, False) display.createDisplay("thresholded", data.create(thresholded)) impthresholded=ImageJFunctions.wrap(thresholded, "wrapped") # or the thresholding results from red and brightness channel impthresholded = ic.run("OR create", impthresholded, impthresholdedred); # convert to mask Prefs.blackBackground = True IJ.run(impthresholded, "Convert to Mask", "") # clear the region outside the roi clone=inputRoi.clone() clone.setLocation(0,0) Utility.clearOutsideRoi(impthresholded, clone) # create a hidden roi manager roim = RoiManager(True) # count the particlesimp.getProcessor().setColor(Color.green) countParticles(impthresholded, roim, detectionParameters.minSize, detectionParameters.maxSize, detectionParameters.minCircularity, detectionParameters.maxCircularity) # define a function to determine the percentage of pixels that are foreground in a binary image # inputs: # imp: binary image, 0=background, 1=foreground # roi: an roi def isRed(imp, roi): stats = imp.getStatistics() if (stats.mean>detectionParameters.redPercentage): return True else: return False def notRed(imp, roi): stats = imp.getStatistics() if (stats.mean>detectionParameters.redPercentage): return False else: return True allList=[] for roi in roim.getRoisAsArray(): allList.append(roi.clone()) # count particles that are red redList=CountParticles.filterParticlesWithFunction(redMask, allList, isRed) # count particles that are red blueList=CountParticles.filterParticlesWithFunction(redMask, allList, notRed) print "Total particles: "+str(len(allList)) print "Filtered particles: "+str(len(redList)) # for each roi add the offset such that the roi is positioned in the correct location for the # original image [roi.setLocation(roi.getXBase()+x1, roi.getYBase()+y1) for roi in allList] # create an overlay and add the rois overlay1=Overlay() inputRoi.setStrokeColor(Color.green) overlay1.add(inputRoi) [CountParticles.addParticleToOverlay(roi, overlay1, Color.red) for roi in redList] [CountParticles.addParticleToOverlay(roi, overlay1, Color.cyan) for roi in blueList] def drawAllRoisOnImage(imp, mainRoi, redList, blueList): imp.getProcessor().setColor(Color.green) IJ.run(imp, "Line Width...", "line=3"); imp.getProcessor().draw(inputRoi) imp.updateAndDraw() IJ.run(imp, "Line Width...", "line=1"); [CountParticles.drawParticleOnImage(imp, roi, Color.magenta) for roi in redList] [CountParticles.drawParticleOnImage(imp, roi, Color.green) for roi in blueList] imp.updateAndDraw() drawAllRoisOnImage(inputImp, inputRoi, redList, blueList) #drawAllRoisOnImage(trueColorImp, inputRoi, redList, blueList) # draw overlay #inputImp.setOverlay(overlay1) #inputImp.updateAndDraw() statsdict=CountParticles.calculateParticleStats(APlus, BPlus, redMask, roim.getRoisAsArray()) print inputRoiArea areas=statsdict['Areas'] poreArea=0 for area in areas: poreArea=poreArea+area ATotal=0 ALevels=statsdict['ALevel'] for A in ALevels: ATotal=ATotal+A AAverage=ATotal/len(ALevels) BTotal=0 BLevels=statsdict['BLevel'] for B in BLevels: BTotal=BTotal+B BAverage=BTotal/len(BLevels) redTotal=0 redPercentages=statsdict['redPercentage'] for red in redPercentages: redTotal=redTotal+red redAverage=redTotal/len(redPercentages) pixwidth=inputImp.getCalibration().pixelWidth inputRoiArea=inputRoiArea/(pixwidth*pixwidth) print str(len(allList))+" "+str(len(redList))+" "+str(len(blueList))+" "+str(poreArea/inputRoiArea)+" "+str(redAverage)
def __addroi(self, event) : if ( not self.__init) : IJ.showMessage("", "please start a new stack") return if ( not self.__initDIA) : IJ.showMessage("", "please select an image for DIA") return if ( not self.__initFLUO) : IJ.showMessage("", "please select an image for FLUO") return twres = TextWindow("measures-"+self.__name, "label\tname\tsol\tarea\tcirc\tAR\tFeret\taxis\traf\tdMajor\tdFeret\tdArea", "", 300, 450) tab="\t" self.__widthl = self.__display2.getText() IJ.selectWindow(self.__impF.getTitle()) self.__rm = RoiManager.getInstance() if (self.__rm==None): self.__rm = RoiManager() if self.__impF.getImageStackSize() > 1 : roisarray =[(roi, self.__rm.getSliceNumber(roi.getName())) for roi in self.__rm.getRoisAsArray()] else : roisarray =[(roi, 1) for roi in self.__rm.getRoisAsArray()] self.__rm.runCommand("reset") #self.__rm.runCommand("Delete") IJ.selectWindow(self.__impF.getTitle()) self.__maxraf=float(self.__display19.text) self.__minraf=float(self.__display20.text) count=1 for roielement in roisarray : roi = roielement[0] pos = roielement[1] lab = self.__impF.getImageStack().getShortSliceLabel(pos) if lab==None : lab=str(pos) if self.__conEllipses : IJ.selectWindow(self.__impF.getTitle()) self.__impF.setSlice(pos) self.__impF.setRoi(roi) self.__rm.runCommand("Add") IJ.run(self.__impF, "Fit Ellipse", "") ellipse=self.__impF.getRoi() params = ellipse.getParams() ferets = ellipse.getFeretValues() imp2 = Duplicator().run(self.__impF,pos,pos) IJ.run(imp2, "Rotate... ", "angle="+str(ferets[1])+" grid=0 interpolation=Bilinear enlarge slice") temproi=Roi((imp2.getWidth()-ferets[0])/2.0,(imp2.getHeight()-ferets[2])/2.0,ferets[0],ferets[2]) imp2.setRoi(temproi) imp3 = Duplicator().run(imp2,1,1) ip3=imp3.getProcessor() if int(self.__display5.text) < ip3.getWidth() < int(self.__display6.text) : self.__iplist.append(ip3) self.__display.text = self.__name + " cell " + str(len(self.__iplist)) fer=Line(params[0],params[1],params[2],params[3]) self.__cellsrois.append((fer, pos)) self.__labels.append(self.__isF.getShortSliceLabel(pos)) m=Morph(self.__impF, roi) twres.append(lab+tab+str(roi.getName())+tab+str(m.Solidity)+tab+str(m.Area)+tab+str(m.Circ)+tab+str(m.AR)+tab+str(m.MaxFeret)+tab+str(fer.getLength())+tab+str(1)+tab+str(0)+tab+str(0)+tab+str(0)) self.__dictCells[count]=(str(roi.getName()), lab, roi) count=count+1 continue if roi.getType() in [6,7] : self.__impF.setSlice(pos) self.__impF.setRoi(roi) self.__rm.runCommand("Add") elif roi.getType() in [2,4] : self.__impF.setSlice(pos) self.__impF.setRoi(roi) m=Morph(self.__impF, roi) m.setMidParams(10, 2) midroi=m.MidAxis if midroi == None : continue raf = m.MaxFeret/midroi.getLength() if (self.__maxraf < raf) or (raf < self.__minraf) : continue maxsol = float(self.__display7.text) minsol = float(self.__display8.text) maxarea = float(self.__display9.text) minarea = float(self.__display10.text) maxcirc = float(self.__display11.text) mincirc = float(self.__display12.text) maxar = float(self.__display13.text) minar = float(self.__display14.text) maxfer = float(self.__display15.text) minfer = float(self.__display16.text) maxmean = float(self.__display17.text) minmean = float(self.__display18.text) maxmferet = float(self.__display21.text) minmferet = float(self.__display22.text) testsol = (minsol<= m.Solidity <= maxsol) testarea = (minarea<= m.Area <= maxarea) testcirc = (mincirc<= m.Circ <= maxcirc) testar = (minar<= m.AR <= maxar) testfer = (minfer<= m.MaxFeret <= maxfer) testmean = (minmean <= m.Mean <= maxmean) testmferet = (minmferet <= m.MinFeret <= maxmferet) #print minmferet , m.MinFeret , maxmferet test = (testsol+testarea+testcirc+testar+testfer+testmean+testmferet)/7 if test : fmaj, ffmx, fa =[],[],[] for r in m.getMidSegments(10, 40, 0)[0] : if r == None : continue m2=Morph(self.__impF, r) fmaj.append(m2.Major) ffmx.append(m2.MaxFeret) fa.append(m2.Area) diffmajor, diffferet, diffarea = 0,0,0 if len(fa) > 4 : medfmaj = self.listmean(fmaj[1:-1]) medffmx = self.listmean(ffmx[1:-1]) medfa = self.listmean(fa[1:-1]) diffmajor = (max(fmaj[1:-1])-medfmaj)/medfmaj diffferet = (max(ffmx[1:-1])-medffmx)/medffmx diffarea = (max(fa[1:-1])-medfa)/medfa twres.append(lab+tab+str(roi.getName())+tab+str(m.Solidity)+tab+str(m.Area)+tab+str(m.Circ)+tab+str(m.AR)+tab+str(m.MaxFeret)+tab+str(midroi.getLength())+tab+str(m.MaxFeret/midroi.getLength())+tab+str(diffmajor)+tab+str(diffferet)+tab+str(diffarea)) #print lab+tab+str(roi.getName())+tab+str(m.Solidity)+tab+str(m.Area)+tab+str(m.Circ)+tab+str(m.AR)+tab+str(m.MaxFeret)+tab+str(midroi.getLength())+tab+str(m.MaxFeret/midroi.getLength())+tab+str(diffmajor)+tab+str(diffferet)+tab+str(diffarea) self.__impF.setRoi(roi) self.__rm.runCommand("Add") self.__impF.killRoi() self.__impF.setRoi(midroi) #self.__dictCells[str(roi.getName())]=(str(roi.getName()), lab, roi) self.__dictCells[count]=(str(roi.getName()), lab, roi) count=count+1 else : #print "test falls" continue else : print "out loop" continue straightener = Straightener() new_ip = straightener.straighten(self.__impF, midroi, int(self.__widthl)) if int(self.__display5.text) < new_ip.getWidth() < int(self.__display6.text) : self.__iplist.append(new_ip.convertToShort(False)) self.__display.text = self.__name + " cell " + str(len(self.__iplist)) #print "add", roi.getName(), roi.getType() self.__cellsrois.append((midroi, pos)) self.__labels.append(self.__isF.getShortSliceLabel(pos)) #roisarray=self.__rm.getRoisAsArray() #self.__rm.runCommand("reset") #self.__rm.runCommand("Delete") self.__impD.killRoi() self.__impF.killRoi() IJ.selectWindow(self.__impD.getTitle())
def process(dirIn, dirOut, expName, ps, pe, ts, te): jobid = commands.getoutput("echo $PBS_JOBID").split('.')[0] jobid = jobid.replace("[","_").replace("]","") # because the jobids look like 2356385[1] which causes problems print "job id: "+jobid jobdir = os.path.join("/tmp",str(jobid)+"_fiji") print "job dir: "+jobdir for p in range(ps,pe+1): pID = str(p); for t in range(ts,te+1): print "TIMEPOINT STARTING ***************" tID = "t"+str(t); print "time-point: "+tID; if os.path.isdir(jobdir): print "removing "+jobdir shutil.rmtree(jobdir) print "creating "+jobdir os.mkdir(jobdir) if stitching: fileOut = "rescaled_flipped_"; for z in range(zs,ze+1): zID = "z"+str(z); print "z-plane: "+zID; if bandpass: IJ.log("bandpass....") # load all images from same time point and same z-position fileID = expName+pID+"_b0"+tID+zID+"m.*"; IJ.log("opening images: "+os.path.join(dirIn,fileID)) IJ.run("Image Sequence...", "open=["+dirIn+"] starting=1 increment=1 scale=100 file=[] or=["+fileID+"] sort"); #selectWindow("im-2012-0007_Position35.tif_Files"); imp = IJ.getImage(); #imp.show(); imp.setTitle("Stack"); # illumination correction IJ.log("computing FFT..."); # run("Flip Horizontally", "stack"); impFFT = Duplicator().run(imp); for i in range(1, impFFT.getNSlices()+1): print "FFT of slice "+str(i) impFFT.setSlice(i) IJ.run(impFFT, "Bandpass Filter...", "filter_large=10000 filter_small=200 suppress=None tolerance=5 "); #impFFT.show() #stats = imp.getStatistics(Measurements.MEAN) #IJ.log("stats.mean = "+str(stats.mean)); # this is only the mean of one slice...is this a problem? print "dividing image stack by FFT stack..."; ic = ImageCalculator() impCorr = ic.run("Divide create 32-bit stack", imp, impFFT); #impCorr.show() def computeMean(pixels): return sum(pixels) / float(len(pixels)) print "multiplying each image by 128/mean for going back to 8 bit space..." stack = impCorr.getStack() for i in range(1, impCorr.getNSlices()+1): ip = stack.getProcessor(i).convertToFloat() mean = computeMean(ip.getPixels()) print "multiplying slice "+str(i)+" by "+str(float(128/mean)) ip.multiply(float(128/mean)) IJ.log("converting from 32-bit to 8-bit...") IJ.setMinAndMax(impCorr, 0, 255); IJ.run(impCorr,"8-bit",""); #IJ.saveAs(impCorr, "Tiff", "/Users/tischi/Documents/processed.tif"); #ff #impCorr.show() # save images IJ.log("saving bandpass corrected image sequence: "+os.path.join(jobdir,fileOut)) IJ.run(impCorr, "Image Sequence... ", "format=TIFF name=["+fileOut+"] start=1 digits=4 save=["+jobdir+"]"); if check: IJ.run(impCorr, "Image Sequence... ", "format=TIFF name=["+fileOut+"] start=1 digits=4 save=["+dirOut+"]"); #impCorr.close(); imp.close(); impFFT.hide(); # stitching IJ.log("STITCHING START **********") layoutFile = copyStitchingLayoutFile(dirIn,expName,jobdir,ps) ###layoutFile = makeStitchingLayoutFile(jobdir) createPreview = 0 computeOverlap = 0 fusion_method="Linear Blending" handleRGB = "Red, Green and Blue" showImage = 0 #fusion=1 regression=0.30 max/avg=2.50 absolute=3.50" st = Stitch_Image_Collection() st.alpha = 1 IJ.log("layout file: "+str(layoutFile)) impStitched = st.work(layoutFile, createPreview, computeOverlap, fusion_method, handleRGB, showImage) stitchedFile = os.path.join(jobdir,tID+zID+"_stitched.tif"); #impStitched.show() IJ.saveAs(impStitched,"Tiff", stitchedFile); if check: print os.path.join(dirOut,tID+zID+"_stitched.tif") stitchedFile = os.path.join(dirOut,tID+zID+"_stitched.tif"); IJ.saveAs(impStitched,"Tiff", stitchedFile); IJ.log("STITCHING END **********") if combine_z: IJ.log("combine z.....") ######### IJ.log("load stitched images into a stack...") for z in range(zs,ze+1): zID = "z"+str(z); stitchedFile = os.path.join(jobdir,tID+zID+"_stitched.tif"); IJ.log("opening "+stitchedFile) imp = IJ.openImage(stitchedFile) if z==zs: stack = ImageStack(imp.width,imp.height) stack.addSlice(imp.getProcessor()) imp = ImagePlus("stack", stack) #imp.show() ######## ######## IJ.log("cropping...") imp.setRoi(xs, ys, xe, ye); IJ.run(imp, "Crop", ""); #imp.show() ######## # the following normalisation should not be necessary, because they are already all 128/mean normalised #IJ.log("-- normalise intensity of all slices...") #stats = imp.getStatistics(Measurements.MEAN) #IJ.log("stats.mean = "+str(stats.mean)); # this is only the mean of one slice...is this a problem? #stack = imp.getStack() #for i in range(1, impFFT.getNSlices()+1): # ip = stack.getProcessor(i).convertToFloat() # ip.multiply(128/stats.mean) # #stack.setSlice(stack.getSliceLabel(i), ip) #run("Set Slice...", "slice="+1); #run("Set Measurements...", " mean redirect=None decimal=9"); #run("Select None"); #setBatchMode(true); #setMinAndMax(0, 255); run("32-bit"); #for(l=0; l<nSlices+1; l++) { ## run("Select All"); # run("Clear Results"); # run("Measure"); # picsum=getResult("Mean",0); # //if(l==0){picsum1=picsum;} # //int_ratio=picsum1/picsum; # int_ratio=128/picsum; # run("Select None"); # IJ.log("ratio ="+int_ratio); # run("Multiply...", "slice value="+int_ratio); # run("Next Slice [>]"); #} #setBatchMode(false); # stop here and try by hand #... #dfgfd #//stack-reg #//IJ.log("register xy...") #//run("StackReg", "transformation=Translation"); #// project into 1 plane .... #// run("Extended Depth of Field (Easy mode)..."); #//run("Z Project...", "start=["+1+"] stop=["+ze+"] projection=[Standard Deviation]"); doEDF = True if doEDF: IJ.log("EDF: start...") parameters = Parameters() parameters.setQualitySettings(1) parameters.setTopologySettings(0) parameters.show3dView = False parameters.showTopology = False edfh = ExtendedDepthOfFieldHeadless(imp, parameters) imp = edfh.processHeadless() IJ.log("EDF: done.") #imp.show() IJ.log("EDF: converting from 32-bit to 8-bit...") IJ.setMinAndMax(imp, 0, 255); IJ.run(imp,"8-bit",""); edfFile = os.path.join(dirOut,expName+pID+"-"+tID+"_EDOF_noTimeNorm.tif"); IJ.log("EDF save: "+edfFile) IJ.saveAs(imp,"Tiff", edfFile); IJ.log("EDF save: done.") #close(); // projection #close(); // stack print "TIMEPOINT FINISHED ***************" if os.path.isdir(jobdir): print "removing "+jobdir shutil.rmtree(jobdir)
import Utility reload(Utility) import CountParticles reload(CountParticles) from CountParticles import countParticles #inputDirectory='/home/bnorthan/Brian2012/Round2/RogueImageJPlugins/SpotDetection/Images/' #inputName='001-D0_cropped.tif' #dataset=data.open(inputDirectory+inputName) #display.createDisplay(dataset.getName(), dataset) inputImp=IJ.getImage() inputDataset=Utility.getDatasetByName(data, inputImp.getTitle()) truecolor1=Duplicator().run(inputImp) truecolor1.show() # get the roi that will be processed inputRoi=inputImp.getRoi().clone() inputRec = inputRoi.getBounds() x1=long(inputRec.getX()) y1=long(inputRec.getY()) x2=x1+long(inputRec.getWidth())-1 y2=y1+long(inputRec.getHeight())-1 # crop the roi interval=FinalInterval( array([x1, y1 ,0], 'l'), array([x2, y2, 2], 'l') ) cropped=ops.crop(interval, None, inputDataset.getImgPlus() )
def runOneFile(fullFilePath): global gFileType global gNumChannels global gAlignBatchVersion if not os.path.isfile(fullFilePath): bPrintLog('\nERROR: runOneFile() did not find file: ' + fullFilePath + '\n',0) return 0 bPrintLog(time.strftime("%H:%M:%S") + ' starting runOneFile(): ' + fullFilePath, 1) enclosingPath = os.path.dirname(fullFilePath) head, tail = os.path.split(enclosingPath) enclosingPath += '/' #make output folders destFolder = enclosingPath + tail + '_channels/' if not os.path.isdir(destFolder): os.makedirs(destFolder) destMaxFolder = destFolder + 'max/' if not os.path.isdir(destMaxFolder): os.makedirs(destMaxFolder) if gDoAlign: destAlignmentFolder = destFolder + 'alignment/' if not os.path.isdir(destAlignmentFolder): os.makedirs(destAlignmentFolder) if gSave8bit: eightBitFolder = destFolder + 'channels8/' if not os.path.isdir(eightBitFolder): os.makedirs(eightBitFolder) eightBitMaxFolder = eightBitFolder + 'max/' if not os.path.isdir(eightBitMaxFolder): os.makedirs(eightBitMaxFolder) if gFileType=='tif': # open .tif image imp = Opener().openImage(fullFilePath) else: # open .lsm cmdStr = 'open=%s autoscale color_mode=Default view=Hyperstack stack_order=XYCZT' % (fullFilePath,) IJ.run('Bio-Formats Importer', cmdStr) lsmpath, lsmfilename = os.path.split(fullFilePath) lsWindow = lsmfilename imp = WindowManager.getImage(lsWindow) # get parameters of image (width, height, nChannels, nSlices, nFrames) = imp.getDimensions() bitDepth = imp.getBitDepth() infoStr = imp.getProperty("Info") #get all .tif tags if not infoStr: infoStr = '' infoStr += 'bAlignBatch_Version=' + str(gAlignBatchVersion) + '\n' infoStr += 'bAlignBatch_Time=' + time.strftime("%Y%m%d") + '_' + time.strftime("%H%M%S") + '\n' msgStr = 'w:' + str(width) + ' h:' + str(height) + ' slices:' + str(nSlices) \ + ' channels:' + str(nChannels) + ' frames:' + str(nFrames) + ' bitDepth:' + str(bitDepth) bPrintLog(msgStr, 1) path, filename = os.path.split(fullFilePath) shortName, fileExtension = os.path.splitext(filename) # # look for num channels in ScanImage infoStr if gGetNumChanFromScanImage: for line in infoStr.split('\n'): #scanimage.SI4.channelsSave = [1;2] scanimage4 = find(line, 'scanimage.SI4.channelsSave =') == 0 #state.acq.numberOfChannelsSave=2 scanimage3 = find(line, 'state.acq.numberOfChannelsSave=') == 0 if scanimage3: #print 'line:', line equalIdx = find(line, '=') line2 = line[equalIdx+1:] if gGetNumChanFromScanImage: gNumChannels = int(line2) bPrintLog('over-riding gNumChannels with: ' + str(gNumChannels), 2) if scanimage4: #print ' we have a scanimage 4 file ... now i need to exptract the number of channel' #print 'line:', line equalIdx = find(line, '=') line2 = line[equalIdx+1:] for delim in ';[]': line2 = line2.replace(delim, ' ') if gGetNumChanFromScanImage: gNumChannels = len(line2.split()) bPrintLog('over-riding gNumChannels with: ' + str(gNumChannels), 2) # show imp.show() # split channels if necc. and grab the original window names if gNumChannels == 1: origImpWinStr = imp.getTitle() #use this when only one channel origImpWin = WindowManager.getWindow(origImpWinStr) #returns java.awt.Window if gNumChannels == 2: winTitle = imp.getTitle() bPrintLog('Deinterleaving 2 channels...', 1) IJ.run('Deinterleave', 'how=2 keep') #makes ' #1' and ' #2', with ' #2' frontmost origCh1WinStr = winTitle + ' #1' origCh2WinStr = winTitle + ' #2' origCh1Imp = WindowManager.getImage(origCh1WinStr) origCh2Imp = WindowManager.getImage(origCh2WinStr) origCh1File = destFolder + shortName + '_ch1.tif' origCh2File = destFolder + shortName + '_ch2.tif' # work on a copy, mostly for alignment with cropping copy = Duplicator().run(imp) #copy.copyAttributes(imp) #don't copy attributes, it copies the name (which we do not want) copy.show() # # crop (on copy) if gDoCrop: bPrintLog('making cropping rectangle (left,top,width,height) ',1) bPrintLog(str(gCropLeft) + ' ' + str(gCropTop) + ' ' +str(gCropWidth) + ' ' +str(gCropHeight), 2) roi = Roi(gCropLeft, gCropTop, gCropWidth, gCropHeight) #left,top,width,height copy.setRoi(roi) time.sleep(0.5) # otherwise, crop SOMETIMES failes. WHAT THE F**K FIJI DEVELOPERS, REALLY, WHAT THE F**K #bPrintLog('cropping', 1) IJ.run('Crop') infoStr += 'bCropping=' + str(gCropLeft) + ',' + str(gCropTop) + ',' + str(gCropWidth) + ',' + str(gCropHeight) + '\n' # # remove calibration ( on original) if gRemoveCalibration: cal = imp.getCalibration() calCoeff = cal.getCoefficients() if calCoeff: msgStr = 'Calibration is y=a+bx' + ' a=' + str(calCoeff[0]) + ' b=' + str(calCoeff[1]) bPrintLog(msgStr, 1) #remove calibration bPrintLog('\tRemoving Calibration', 2) imp.setCalibration(None) #without these, 8-bit conversion goes to all 0 !!! what the f**k !!! #bPrintLog('calling imp.resetStack() and imp.resetDisplayRange()', 2) imp.resetStack() imp.resetDisplayRange() #get and print out min/max origMin = StackStatistics(imp).min origMax = StackStatistics(imp).max msgStr = '\torig min=' + str(origMin) + ' max=' + str(origMax) bPrintLog(msgStr, 2) # 20150723, 'shift everybody over by linear calibration intercept calCoeff[0] - (magic number) if 1: # [1] was this #msgStr = 'Subtracting original min '+str(origMin) + ' from stack.' #bPrintLog(msgStr, 2) #subArgVal = 'value=%s stack' % (origMin,) #IJ.run('Subtract...', subArgVal) # [2] now this #msgStr = 'Adding calCoeff[0] '+str(calCoeff[0]) + ' from stack.' #bPrintLog(msgStr, 2) #addArgVal = 'value=%s stack' % (int(calCoeff[0]),) #IJ.run('Add...', addArgVal) # [3] subtract a magic number 2^15-2^7 = 32768 - 128 magicNumber = gLinearShift #2^15 - 128 msgStr = 'Subtracting a magic number (linear shift) '+str(magicNumber) + ' from stack.' bPrintLog(msgStr, 2) infoStr += 'bLinearShift=' + str(gLinearShift) + '\n' subArgVal = 'value=%s stack' % (gLinearShift,) IJ.run(imp, 'Subtract...', subArgVal) # 20150701, set any pixel <0 to 0 if 0: ip = imp.getProcessor() # returns a reference pixels = ip.getPixels() # returns a reference msgStr = '\tSet all pixels <0 to 0. This was added 20150701 ...' bPrintLog(msgStr, 2) pixels = map(lambda x: 0 if x<0 else x, pixels) bPrintLog('\t\t... done', 2) #get and print out min/max newMin = StackStatistics(imp).min newMax = StackStatistics(imp).max msgStr = '\tnew min=' + str(newMin) + ' max=' + str(newMax) bPrintLog(msgStr, 2) #append calibration to info string infoStr += 'bCalibCoeff_a = ' + str(calCoeff[0]) + '\n' infoStr += 'bCalibCoeff_b = ' + str(calCoeff[1]) + '\n' infoStr += 'bNewMin = ' + str(newMin) + '\n' infoStr += 'bNewMax = ' + str(newMax) + '\n' # # set up if gNumChannels == 1: impWinStr = copy.getTitle() #use this when only one channel impWin = WindowManager.getWindow(impWinStr) #returns java.awt.Window if gNumChannels == 2: winTitle = copy.getTitle() bPrintLog('Deinterleaving 2 channels...', 1) IJ.run('Deinterleave', 'how=2 keep') #makes ' #1' and ' #2', with ' #2' frontmost ch1WinStr = winTitle + ' #1' ch2WinStr = winTitle + ' #2' ch1Imp = WindowManager.getImage(ch1WinStr) ch2Imp = WindowManager.getImage(ch2WinStr) ch1File = destFolder + shortName + '_ch1.tif' ch2File = destFolder + shortName + '_ch2.tif' # # alignment if gDoAlign and gNumChannels == 1 and copy.getNSlices()>1: infoStr += 'AlignOnChannel=1' + '\n' #snap to middle slice if gAlignOnMiddleSlice: middleSlice = int(math.floor(copy.getNSlices() / 2)) #int() is necc., python is f*****g picky else: middleSlice = gAlignOnThisSlice copy.setSlice(middleSlice) transformationFile = destAlignmentFolder + shortName + '.txt' bPrintLog('MultiStackReg aligning:' + impWinStr, 1) stackRegParams = 'stack_1=[%s] action_1=Align file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body] save' %(impWin,transformationFile) IJ.run('MultiStackReg', stackRegParams) infoStr += 'AlignOnSlice=' + str(middleSlice) + '\n' #20150723, we just aligned on a cropped copy, apply alignment to original imp origImpTitle = imp.getTitle() stackRegParams = 'stack_1=[%s] action_1=[Load Transformation File] file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body]' %(origImpTitle,transformationFile) IJ.run('MultiStackReg', stackRegParams) if gDoAlign and gNumChannels == 2 and ch1Imp.getNSlices()>1 and ch2Imp.getNSlices()>1: #apply to gAlignThisChannel alignThisWindow = '' applyAlignmentToThisWindow = '' if gAlignThisChannel == 1: infoStr += 'AlignOnChannel=1' + '\n' transformationFile = destAlignmentFolder + shortName + '_ch1.txt' alignThisWindow = ch1WinStr applyAlignmentToThisWindow = ch2WinStr else: infoStr += 'AlignOnChannel=2' + '\n' transformationFile = destAlignmentFolder + shortName + '_ch2.txt' alignThisWindow = ch2WinStr applyAlignmentToThisWindow = ch1WinStr alignThisImp = WindowManager.getImage(alignThisWindow) #snap to middle slice if gAlignOnMiddleSlice: middleSlice = int(math.floor(alignThisImp.getNSlices() / 2)) #int() is necc., python is f*****g picky else: middleSlice = gAlignOnThisSlice alignThisImp.setSlice(middleSlice) infoStr += 'bAlignOnSlice=' + str(middleSlice) + '\n' bPrintLog('MultiStackReg aligning:' + alignThisWindow, 1) stackRegParams = 'stack_1=[%s] action_1=Align file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body] save' %(alignThisWindow,transformationFile) IJ.run('MultiStackReg', stackRegParams) # 20150723, we just aligned on a copy, apply alignment to both channels of original # ch1 bPrintLog('MultiStackReg applying alignment to:' + origCh1WinStr, 1) stackRegParams = 'stack_1=[%s] action_1=[Load Transformation File] file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body]' %(origCh1WinStr,transformationFile) IJ.run('MultiStackReg', stackRegParams) # ch2 bPrintLog('MultiStackReg applying alignment to:' + origCh2WinStr, 1) stackRegParams = 'stack_1=[%s] action_1=[Load Transformation File] file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body]' %(origCh2WinStr,transformationFile) IJ.run('MultiStackReg', stackRegParams) #apply alignment to other window #bPrintLog('MultiStackReg applying alignment to:' + applyAlignmentToThisWindow, 1) #applyAlignThisImp = WindowManager.getImage(applyAlignmentToThisWindow) #stackRegParams = 'stack_1=[%s] action_1=[Load Transformation File] file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body]' %(applyAlignmentToThisWindow,transformationFile) #IJ.run('MultiStackReg', stackRegParams) elif gDoAlign: bPrintLog('Skipping alignment, there may be only one slice?',3) # # save if gNumChannels == 1: imp.setProperty("Info", infoStr); impFile = destFolder + shortName + '.tif' #bPrintLog('Saving:' + impFile, 1) bSaveStack(imp, impFile) #max project bSaveZProject(imp, destMaxFolder, shortName) if gNumChannels == 2: #ch1 origCh1Imp.setProperty("Info", infoStr); #bPrintLog('Saving:' + ch1File, 1) bSaveStack(origCh1Imp, ch1File) #max project bSaveZProject(origCh1Imp, destMaxFolder, shortName+'_ch1') #ch2 origCh2Imp.setProperty("Info", infoStr); #bPrintLog('Saving:' + ch2File, 1) bSaveStack(origCh2Imp, ch2File) #max project bSaveZProject(origCh2Imp, destMaxFolder, shortName+'_ch2') # # post convert to 8-bit and save if gSave8bit: if bitDepth == 16: if gNumChannels == 1: bPrintLog('Converting to 8-bit:' + impWinStr, 1) IJ.selectWindow(impWinStr) #IJ.run('resetMinAndMax()') IJ.run("8-bit") impFile = eightBitFolder + shortName + '.tif' bPrintLog('Saving 8-bit:' + impFile, 2) bSaveStack(imp, impFile) #max project bSaveZProject(imp, eightBitMaxFolder, shortName) if gNumChannels == 2: # bPrintLog('Converting to 8-bit:' + origCh1WinStr, 1) IJ.selectWindow(origCh1WinStr) IJ.run("8-bit") impFile = eightBitFolder + shortName + '_ch1.tif' bPrintLog('Saving 8-bit:' + impFile, 2) bSaveStack(origCh1Imp, impFile) #max project bSaveZProject(origCh1Imp, eightBitMaxFolder, shortName+'_ch1') # bPrintLog('Converting to 8-bit:' + origCh2WinStr, 1) IJ.selectWindow(origCh2WinStr) #IJ.run('resetMinAndMax()') IJ.run("8-bit") impFile = eightBitFolder + shortName + '_ch2.tif' bPrintLog('Saving 8-bit:' + impFile, 2) bSaveStack(origCh2Imp, impFile) #max project bSaveZProject(origCh2Imp, eightBitMaxFolder, shortName+'_ch2') # # close original window imp.changes = 0 imp.close() #copy copy.changes = 0 copy.close() # # close ch1/ch2 if gNumChannels == 2: #original origCh1Imp.changes = 0 origCh1Imp.close() origCh2Imp.changes = 0 origCh2Imp.close() #copy ch1Imp.changes = 0 ch1Imp.close() ch2Imp.changes = 0 ch2Imp.close() bPrintLog(time.strftime("%H:%M:%S") + ' finished runOneFile(): ' + fullFilePath, 1)
def poreDetectionUV(inputImp, inputDataset, inputRoi, ops, data, display, detectionParameters): # set calibration detectionParameters.setCalibration(inputImp); # calculate area of roi stats=inputImp.getStatistics() inputRoiArea=stats.area # get the bounding box of the active roi inputRec = inputRoi.getBounds() x1=long(inputRec.getX()) y1=long(inputRec.getY()) x2=x1+long(inputRec.getWidth())-1 y2=y1+long(inputRec.getHeight())-1 # crop the roi interval=FinalInterval( array([x1, y1 ,0], 'l'), array([x2, y2, 2], 'l') ) #cropped=ops.image().crop(interval, None, inputDataset.getImgPlus() ) cropped=ops.image().crop(inputDataset.getImgPlus() , interval) datacropped=data.create(cropped) display.createDisplay("cropped", datacropped) croppedPlus=IJ.getImage() # instantiate the duplicator and the substackmaker classes duplicator=Duplicator() substackMaker=SubstackMaker() # duplicate the roi duplicate=duplicator.run(croppedPlus) # convert duplicate of roi to HSB and get brightness IJ.run(duplicate, "HSB Stack", ""); brightnessPlus=substackMaker.makeSubstack(duplicate, "3-3") brightness=ImgPlus(ImageJFunctions.wrapByte(brightnessPlus)) brightnessPlus.setTitle("Brightness") #brightnessPlus.show() # make another duplicate, split channels and get red duplicate=duplicator.run(croppedPlus) channels=ChannelSplitter().split(duplicate) redPlus=channels[0] red=ImgPlus(ImageJFunctions.wrapByte(redPlus)) # convert to lab IJ.run(croppedPlus, "Color Transformer", "colour=Lab") IJ.selectWindow('Lab') labPlus=IJ.getImage() croppedPlus.changes=False croppedPlus.close() # get the A channel APlus=substackMaker.makeSubstack(labPlus, "2-2") APlus.setTitle('A') #APlus.show() APlus.getProcessor().resetMinAndMax() #APlus.updateAndDraw() AThresholded=threshold(APlus, -10, 50) # get the B channel BPlus=substackMaker.makeSubstack(labPlus, "3-3") BPlus.setTitle('B') #BPlus.show() BPlus.getProcessor().resetMinAndMax() #BPlus.updateAndDraw() BThresholded=threshold(BPlus, -10, 50) # AND the Athreshold and Bthreshold to get a map of the red pixels ic = ImageCalculator(); redMask = ic.run("AND create", AThresholded, BThresholded); IJ.run(redMask, "Divide...", "value=255"); labPlus.close() fast=True # threshold the spots from the red channel if (fast==False): thresholdedred=SpotDetectionGray(red, data, display, ops, "triangle") impthresholdedred = ImageJFunctions.wrap(thresholdedred, "wrapped") else: impthresholdedred=SpotDetection2(redPlus) # threshold the spots from the brightness channel if (fast==False): thresholded=SpotDetectionGray(brightness, data, display, ops, "triangle") impthresholded=ImageJFunctions.wrap(thresholded, "wrapped") else: impthresholded=SpotDetection2(brightnessPlus) # or the thresholding results from red and brightness channel impthresholded = ic.run("OR create", impthresholded, impthresholdedred); roim=RoiManager(True) # convert to mask Prefs.blackBackground = True IJ.run(impthresholded, "Convert to Mask", "") def isRed(imp, roi): stats = imp.getStatistics() if (stats.mean>detectionParameters.porphyrinRedPercentage): return True else: return False def notRed(imp, roi): stats = imp.getStatistics() if (stats.mean>detectionParameters.porphyrinRedPercentage): return False else: return True roiClone=inputRoi.clone() roiClone.setLocation(0,0) Utility.clearOutsideRoi(impthresholded, roiClone) impthresholded.show() countParticles(impthresholded, roim, detectionParameters.porphyrinMinSize, detectionParameters.porphyrinMaxSize, \ detectionParameters.porphyrinMinCircularity, detectionParameters.porphyrinMaxCircularity) uvPoreList=[] for roi in roim.getRoisAsArray(): uvPoreList.append(roi.clone()) #allList=uvPoreList+closedPoresList+openPoresList # count particles that are porphyrins (red) porphyrinList=CountParticles.filterParticlesWithFunction(redMask, uvPoreList, isRed) # count particles that are visible on uv but not porphyrins sebumList=CountParticles.filterParticlesWithFunction(redMask, uvPoreList, notRed) # for each roi add the offset such that the roi is positioned in the correct location for the # original image [roi.setLocation(roi.getXBase()+x1, roi.getYBase()+y1) for roi in uvPoreList] # draw the ROIs on to the image inputImp.getProcessor().setColor(Color.green) IJ.run(inputImp, "Line Width...", "line=3"); inputImp.getProcessor().draw(inputRoi) IJ.run(inputImp, "Line Width...", "line=1"); [CountParticles.drawParticleOnImage(inputImp, roi, Color.magenta) for roi in porphyrinList] [CountParticles.drawParticleOnImage(inputImp, roi, Color.green) for roi in sebumList] inputImp.updateAndDraw() # calculate stats for the UV visible particles detectionParameters.setCalibration(APlus) statsDictUV=CountParticles.calculateParticleStatsUV(APlus, BPlus, redMask, roim.getRoisAsArray()) totalUVPoreArea=0 for area in statsDictUV['Areas']: totalUVPoreArea=totalUVPoreArea+area averageUVPoreArea=totalUVPoreArea/len(statsDictUV['Areas']) poreDiameter=0 for diameter in statsDictUV['Diameters']: poreDiameter=poreDiameter+diameter poreDiameter=poreDiameter/len(statsDictUV['Diameters']) redTotal=0 for red in statsDictUV['redPercentage']: redTotal=redTotal+red redAverage=redTotal/len(statsDictUV['redPercentage']) statslist=[len(porphyrinList), 100*redAverage]; statsheader=[Messages.Porphyrins, Messages.PercentageRedPixels] print("Roi Area: "+str(inputRoiArea)) print("Total Pore Area: "+str(totalUVPoreArea)) print("Average Pore Area: "+str(averageUVPoreArea)) print str(len(uvPoreList))+" "+str(len(porphyrinList))+" "+str(len(sebumList))+" "+str(100*totalUVPoreArea/inputRoiArea)+" "+str(100*redAverage) print "cp min circularity"+str(detectionParameters.closedPoresMinCircularity)+":"+str(detectionParameters.closedPoresMinSize) # close the thresholded image impthresholded.changes=False impthresholded.close() return uvPoreList, statslist, statsheader
return Pixel_size ######### open image using dialogue box #imp = IJ.getImage() original = IJ.openImage(getFile()) original.show() ########## Use thresholding and selection to define UFOV ################################################################################### #IJ.run("ROI Manager...", "") # not sure if I need this IJ.setRawThreshold(original, 1, 255,'') # background pixels have value 0. See IMAGE>ADJUST>THRESHOLD IJ.run(original, "Create Selection", "") # add bounding box. See EDIT>SELECTION IJ.run(original,"To Bounding Box", "") # this box defines the UFOV. See EDIT>SELECTION IJ.resetThreshold(original) # get back original now UFOV is definedthresholding UFOV = Duplicator().run(original) # duplicate the original image, only the CFOV UFOV.setTitle("UFOV") UFOV.show() CFOV_fraction = 0.75 # choose the fraction of the UFOV that defines the CFOV IJ.run(original,"Scale... ", "x="+str(CFOV_fraction)+" y="+str(CFOV_fraction)+" centered") # rescale bounding box to get CFOV CFOV = Duplicator().run(original) # duplicate the original image, only the CFOV CFOV.setTitle("CFOV") CFOV.show() ######### Nema process including Re-bin image to larger pixels ################################################################################ desired_pixel_width = getPixel() # 6.4 mm default, remember tolerance is +/-30% current_pixel_width = CFOV.getCalibration().pixelWidth #get pixel width, 1.16 mm shrink_factor = int(desired_pixel_width/current_pixel_width) # must be an integer
def getThreshold(self, imp, method): thresholder = Auto_Threshold() duplicator = Duplicator() tmp = duplicator.run(imp) return thresholder.exec(tmp, method, False, False, True, False, False, True)
def analyze(iDataSet, tbModel, p, output_folder): # # LOAD FILES # filepath = tbModel.getFileAPth(iDataSet, "RAW", "IMG") filename = tbModel.getFileName(iDataSet, "RAW", "IMG") print("Analyzing: "+filepath) IJ.run("Bio-Formats Importer", "open=["+filepath+"] color_mode=Default view=Hyperstack stack_order=XYCZT"); imp = IJ.getImage() # # INIT # IJ.run("Options...", "iterations=1 count=1"); # # SCALING # IJ.run(imp, "Scale...", "x="+str(p["scale"])+" y="+str(p["scale"])+" z=1.0 interpolation=Bilinear average process create"); imp = IJ.getImage() # save output file output_file = filename+"--downscale_input.tif" IJ.saveAs(IJ.getImage(), "TIFF", os.path.join(output_folder, output_file)) tbModel.setFileAPth(output_folder, output_file, iDataSet, "INPUT","IMG") # # CONVERSION # #IJ.run(imp, "8-bit", ""); # # CROPPING # #imp.setRoi(392,386,750,762); #IJ.run(imp, "Crop", ""); # # BACKGROUND SUBTRACTION # # IJ.run(imp, "Subtract...", "value=32768 stack"); IJ.run(imp, "Z Project...", "projection=[Average Intensity]"); imp_avg = IJ.getImage() ic = ImageCalculator(); imp = ic.run("Subtract create 32-bit stack", imp, imp_avg); # # REGION SEGMENTATION # imp1 = Duplicator().run(imp, 1, imp.getImageStackSize()-1) imp2 = Duplicator().run(imp, 2, imp.getImageStackSize()) imp_diff = ic.run("Subtract create 32-bit stack", imp1, imp2); #imp_diff.show() IJ.run(imp_diff, "Z Project...", "projection=[Standard Deviation]"); imp_diff_sd = IJ.getImage() # save IJ.run(imp_diff_sd, "Gaussian Blur...", "sigma=5"); output_file = filename+"--sd.tif" IJ.saveAs(imp_diff_sd, "TIFF", os.path.join(output_folder, output_file)) tbModel.setFileAPth(output_folder, output_file, iDataSet, "SD","IMG") IJ.run(imp_diff_sd, "Enhance Contrast", "saturated=0.35"); IJ.run(imp_diff_sd, "8-bit", ""); IJ.run(imp_diff_sd, "Properties...", "unit=p pixel_width=1 pixel_height=1 voxel_depth=1"); IJ.run(imp_diff_sd, "Auto Local Threshold", "method=Niblack radius=60 parameter_1=2 parameter_2=0 white"); rm = ROIManipulator.getEmptyRm() IJ.run(imp_diff_sd, "Analyze Particles...", "add"); # select N largest Rois diameter_roi = [] for i in range(rm.getCount()): roi = rm.getRoi(i) diameter_roi.append([roi.getFeretsDiameter(), roi]) diameter_roi = sorted(diameter_roi, reverse=True) #print diameter_roi rm.reset() for i in range(min(len(diameter_roi), p["n_rois"])): rm.addRoi(diameter_roi[i][1]) # save output_file = filename+"--rois" ROIManipulator.svRoisToFl(output_folder, output_file, rm.getRoisAsArray()) tbModel.setFileAPth(output_folder, output_file+".zip", iDataSet, "REGIONS","ROI") # # FFT in each region # IJ.run(imp, "Variance...", "radius=2 stack"); output_file = filename+"--beats.tif" IJ.saveAs(imp, "TIFF", os.path.join(output_folder, output_file)) tbModel.setFileAPth(output_folder, output_file, iDataSet, "BEATS","IMG") n = rm.getCount() for i_roi in range(n): imp_selection = Duplicator().run(imp) rm.select(imp_selection, i_roi) IJ.run(imp_selection, "Clear Outside", "stack"); imp_selection.show() # FFT using Parallel FFTJ transformer = FloatTransformer(imp_selection.getStack()) transformer.fft() imp_fft = transformer.toImagePlus(SpectrumType.FREQUENCY_SPECTRUM) imp_fft.show() # Analyze FFt IJ.run(imp_fft, "Gaussian Blur 3D...", "x=0 y=0 z=1.5"); IJ.run(imp_fft, "Plot Z-axis Profile", ""); output_file = filename+"--Region"+str(i_roi+1)+"--fft.tif" IJ.saveAs(IJ.getImage(), "TIFF", os.path.join(output_folder, output_file)) tbModel.setFileAPth(output_folder, output_file, iDataSet, "FFT_R"+str(i_roi+1),"IMG") IJ.run(imp_fft, "Select All", ""); rm.addRoi(imp_fft.getRoi()) rm.select(rm.getCount()) rt = ResultsTable() rt = rm.multiMeasure(imp_fft); #print(rt.getColumnHeadings); x = rt.getColumn(rt.getColumnIndex("Mean1")) #rm.runCommand("delete") peak_height_pos = [] x_min = 10 for i in range(x_min,len(x)/2): before = x[i-1] center = x[i] after = x[i+1] if (center>before) and (center>after): peak_height_pos.append([float(x[i]),i]) if len(peak_height_pos)>0: peak_height_pos = sorted(peak_height_pos, reverse=True) n_max = 3 for i_max in range(min(len(peak_height_pos),n_max)): tbModel.setNumVal(round(float(len(x))/float(peak_height_pos[i_max][1]),2), iDataSet, "F"+str(i_max+1)+"_R"+str(i_roi+1)) tbModel.setNumVal(int(peak_height_pos[i_max][0]), iDataSet, "A"+str(i_max+1)+"_R"+str(i_roi+1))
def poreDetectionTrueColor(inputImp, inputDataset, inputRoi, ops, data, display, detectionParameters): detectionParameters.setCalibration(inputImp); # calculate area of roi stats=inputImp.getStatistics() inputRoiArea=stats.area # get the bounding box of the active roi inputRec = inputRoi.getBounds() x1=long(inputRec.getX()) y1=long(inputRec.getY()) x2=x1+long(inputRec.getWidth())-1 y2=y1+long(inputRec.getHeight())-1 # crop the roi interval=FinalInterval( array([x1, y1 ,0], 'l'), array([x2, y2, 2], 'l') ) cropped=ops.image().crop(inputDataset.getImgPlus(), interval ) datacropped=data.create(cropped) display.createDisplay("cropped", datacropped) croppedPlus=IJ.getImage() # instantiate the duplicator and the substackmaker classes duplicator=Duplicator() substackMaker=SubstackMaker() # duplicate the roi duplicate=duplicator.run(croppedPlus) # separate into RGB and get the blue channel IJ.run(duplicate, "RGB Stack", "") bluePlus=substackMaker.makeSubstack(duplicate, "3-3") blue=ImgPlus(ImageJFunctions.wrapByte(bluePlus)) bluePlus.setTitle("Blue") # duplicate and look for bright spots thresholdedLight=SpotDetection2(bluePlus) # duplicate and look for dark spots thresholdedDark=SpotDetection3(bluePlus, True) # convert to mask Prefs.blackBackground = True #IJ.run(thresholdedDark, "Convert to Mask", "")substackMaker # clear the region outside the roi clone=inputRoi.clone() clone.setLocation(0,0) Utility.clearOutsideRoi(thresholdedLight, clone) Utility.clearOutsideRoi(thresholdedDark, clone) roimClosedPores = RoiManager(True) detectionParameters.setCalibration(thresholdedDark) countParticles(thresholdedDark, roimClosedPores, detectionParameters.closedPoresMinSize, detectionParameters.closedPoresMaxSize, \ detectionParameters.closedPoresMinCircularity, detectionParameters.closedPoresMaxCircularity) # count number of open pores roimOpenPores = RoiManager(True) detectionParameters.setCalibration(thresholdedDark) countParticles(thresholdedDark, roimOpenPores, detectionParameters.openPoresMinSize, detectionParameters.openPoresMaxSize, \ detectionParameters.openPoresMinCircularity, detectionParameters.openPoresMaxCircularity) # count number of sebum roimSebum = RoiManager(True) detectionParameters.setCalibration(thresholdedLight) countParticles(thresholdedLight, roimSebum, detectionParameters.sebumMinSize, detectionParameters.sebumMaxSize, \ detectionParameters.sebumMinCircularity, detectionParameters.sebumMaxCircularity) # create lists for open and closed pores closedPoresList=[] for roi in roimClosedPores.getRoisAsArray(): closedPoresList.append(roi.clone()) openPoresList=[] for roi in roimOpenPores.getRoisAsArray(): openPoresList.append(roi.clone()) # create lists for sebum sebumsList=[] for roi in roimSebum.getRoisAsArray(): sebumsList.append(roi.clone()) # a list of all pores allList=closedPoresList+openPoresList+sebumsList # calculate the stats for all pores detectionParameters.setCalibration(bluePlus) statsDict=CountParticles.calculateParticleStats(bluePlus, allList) poresTotalArea=0 for area in statsDict['Areas']: poresTotalArea=poresTotalArea+area print area poresAverageArea=poresTotalArea/len(statsDict['Areas']) # for each roi add the offset such that the roi is positioned in the correct location for the # original image [roi.setLocation(roi.getXBase()+x1, roi.getYBase()+y1) for roi in allList] # draw the rois on the image inputImp.getProcessor().setColor(Color.green) IJ.run(inputImp, "Line Width...", "line=3"); inputImp.getProcessor().draw(inputRoi) IJ.run(inputImp, "Line Width...", "line=1"); [CountParticles.drawParticleOnImage(inputImp, roi, Color.red) for roi in closedPoresList] [CountParticles.drawParticleOnImage(inputImp, roi, Color.magenta) for roi in openPoresList] [CountParticles.drawParticleOnImage(inputImp, roi, Color.green) for roi in sebumsList] inputImp.updateAndDraw() # close images that represent intermediate steps croppedPlus.changes=False croppedPlus.close() bluePlus.changes=False bluePlus.close() print "Total ROI Area: "+str(inputRoiArea) print "Num closed pores: "+str(len(closedPoresList)) print "Num open pores: "+str(len(openPoresList)) print "Num sebums: "+str(len(sebumsList)) print "Total particles: "+str(len(allList))+ " total area: "+str(poresTotalArea) statslist=[inputRoiArea, len(allList), len(closedPoresList), len(openPoresList), len(sebumsList), poresAverageArea, 100*poresTotalArea/inputRoiArea] header=[Messages.TotalAreaMask, Messages.TotalDetectedPores, Messages.ClosedPores, Messages.OpenPores, Messages.Sebum, Messages.PoresAverageArea, Messages.PoresFractionalArea] return header,statslist
def run(imp, preprocessor_path, postprocessor_path, threshold_method, user_comment): output_parameters = {"image title" : "", "preprocessor path" : float, "post processor path" : float, "thresholding op" : float, "use ridge detection" : bool, "high contrast" : int, "low contrast" : int, "line width" : int, "minimum line length" : int, "mitochondrial footprint" : float, "branch length mean" : float, "branch length median" : float, "branch length stdevp" : float, "summed branch lengths mean" : float, "summed branch lengths median" : float, "summed branch lengths stdevp" : float, "network branches mean" : float, "network branches median" : float, "network branches stdevp" : float} output_order = ["image title", "preprocessor path", "post processor path", "thresholding op", "use ridge detection", "high contrast", "low contrast", "line width", "minimum line length", "mitochondrial footprint", "branch length mean", "branch length median", "branch length stdevp", "summed branch lengths mean", "summed branch lengths median", "summed branch lengths stdevp", "network branches mean", "network branches median", "network branches stdevp"] # Perform any preprocessing steps... status.showStatus("Preprocessing image...") if preprocessor_path != None: if preprocessor_path.exists(): preprocessor_thread = scripts.run(preprocessor_path, True) preprocessor_thread.get() imp = WindowManager.getCurrentImage() else: pass # Store all of the analysis parameters in the table if preprocessor_path == None: preprocessor_str = "" else: preprocessor_str = preprocessor_path.getCanonicalPath() if postprocessor_path == None: postprocessor_str = "" else: postprocessor_str = preprocessor_path.getCanonicalPath() output_parameters["preprocessor path"] = preprocessor_str output_parameters["post processor path"] = postprocessor_str output_parameters["thresholding op"] = threshold_method output_parameters["use ridge detection"] = str(use_ridge_detection) output_parameters["high contrast"] = rd_max output_parameters["low contrast"] = rd_min output_parameters["line width"] = rd_width output_parameters["minimum line length"] = rd_length # Create and ImgPlus copy of the ImagePlus for thresholding with ops... status.showStatus("Determining threshold level...") imp_title = imp.getTitle() slices = imp.getNSlices() frames = imp.getNFrames() output_parameters["image title"] = imp_title imp_calibration = imp.getCalibration() imp_channel = Duplicator().run(imp, imp.getChannel(), imp.getChannel(), 1, slices, 1, frames) img = ImageJFunctions.wrap(imp_channel) # Determine the threshold value if not manual... binary_img = ops.run("threshold.%s"%threshold_method, img) binary = ImageJFunctions.wrap(binary_img, 'binary') binary.setCalibration(imp_calibration) binary.setDimensions(1, slices, 1) # Get the total_area if binary.getNSlices() == 1: area = binary.getStatistics(Measurements.AREA).area area_fraction = binary.getStatistics(Measurements.AREA_FRACTION).areaFraction output_parameters["mitochondrial footprint"] = area * area_fraction / 100.0 else: mito_footprint = 0.0 for slice in range(binary.getNSlices()): binary.setSliceWithoutUpdate(slice) area = binary.getStatistics(Measurements.AREA).area area_fraction = binary.getStatistics(Measurements.AREA_FRACTION).areaFraction mito_footprint += area * area_fraction / 100.0 output_parameters["mitochondrial footprint"] = mito_footprint * imp_calibration.pixelDepth # Generate skeleton from masked binary ... # Generate ridges first if using Ridge Detection if use_ridge_detection and (imp.getNSlices() == 1): skeleton = ridge_detect(imp, rd_max, rd_min, rd_width, rd_length) else: skeleton = Duplicator().run(binary) IJ.run(skeleton, "Skeletonize (2D/3D)", "") # Analyze the skeleton... status.showStatus("Setting up skeleton analysis...") skel = AnalyzeSkeleton_() skel.setup("", skeleton) status.showStatus("Analyzing skeleton...") skel_result = skel.run() status.showStatus("Computing graph based parameters...") branch_lengths = [] summed_lengths = [] graphs = skel_result.getGraph() for graph in graphs: summed_length = 0.0 edges = graph.getEdges() for edge in edges: length = edge.getLength() branch_lengths.append(length) summed_length += length summed_lengths.append(summed_length) output_parameters["branch length mean"] = eztables.statistical.average(branch_lengths) output_parameters["branch length median"] = eztables.statistical.median(branch_lengths) output_parameters["branch length stdevp"] = eztables.statistical.stdevp(branch_lengths) output_parameters["summed branch lengths mean"] = eztables.statistical.average(summed_lengths) output_parameters["summed branch lengths median"] = eztables.statistical.median(summed_lengths) output_parameters["summed branch lengths stdevp"] = eztables.statistical.stdevp(summed_lengths) branches = list(skel_result.getBranches()) output_parameters["network branches mean"] = eztables.statistical.average(branches) output_parameters["network branches median"] = eztables.statistical.median(branches) output_parameters["network branches stdevp"] = eztables.statistical.stdevp(branches) # Create/append results to a ResultsTable... status.showStatus("Display results...") if "Mito Morphology" in list(WindowManager.getNonImageTitles()): rt = WindowManager.getWindow("Mito Morphology").getTextPanel().getOrCreateResultsTable() else: rt = ResultsTable() rt.incrementCounter() for key in output_order: rt.addValue(key, str(output_parameters[key])) # Add user comments intelligently if user_comment != None and user_comment != "": if "=" in user_comment: comments = user_comment.split(",") for comment in comments: rt.addValue(comment.split("=")[0], comment.split("=")[1]) else: rt.addValue("Comment", user_comment) rt.show("Mito Morphology") # Create overlays on the original ImagePlus and display them if 2D... if imp.getNSlices() == 1: status.showStatus("Generate overlays...") IJ.run(skeleton, "Green", "") IJ.run(binary, "Magenta", "") skeleton_ROI = ImageRoi(0,0,skeleton.getProcessor()) skeleton_ROI.setZeroTransparent(True) skeleton_ROI.setOpacity(1.0) binary_ROI = ImageRoi(0,0,binary.getProcessor()) binary_ROI.setZeroTransparent(True) binary_ROI.setOpacity(0.25) overlay = Overlay() overlay.add(binary_ROI) overlay.add(skeleton_ROI) imp.setOverlay(overlay) imp.updateAndDraw() # Generate a 3D model if a stack if imp.getNSlices() > 1: univ = Image3DUniverse() univ.show() pixelWidth = imp_calibration.pixelWidth pixelHeight = imp_calibration.pixelHeight pixelDepth = imp_calibration.pixelDepth # Add end points in yellow end_points = skel_result.getListOfEndPoints() end_point_list = [] for p in end_points: end_point_list.append(Point3f(p.x * pixelWidth, p.y * pixelHeight, p.z * pixelDepth)) univ.addIcospheres(end_point_list, Color3f(255.0, 255.0, 0.0), 2, 1*pixelDepth, "endpoints") # Add junctions in magenta junctions = skel_result.getListOfJunctionVoxels() junction_list = [] for p in junctions: junction_list.append(Point3f(p.x * pixelWidth, p.y * pixelHeight, p.z * pixelDepth)) univ.addIcospheres(junction_list, Color3f(255.0, 0.0, 255.0), 2, 1*pixelDepth, "junctions") # Add the lines in green graphs = skel_result.getGraph() for graph in range(len(graphs)): edges = graphs[graph].getEdges() for edge in range(len(edges)): branch_points = [] for p in edges[edge].getSlabs(): branch_points.append(Point3f(p.x * pixelWidth, p.y * pixelHeight, p.z * pixelDepth)) univ.addLineMesh(branch_points, Color3f(0.0, 255.0, 0.0), "branch-%s-%s"%(graph, edge), True) # Add the surface univ.addMesh(binary) univ.getContent("binary").setTransparency(0.5) # Perform any postprocessing steps... status.showStatus("Running postprocessing...") if postprocessor_path != None: if postprocessor_path.exists(): postprocessor_thread = scripts.run(postprocessor_path, True) postprocessor_thread.get() else: pass status.showStatus("Done analysis!")