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 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
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
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)
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
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 split_and_rotate(imp, info): """return image to segment on, image to project out, and images to display""" # for now, assume that these are ISVs and that embryo is mounted in familiar fashion. First of these can be developed out... print("Image dimensions at start of split and rotate = ({}x{}x{}) pix". format(imp.getWidth(), imp.getHeight(), imp.getNSlices())) if imp.isVisible(): IJ.run("Enhance Contrast", "saturated=0.35") seg_ch_idx, proj_ch_idx = ui.choose_segmentation_and_projection_channels( info) channels = ChannelSplitter().split(imp) seg_imp = Duplicator().run(channels[seg_ch_idx]) # use Duplicator to decouple - can do smarter to save memory? proj_imp = Duplicator().run(channels[proj_ch_idx]) rot_seg_imp = utils.rot3d(seg_imp, axis='x') rot_seg_imp.setTitle("rot_seg_imp") rot_proj_imp = utils.rot3d(proj_imp, axis='x') rot_proj_imp.setTitle("rot_proj_imp") egfp_mch_imps = [] egfp_idx = 0 if "gfp" in info.ch1_label.lower() else 1 mch_idx = int(not (egfp_idx)) # assume two channel... for ch_idx in [egfp_idx, mch_idx]: if ch_idx == seg_ch_idx: egfp_mch_imps.append(Duplicator().run(rot_seg_imp)) elif ch_idx == proj_ch_idx: egfp_mch_imps.append(Duplicator().run(rot_proj_imp)) else: egfp_mch_imps.append( utils.rot3d(Duplicator().run(channels[ch_idx]), axis='x')) imp.changes = False imp.close() seg_imp.changes = False proj_imp.changes = False seg_imp.close() proj_imp.close() print("Image dimensions at start of split and rotate = ({}x{}x{}) pix". format(rot_proj_imp.getWidth(), rot_proj_imp.getHeight(), rot_proj_imp.getNSlices())) return rot_seg_imp, rot_proj_imp, egfp_mch_imps
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 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 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 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 qc_background_regions(intensity_imp, bg_rois): """allow the user to view and correct automatically-determined background regions""" imp = Duplicator().run(intensity_imp); imp.setTitle("Background region QC"); imp.show(); imp.setPosition(1); autoset_zoom(imp); imp.setRoi(bg_rois[0]); IJ.setTool("freehand"); notOK = True; while notOK: listener = UpdateRoiImageListener(bg_rois, is_area=True); imp.addImageListener(listener); dialog = NonBlockingGenericDialog("Background region quality control"); dialog.enableYesNoCancel("Continue", "Use this region for all t"); dialog.setCancelLabel("Cancel analysis"); dialog.addMessage("Please redraw background regions as necessary...") dialog.showDialog(); if dialog.wasCanceled(): raise KeyboardInterrupt("Run canceled"); elif not(dialog.wasOKed()): this_roi = imp.getRoi(); bg_rois = [this_roi for _ in listener.getRoiList()]; imp.removeImageListener(listener); else: last_roi = imp.getRoi(); qcd_bg_rois = listener.getRoiList(); if imp.getNFrames() > imp.getNSlices(): qcd_bg_rois[imp.getT() - 1] = last_roi; else: qcd_bg_rois[imp.getZ() - 1] = last_roi; notOK = False; imp.removeImageListener(listener); imp.changes = False; imp.close(); return qcd_bg_rois;
def 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 time_crop(imp, params): """trim a time series based on interactively-defined start and end points""" start_frame = None; end_frame = None; if params.perform_time_crop: if params.time_crop_start_end is not None: start_frame = params.time_crop_start_end[0]; end_frame = params.time_crop_start_end[1]; else: MyWaitForUser("First T...", "Choose first time frame and click OK..."); start_frame = imp.getT(); MyWaitForUser("Last T...", "Now choose last time frame and click OK..."); end_frame = imp.getT(); slices = imp.getNSlices(); channels = imp.getNChannels(); if start_frame is not None: dupimp = Duplicator().run(imp, 1, channels, 1, slices, start_frame, end_frame); imp.changes = False; imp.close(); dupimp.show() autoset_zoom(dupimp); return dupimp, (start_frame, end_frame); else: return imp, (start_frame, end_frame);
maxZ = max([i.getNSlices() for i in imL]) if chl is None: maxC = max([i.getNChannels() for i in imL]) else: maxC = len(chl) ssL = [] # Same number of slices nff=True for im in imL: if chl is not None: ## Here we extract only the channels we need im = SubHyperstackMaker().makeSubhyperstack(im, [i+1 for i in chl], range(1, im.getNSlices()+1), range(1, im.getNFrames()+1)) nz = maxZ-im.getNSlices() # Number of z planes to add if nz==0 and im.getNChannels()==maxC: ssL.append(im) continue if im.getNFrames()==1: tmp = Duplicator().run(im, 1, im.getNChannels(), 1, 1, 1, 1) # create a duplicated slice tmp.getProcessor().multiply(0) # make it a dark frame ssL.append(Concatenator().concatenate([im]+[tmp]*nz, False)) # This deletes references/images in imL else: # if im.getNFrames()>1 (we need to concatenate time-point-per timepoint :s ) nff=False allFrames = [] stack = im.getImageStack() nZ = im.getNSlices() nC = im.getNChannels() dark = Duplicator().run(im, 1, 1, 1, 1, 1, 1) dark.getProcessor().multiply(0) res = ij.ImageStack(im.width, im.height) icnt = 0 for ia in range(1, im.getNFrames()+1): for ib in range(1, maxZ+1): for ic in range(1,maxC+1):
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)
final_folder = "marcksl1 shape prescreener" script_path = os.path.join(ss[0], "Fiji.app", "plugins", "Scripts", "Plugins", final_folder) sys.path.insert(0, os.path.join(script_path, 'modules')) sys.path.insert(0, os.path.join(script_path, 'classes')) from UpdateRoiImageListener import UpdateRoiImageListener # angle method max_r_pix = 60 min_r_pix = 10 split_chs = ChannelSplitter().split(imp) mch_imp = split_chs[0] egfp_imp = split_chs[1] egfp_imp_disp = Duplicator().run(egfp_imp) cl_imp = split_chs[2] #egfp_imp.show(); centres = [] projected_im_pix = [] ring_rois = [] unzip_axis = [] roi_stack = IJ.createImage("rois", egfp_imp.getWidth(), egfp_imp.getHeight(), egfp_imp.getNSlices(), 16) #roi_stack.show(); for zidx in range(cl_imp.getNSlices()): #for zidx in range(200,350): #for zidx in range(200,202): if ((zidx + 1) % 100) == 0:
def croptracks(self, outdir, trackid="TRACK_ID", 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_ID", "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. trackid: A unique track identifier. Defaults to "TRACK_ID" 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. """ imp = self.imp tracks = self.tracks cal = imp.getCalibration() stacks = [] # 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[trackid]) i_x = int(i[trackx] / cal.pixelWidth) # TODO fix for calibration. i_y = int(i[tracky] / cal.pixelHeight) # TODO fix for calibration. i_start = int(i[trackstart] / cal.frameInterval) i_stop = int(i[trackstop] / cal.frameInterval) # 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_ID: {}/{}".format(i_id+1, int(len(tracks)))) # Duplicator().run(firstC, lastC, firstZ, lastZ, firstT, lastT) impout = Duplicator().run(imp, 1, nChannels, 1, nSlices, i_start, i_stop) stacks.append(impout) # Save the substack in the output directory # outfile = os.path.join(outdir, "TRACK_ID_{}.tif".format(i_id)) # IJ.saveAs(imp2, "Tiff", outfile) self.croppedtracks = stacks IJ.log("\nExecution croptracks() finished.")
def runOneFile(fullFilePath): 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) # open image imp = Opener().openImage(fullFilePath) # 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)
# choose random x and y from anywhere in the image xcenter = random.randint(0, width) # in pixel units because integers ycenter = random.randint(0, height) # discard positions that would generate overlapping cells if not cellOverlap(xcenter, ycenter, celldiam, centers): centers.append([xcenter, ycenter]) # print("Spot "+str(count)+" center: "+str(centers[count])) count += 1 # work on a copy of the image from ij.plugin import Duplicator imp2 = Duplicator().run(imp, 1, channels, 1, 1, 1, 1) # clear the existing channel imp2.setDisplayMode(IJ.COLOR) imp2.setC(targetChannel) IJ.run(imp2, "Select All", "") IJ.setBackgroundColor(0, 0, 0) IJ.run(imp2, "Clear", "slice") # draw white circles to simulate cells IJ.setForegroundColor(255, 255, 255) for point in centers: drawSpot(point, celldiam) # save the simulated image IJ.saveAs(imp2, "Tiff",
IJ.log("image type: %s" % types[imp.type]) ## ==== Preprocess the image imp.getCalibration().pixelWidth = pixXY imp.getCalibration().pixelHeight = pixXY imp.getCalibration().pixelDepth = stepZ #imp.getCalibration().getUnit() # should return 'micron' #imp.getCalibration() # DBG if crop_image: imp.setRoi(int(xLoc-math.floor(winCrop/2)),int(yLoc-math.floor(winCrop/2)),winCrop,winCrop) # Create a ROI and crop it. else: imp.setRoi(0,0,imp.width,imp.height) # Create a ROI and crop it. crop = imp.crop("stack") ij.process.ImageConverter(crop).convertToGray32() tmp1 = Duplicator().run(crop, chDNA, chDNA, 1, crop.getNSlices(), 1, crop.getNFrames()) #Stack.setChannel(chDNA); run("Duplicate...", "channels=2 title=cropDNA duplicate"); tmp2 = Duplicator().run(crop, chDNA, chDNA, 1, crop.getNSlices(), 1, crop.getNFrames()) #run("Duplicate...", "title=tmp2 duplicate"); # === Band pass filtering IJ.run(tmp1, "Gaussian Blur...", "sigma=%f stack" % sd1) #selectWindow("tmp1"); run("Gaussian Blur...", "sigma="+sd1+" stack"); IJ.run(tmp2, "Gaussian Blur...", "sigma=%f stack" % sd2) #selectWindow("tmp2"); run("Gaussian Blur...", "sigma="+sd2+" stack"); cropDNA_bPass = ImageCalculator().run("Subtract create 32-bit stack", tmp1, tmp2) #imageCalculator("Subtract create 32-bit stack", "tmp1","tmp2"); rename("cropDNA_bPass"); tmp1.close() tmp2.close() # === Create stack to be processed # From https://stackoverflow.com/questions/48213759/combine-channels-in-imagej-jython crop_channels = ij.plugin.ChannelSplitter.split(crop) # selectWindow("crop"); run("Split Channels"); if len(crop_channels)>=2: res_st = ij.plugin.RGBStackMerge().mergeHyperstacks([cropDNA_bPass, ]+[c for c in crop_channels], True) #run("Merge Channels...", "c1=cropDNA_bPass c2=C1-crop c3=C2-crop create") else :
manager = RoiManager.getRoiManager() manager.reset() IJ.run("Close All", "") # access to the folder and the files in it directory = File(folder) listOfFilesInFolder = directory.listFiles() for file in listOfFilesInFolder: if (file.toString().endswith(".tif")): # load image and show it imp = IJ.openImage(file.toString()) imp.show() copy = Duplicator().run(imp) # apply a threshold to detect objects (cells, nuclei,...) IJ.setAutoThreshold(imp, "Otsu") Prefs.blackBackground = False IJ.run(imp, "Convert to Mask", "") # analyse objects and put results in table IJ.run("Set Measurements...", "area display redirect=None decimal=5") IJ.run(imp, "Analyze Particles...", "exclude add") manager = RoiManager.getRoiManager() manager.runCommand("Save", file.toString() + ".RoiSet.zip") for roi in manager.getRoisAsArray():
Nuclei.changes = False Nuclei.close() imp2.changes = False imp2.close() if automatic_save_results: dataname = imp1.getTitle() filename = dataname + ".csv" #files = glob.glob(savepath+"/"+dataname+"*.csv") savename = savepath + "/" + filename ort.saveAs(savename) else: print "not saving" if filenum == 0: dup = Duplicator() stack1 = dup.run(imp1) print "first round" else: try: dup = Duplicator() stack2 = dup.run(imp1) stack1 = concat.run(stack1, stack2) stack1.setTitle(directory) print "making stack" except NameError: dup = Duplicator() stack1 = dup.run(imp1) print "first image was empty" imp1.changes = False
def main(): #print (sys.version_info) # debug #print(sys.path) # debug data_root = r'C:\Users\dougk\Desktop\test' # debug output_root = r'C:\Users\dougk\Desktop\test' #debug #default_directory = r'C:\\Users\\Doug\\Desktop\\test'; #data_root, output_root = file_location_chooser(default_directory); if (data_root is None) or (output_root is None): raise IOError("File location dialogs cancelled!") timestamp = datetime.strftime(datetime.now(), "%Y-%m-%d %H.%M.%S") output_path = os.path.join(output_root, (timestamp + " output")) for file_path in filterByFileType(os.listdir(data_root), '.tif'): subfolder_name = os.path.splitext(file_path)[0] output_subfolder = os.path.join(output_path, subfolder_name) print(output_subfolder) os.makedirs(output_subfolder) imps = bf.openImagePlus(os.path.join(data_root, file_path)) imp = imps[0] imp.show() h = imp.height w = imp.width slices = imp.getNSlices() channels = imp.getNChannels() frames = imp.getNFrames() # rotation step - since using multiples of 90, TransformJ.Turn is more efficient IJ.run("Enhance Contrast", "saturated=0.35") angleZ = 1 while ((angleZ % 90) > 0): gd = GenericDialog("Rotate?") gd.addMessage( "Define rotation angle - increments of 90. Apical at top") gd.addNumericField("Rotation angle", 0, 0) gd.showDialog() angleZ = int(gd.getNextNumber()) if (angleZ > 1): IJ.run("TransformJ Turn", "z-angle=" + str(angleZ) + " y-angle=0 x-angle=0") imp.close() imp = WindowManager.getCurrentImage() imp.setTitle(file_path) # trim time series IJ.run("Enhance Contrast", "saturated=0.35") imp.setDisplayMode(IJ.COLOR) WaitForUserDialog( "Scroll to the first frame of the period of interest and click OK" ).show() start_frame = imp.getT() WaitForUserDialog( "Scroll to the last frame of the period of interest and click OK" ).show() end_frame = imp.getT() trim_imp = Duplicator().run(imp, 1, channels, 1, slices, start_frame, end_frame) imp.close() trim_imp.show() dup_imp = Duplicator().run(trim_imp) # create images to process and find bounds for dup_imps = ChannelSplitter().split(dup_imp) myo_imp = dup_imps[1] mem_imp = dup_imps[0] FileSaver(myo_imp).saveAsTiffStack( os.path.join(output_subfolder, "myosin_channel.tif")) FileSaver(mem_imp).saveAsTiffStack( os.path.join(output_subfolder, "membrane_channel.tif")) # set basal bounds myo_imp.show() ImageConverter(myo_imp).convertToGray8() frames = myo_imp.getNFrames() gb = GaussianBlur() for fridx in range(0, frames): myo_imp.setSliceWithoutUpdate(fridx + 1) ip = myo_imp.getProcessor() gb.blurGaussian(ip, 5.0, 1.0, 0.02) # assymmetrical Gaussian IJ.run(myo_imp, "Convert to Mask", "method=Otsu background=Dark calculate") IJ.run("Despeckle", "stack") title = myo_imp.getTitle() # assume that first frame is good quality image... basal_edges = find_basal_edges(myo_imp) #myo_imp.hide() mem_imp.hide() # draw some edges for checking roim = RoiManager() xs = [x for x in range(1, trim_imp.getWidth() + 1)] trim_imp.show() for fridx in range(0, myo_imp.getNFrames()): trim_imp.setPosition(2, 1, fridx + 1) IJ.run("Enhance Contrast", "saturated=0.35") roi = PolygonRoi(xs, basal_edges[fridx], Roi.POLYLINE) trim_imp.setRoi(roi) roim.addRoi(roi)
def glidingprojection(imp, startframe=1, stopframe=None, glidingFlag=True, no_frames_per_integral=3, projectionmethod="Median"): """This function subtracts the gliding projection of several frames from the input stack. Thus, everything which moves too fast is filtered away. Args: imp (ImagePlus): Input image as ImagePlus object. startframe (int, optional): Choose a start frame. Defaults to 1. stopframe (int, optional): Choose an end frame. Defaults to None. glidingFlag (bool, optional): Should a gliding frame by frame projection be used? Defaults to True. no_frames_per_integral (int, optional): Number of frames to project each integral. Defaults to 3. projectionmethod (str, optional): Choose the projection method. Options are 'Average Intensity', 'Max Intensity', 'Min Intensity', 'Sum Slices', 'Standard Deviation', 'Median'. Defaults to "Median". Raises: RuntimeException: Start frame > stop frame. Returns: ImagePlus: The output stack. """ # Store some image properties. cal = imp.getCalibration() width, height, nChannels, nSlices, nFrames = imp.getDimensions() title = imp.getTitle() # Some simple sanity checks for input parameters. if stopframe == None: stopframe = nFrames if (startframe > stopframe): IJ.showMessage("Start frame > Stop frame, can't go backwards in time!") raise RuntimeException("Start frame > Stop frame!") # If a subset of the image is to be projected, these lines of code handle that. if ((startframe != 1) or (stopframe != nFrames)): imp = Duplicator().run(imp, 1, nChannels, 1, nSlices, startframe, stopframe) # Define the number of frames to advance per step based on boolean input parameter glidingFlag. if glidingFlag: frames_to_advance_per_step = 1 else: frames_to_advance_per_step = no_frames_per_integral # Make a dict containg method_name:const_fieled_value pairs for the projection methods methods_as_strings = [ 'Average Intensity', 'Max Intensity', 'Min Intensity', 'Sum Slices', 'Standard Deviation', 'Median' ] methods_as_const = [ ZProjector.AVG_METHOD, ZProjector.MAX_METHOD, ZProjector.MIN_METHOD, ZProjector.SUM_METHOD, ZProjector.SD_METHOD, ZProjector.MEDIAN_METHOD ] method_dict = dict(zip(methods_as_strings, methods_as_const)) # Initialize a ZProjector object and an empty stack to collect projections. zp = ZProjector(imp) zp.setMethod(method_dict[projectionmethod]) outstack = imp.createEmptyStack() # Loop through all the frames in the image, and project that frame with the other frames in the integral. for frame in range(1, nFrames + 1, frames_to_advance_per_step): zp.setStartSlice(frame) zp.setStopSlice(frame + no_frames_per_integral) zp.doProjection() outstack.addSlice(zp.getProjection().getProcessor()) # Create an image processor from the newly created Z-projection stack # nFrames = outstack.getSize()/nChannels impout = ImagePlus( title + '_' + projectionmethod + '_' + str(no_frames_per_integral) + '_frames', outstack) impout = HyperStackConverter.toHyperStack(impout, nChannels, nSlices, nFrames) impout.setCalibration(cal) return impout
def overlay_curvatures(imp, curvature_profiles, params, limits=None, annotate=True): """Overlay curvature pixels on membrane image""" membrane_channel = params.membrane_channel_number overlay_base_imp = imp.clone() curvature_stack = ImageStack(imp.getWidth(), imp.getHeight()) for profile in curvature_profiles: curvature_stack = generate_curvature_overlays(profile, curvature_stack) overlay_imp = ImagePlus("Curvature stack", curvature_stack) IJ.run(overlay_imp, params.curvature_overlay_lut_string, "") if limits is None: flat_list_curv = [c[1] for cs in curvature_profiles for c in cs] limits = [min(flat_list_curv), max(flat_list_curv)] IJ.setMinAndMax(overlay_imp, limits[0], limits[1]) raw_overlay = Duplicator().run(overlay_imp) if annotate: cb_fraction = 0.05 overlay_imp = add_colorbar(overlay_imp, limits, cb_fraction) IJ.run(overlay_imp, "RGB Color", "") w = overlay_imp.getWidth() h = overlay_imp.getHeight() overlaid_stack = ImageStack(w, h) for fridx in range(1, curvature_stack.getSize() + 1): raw_idx = overlay_base_imp.getStackIndex(membrane_channel, 1, fridx) ip = overlay_base_imp.getStack().getProcessor(raw_idx).convertToRGB() pix = overlay_imp.getStack().getProcessor(fridx).getPixels() base_pix = ip.getPixels() curv = [c for ((x, y), c) in curvature_profiles[fridx - 1]] start_idx = next((i for i, x in enumerate(curv) if x), None) end_idx = next( (len(curv) - i for i, x in enumerate(reversed(curv)) if x), None) for ((x, y), c) in curvature_profiles[fridx - 1][start_idx:end_idx]: # ensure that no rounding issues cause pixels to fall outside image... if x > (w - 1): x = w - 1 if y > (h - 1): y = h - 1 if x < 0: x = 0 if y < 0: y = 0 if params.filter_negative_curvatures: if (c > 0): base_pix[int(round(y)) * w + int(round(x))] = pix[int(round(y)) * w + int(round(x))] else: base_pix[int(round(y)) * w + int(round(x))] = pix[int(round(y)) * w + int(round(x))] if annotate: for x in range(w - int(w * cb_fraction), w): for y in range(0, h): base_pix[int(round(y)) * w + int(round(x))] = pix[int(round(y)) * w + int(round(x))] overlaid_stack.addSlice(ip) out_imp = ImagePlus("Overlaid curvatures", overlaid_stack) if annotate: out_imp = generate_limit_labels(out_imp, limits, cb_fraction, params) FileSaver(raw_overlay).saveAsTiff( os.path.join(params.output_path, "raw curvature.tif")) return out_imp, raw_overlay
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) # present user with the familiar setup UI, with options that don't make sense/aren't yet implemented disabled params = mbui.analysis_parameters_gui(rerun_analysis=True, params=params) # 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") 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") # 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) # import edges membrane_edges = mbio.load_qcd_edges2( os.path.join(output_folder_old, "user_defined_edges.zip")) mbio.save_qcd_edges2(membrane_edges, params.output_path) calculated_objects = CalculatedObjects() calculated_objects.membrane_edges = membrane_edges if params.time_crop_start_end[0] is not None: calculated_objects.timelist = [ idx * params.frame_interval for idx in range(params.time_crop_start_end[0], params.time_crop_start_end[1] + 1) ] else: calculated_objects.timelist = [ idx * params.frame_interval for idx in range(imp.getNFrames()) ] split_channels = mbfs.split_image_plus(imp, params) membrane_channel_imp = split_channels[0] actin_channel_imp = split_channels[1] segmentation_channel_imp = None if params.photobleaching_correction: if os.path.isfile( os.path.join(output_folder_old, 'binary_membrane_stack.tif')): segmentation_binary_path = os.path.join( output_folder_old, 'binary_membrane_stack.tif') segmentation_channel_imp = IJ.openImage(segmentation_binary_path) else: segmentation_channel_imp = split_channels[2] segmentation_channel_imp = mb.make_and_clean_binary( segmentation_channel_imp, params.threshold_method) split_channels[2] = segmentation_channel_imp calculated_objects = mbfs.calculate_outputs(params, calculated_objects, split_channels) # output colormapped images and kymographs fig_imp_list = mbfs.generate_and_save_figures(imp, calculated_objects, params, membrane_channel_imp, segmentation_channel_imp) mbfs.save_csvs(calculated_objects, params) params.saveParametersToJson( os.path.join(params.output_path, "parameters used.json")) imp.changes = False IJ.setTool("zoom") if params.close_on_completion: for fig_imp in fig_imp_list: fig_imp.close() imp.close() return
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!")