def analyze(imp, min_area): MAXSIZE = 1000000000000 MINCIRCULARITY = 0.0 MAXCIRCULARITY = 1. options = PA.SHOW_MASKS temp_results = ResultsTable() p = PA(options, PA.AREA + PA.MEAN, temp_results, min_area, MAXSIZE, MINCIRCULARITY, MAXCIRCULARITY) p.setHideOutputImage(True) p.analyze(imp) if temp_results.getCounter() == 0: areas = [] signals = [] else: areas = list(temp_results.getColumn(0)) signals = list(temp_results.getColumn(1)) count = len(areas) area = sum(areas) total = 0 if area > 0: total = sum([a*s for a,s in zip(areas, signals)]) / area return p.getOutputImage(), count, area, total
def particleAnalysis(slicenum, sliceimp, resrt): options = PA.SHOW_NONE rt = ResultsTable() p = PA(options, PA.AREA + PA.CENTROID, rt, MINSIZE, MAXSIZE) p.analyze(sliceimp) centrosomecounts = rt.getCounter() print "-- Region", str(slicenum), "--" curCount = resrt.getCounter() resrt.setValue("cellID", curCount, slicenum) resrt.setValue("counts", curCount, centrosomecounts) if centrosomecounts == 0: print " .. no centrosome" elif centrosomecounts == 1: print " .. Only one centrosome" # if rt.getValue("Area", 0) == 1.0: # print " .. Only one centrosome" # else: # print " .. one centrosome but Area 1 < : maybe combined" elif centrosomecounts == 2: print " .. two centrosomes" resrt.setValue("c1x", curCount, rt.getValue("X", 0)) resrt.setValue("c1y", curCount, rt.getValue("Y", 0)) resrt.setValue("c2x", curCount, rt.getValue("X", 1)) resrt.setValue("c2y", curCount, rt.getValue("Y", 1)) else: print " .. ", str(centrosomecounts),"centrosomes detected"
def keep_largest_blob(imp): """remove all blobs other than the largest by area""" rt = ResultsTable() mxsz = imp.width * imp.height roim = RoiManager(False) pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, ParticleAnalyzer.AREA | ParticleAnalyzer.SLICE, rt, 0, mxsz) pa.setRoiManager(roim) for idx in range(1, imp.getImageStackSize() + 1): roim.reset() rt.reset() imp.setPosition(idx) pa.analyze(imp) rt_areas = rt.getColumn(rt.getColumnIndex("Area")).tolist() mx_ind = rt_areas.index(max(rt_areas)) indices_to_remove = [ a for a in range(0, len(rt_areas)) if a != mx_ind ] indices_to_remove.reverse() for rem_idx in indices_to_remove: roim.select(imp, rem_idx) IJ.run(imp, "Set...", "value=0 slice") imp.killRoi() roim.reset() roim.close()
def threshold(imPlus, edgeThreshold=2500): mask = Duplicator().run(imPlus) mask_stk = mask.getStack() # First, we threshold based on edges IJ.setThreshold(mask, edgeThreshold, 100000, "No Update") for i in range(mask.getImageStackSize()): mask_stk.getProcessor(i + 1).findEdges() IJ.run(mask, "Make Binary", "method=Default background=Default black") # Now, we need to clean up the binary images morphologically IJ.run(mask, "Dilate", "stack") IJ.run(mask, "Fill Holes", "stack") IJ.run(mask, "Erode", "stack") IJ.run(mask, "Erode", "stack") # Finally, remove the small particles stk = ImageStack(mask.getWidth(), mask.getHeight()) p = PA(PA.SHOW_MASKS, 0, None, 200, 100000) p.setHideOutputImage(True) for i in range(mask_stk.getSize()): mask.setSliceWithoutUpdate(i + 1) p.analyze(mask) mmap = p.getOutputImage() stk.addSlice(mmap.getProcessor()) mask.setStack(stk) mask.setSliceWithoutUpdate(1) mask.setTitle(mask_title(imPlus.getTitle())) mask.show() return mask
def keep_blobs_bigger_than(imp, min_size_pix=100): """remove all blobs other than the largest by area""" imp.killRoi() rt = ResultsTable() if "Size_filtered_" in imp.getTitle(): title_addition = "" else: title_addition = "Size_filtered_" out_imp = IJ.createImage("{}{}".format(title_addition, imp.getTitle()), imp.getWidth(), imp.getHeight(), 1, 8) out_imp.show() IJ.run(out_imp, "Select All", "") IJ.run(out_imp, "Set...", "value=0 slice") mxsz = imp.width * imp.height roim = RoiManager() pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, ParticleAnalyzer.AREA | ParticleAnalyzer.SLICE, rt, min_size_pix, mxsz) pa.setRoiManager(roim) roim.reset() rt.reset() pa.analyze(imp) rt_areas = rt.getColumn(rt.getColumnIndex("Area")).tolist() # print("Number of cells identified: {}".format(len(rt_areas))); for idx in range(len(rt_areas)): roim.select(out_imp, idx) IJ.run(out_imp, "Set...", "value=255 slice") mx_ind = rt_areas.index(max(rt_areas)) roim.reset() roim.close() imp.changes = False imp.close() return out_imp
def anaParticles(imp, minSize, maxSize, minCirc, bHeadless=True): """anaParticles(imp, minSize, maxSize, minCirc, bHeadless=True) Analyze particles using a watershed separation. If headless=True, we cannot redirect the intensity measurement to the original immage becuae it is never displayed. If we display the original, we can and get the mean gray level. We may then compute the particle contrast from the measured Izero value for the image. No ability here to draw outlines on the original.""" strName = imp.getShortTitle() imp.setTitle("original") ret = imp.duplicate() IJ.run(ret, "Enhance Contrast", "saturated=0.35") IJ.run(ret, "8-bit", "") IJ.run(ret, "Threshold", "method=Default white") IJ.run(ret, "Watershed", "") rt = ResultsTable() # strSetMeas = "area mean modal min center perimeter bounding fit shape feret's redirect='original' decimal=3" # N.B. redirect will not work without a displayed image, so we cannot use a gray level image if bHeadless == True: strSetMeas = "area mean modal min center perimeter bounding fit shape feret's decimal=3" else: imp.show() strSetMeas = "area mean modal min center perimeter bounding fit shape feret's redirect='original' decimal=3" IJ.run("Set Measurements...", strSetMeas) # note this doies not get passed directly to ParticleAnalyzer, so # I did this, saved everything and looked for the measurement value in ~/Library/Preferences/IJ_Prefs.txt # measurements=27355 # meas = Measurements.AREA + Measurements.CIRCULARITY + Measurements.PERIMETER + Measurements.SHAPE_DESCRIPTORS # didn't work reliably meas = 27355 pa = ParticleAnalyzer(0, meas, rt, minSize, maxSize, minCirc, 1.0); pa.analyze(ret); rt.createTableFromImage(ret.getProcessor()) return [ret, rt]
def resetpressed(event): self.__ranges.clear() self.__image=IJ.getImage() rm = RoiManager.getInstance() if (rm==None): rm = RoiManager() rm.runCommand("reset") self.__image.killRoi() IJ.setAutoThreshold(self.__image, "MaxEntropy") rt=ResultsTable() pa=ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER+ParticleAnalyzer.CLEAR_WORKSHEET , Measurements.AREA+Measurements.ELLIPSE+Measurements.MEAN, rt, 0.00, 10000.00, 0.00, 1.00) pa.analyze(self.__image) self.__roisArray=[] self.__roisArray=rm.getRoisAsArray() #rm.runCommand("Show All") #rm.runCommand("Select All") #rm.runCommand("Set Color", "blue") IJ.resetThreshold(self.__image) keys=self.__slidersDict.keys() for k in keys: if k.endswith("min"): self.__slidersDict[k].setValue(0) self.__slidersDict[k].repaint() else: self.__slidersDict[k].setValue(self.__slidersDict[k].getMaximum()) self.__slidersDict[k].repaint()
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 analyzeParticles(imp, minsize, maxsize, mincirc, maxcirc, filename='Test.czi', addROIManager=True, headless=True, exclude=True): if addROIManager is True: if exclude is False: options = PA.SHOW_ROI_MASKS \ + PA.SHOW_RESULTS \ + PA.DISPLAY_SUMMARY \ + PA.ADD_TO_MANAGER \ + PA.ADD_TO_OVERLAY \ if exclude is True: options = PA.SHOW_ROI_MASKS \ + PA.SHOW_RESULTS \ + PA.DISPLAY_SUMMARY \ + PA.ADD_TO_MANAGER \ + PA.ADD_TO_OVERLAY \ + PA.EXCLUDE_EDGE_PARTICLES if addROIManager is False: if exclude is False: options = PA.SHOW_ROI_MASKS \ + PA.SHOW_RESULTS \ + PA.DISPLAY_SUMMARY \ + PA.ADD_TO_OVERLAY \ if exclude is True: options = PA.SHOW_ROI_MASKS \ + PA.SHOW_RESULTS \ + PA.DISPLAY_SUMMARY \ + PA.ADD_TO_OVERLAY \ + PA.EXCLUDE_EDGE_PARTICLES measurements = PA.STACK_POSITION \ + PA.LABELS \ + PA.AREA \ + PA.RECT \ results = ResultsTable() p = PA(options, measurements, results, minsize, maxsize, mincirc, maxcirc) p.setHideOutputImage(True) particlestack = ImageStack(imp.getWidth(), imp.getHeight()) for i in range(imp.getStackSize()): imp.setSliceWithoutUpdate(i + 1) ip = imp.getProcessor() #IJ.run(imp, "Convert to Mask", "") p.analyze(imp, ip) mmap = p.getOutputImage() particlestack.addSlice(mmap.getProcessor()) return particlestack, results
def measure(self): imp = IJ.openImage(self.filename) IJ.log("Input file: %s" % self.filename) ImageConverter(imp).convertToGray8() res = Auto_Threshold().exec(imp, self.myMethod, self.noWhite, self.noBlack, self.doIwhite, self.doIset, self.doIlog, self.doIstackHistogram) rt = ResultsTable() rt.showRowNumbers(False) pa = PA(self.options, PA.AREA + PA.PERIMETER + PA.CIRCULARITY, rt, self.MINSIZE, self.MAXSIZE) pa.analyze(imp) self.result = self.rtToResult(rt) self.mask = imp
def test(): newImg = ImagePlus("GrayScaled", imp) newip = newImg.getProcessor() hist = newip.getHistogram() lowTH = Auto_Threshold.IsoData(hist) newip.setThreshold(lowTH, max(hist), ImageProcessor.BLACK_AND_WHITE_LUT) rt = ResultsTable() pa = ParticleAnalyzer(ParticleAnalyzer.SHOW_RESULTS | ParticleAnalyzer.SHOW_OVERLAY_OUTLINES, Measurements.AREA |Measurements.MEAN |\ Measurements.MEDIAN | Measurements.STD_DEV | Measurements.MIN_MAX | Measurements.RECT, rt,50, 200000, 0.5, 1 ) pa.setResultsTable(rt) pa.analyze(newImg) rt.show("Results")
def test(): newImg = ImagePlus("GrayScaled",imp) newip = newImg.getProcessor() hist = newip.getHistogram() lowTH = Auto_Threshold.IsoData(hist) newip.setThreshold(lowTH, max(hist),ImageProcessor.BLACK_AND_WHITE_LUT) rt = ResultsTable() pa = ParticleAnalyzer(ParticleAnalyzer.SHOW_RESULTS | ParticleAnalyzer.SHOW_OVERLAY_OUTLINES, Measurements.AREA |Measurements.MEAN |\ Measurements.MEDIAN | Measurements.STD_DEV | Measurements.MIN_MAX | Measurements.RECT, rt,50, 200000, 0.5, 1 ) pa.setResultsTable(rt) pa.analyze(newImg) rt.show("Results")
def generate_cell_rois(seg_binary_imp): """generate rois from which cell shape information will be gleaned""" seg_binary_imp.killRoi() mxsz = seg_binary_imp.width * seg_binary_imp.height roim = RoiManager(False) pa_options = ParticleAnalyzer.AREA | ParticleAnalyzer.PERIMETER | ParticleAnalyzer.SHAPE_DESCRIPTORS pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, pa_options, None, 1000, mxsz) pa.setRoiManager(roim) roim.reset() pa.analyze(seg_binary_imp) rois = roim.getRoisAsArray() roim.reset() roim.close() return rois
def process(inputpath, outputpath): imp = IJ.openImage(inputpath) IJ.run( imp, "Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=0.8777017 pixel_height=0.8777017 voxel_depth=25400.0508001" ) IJ.setThreshold(imp, t1, 255) #imp.show() #WaitForUserDialog("Title", "Look at image").show() IJ.run(imp, "Convert to Mask", "") IJ.run(imp, "Watershed", "") # Counts and measures the area of particles and adds them to a table called areas. Also adds them to the ROI manager table = ResultsTable() roim = RoiManager(True) ParticleAnalyzer.setRoiManager(roim) pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA, table, 50, 9999999999999999, 0.2, 1.0) pa.setHideOutputImage(True) pa.analyze(imp) imp.changes = False imp.close() areas = table.getColumn(0) summary = {} if areas: summary['Image'] = filename summary['Nuclei.count'] = len(areas) summary['Area.Covered'] = sum(areas) fieldnames = list(summary.keys()) with open(outputpath, 'a') as csvfile: writer = csv.DictWriter(csvfile, fieldnames=fieldnames, extrasaction='ignore', lineterminator='\n') if os.path.getsize(outputDirectory + "/" + outputname + ".csv") < 1: writer.writeheader() writer.writerow(summary)
def countobjects(imp, rt, subtractBackground=False, watershed=False, dilate=False, threshMethod="Otsu", physicalUnits=True, minSize=0.00, maxSize=float("inf"), minCirc=0.00, maxCirc=1.00): """Threshold and count objects in channel 'channelNumber'. This function splits an image in the separate channels, and counts the number of objects in the thresholded channel. Args: imp: An ImagePlus with 1 frame, 1 slice. Returns: A list of filepaths. """ cal = imp.getCalibration() if subtractBackground: IJ.run(imp, "Subtract Background...", "rolling=50") IJ.setAutoThreshold(imp, "{} dark".format(threshMethod)) IJ.run(imp, "Convert to Mask", "") if dilate: IJ.run(imp, "Dilate", "") if watershed: IJ.run(imp, "Watershed", "") if physicalUnits: # Convert physical units to pixels for the current calibration. minSize = cal.getRawX(math.sqrt(minSize))**2 maxSize = cal.getRawX(math.sqrt(maxSize))**2 pa = ParticleAnalyzer( ParticleAnalyzer.SHOW_OVERLAY_OUTLINES | ParticleAnalyzer.DISPLAY_SUMMARY, #int options Measurements.AREA | Measurements.SHAPE_DESCRIPTORS | Measurements.MEAN | Measurements.CENTROID | Measurements.LABELS, #int measurements rt, #ResultsTable minSize, #double maxSize, #double minCirc, #double maxCirc) #double pa.analyze(imp) return imp
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 removeSmallCCs(image): MINSIZE = 1000 MAXSIZE = 1000000 options = PA.SHOW_ROI_MASKS results = ResultsTable() p = PA(options, PA.STACK_POSITION + PA.LABELS + PA.AREA + PA.PERIMETER + PA.CIRCULARITY, results, MINSIZE, MAXSIZE) p.setHideOutputImage(True) p.analyze(image) mmap = p.getOutputImage() mip = mmap.getProcessor() mip.threshold(0) img = ImagePlus("rods_processed", mip) IJ.run(img, "8-bit", "") IJ.run(img, "Make Binary", "method=Default background=Dark black") return img
def AnalyzeParticle(IMP): rm = RoiManager().getInstance2() rt = ResultsTable() #再現性確保のために最終的には実装 #IJ.run("Set Measurements...","area centroid fit redirect=None decimal=3") #https://imagej.nih.gov/ij/developer/api/constant-values.html#ij.plugin.filter.ParticleAnalyzer.SHOW_RESULTS #表示オプション無し、resultは全部選択 PA = ParticleAnalyzer(0 , 1043199 , rt, 10000, 300000, 0.2, 1.0) PA.setRoiManager(rm) PA.analyze(IMP) #IJ.run(IMP, "Analyze Particles...", "display clear include add") rm.runCommand("Save", "C:/Users/For Programming/Documents/Python Scripts/OutletHDD/aaa.zip") rt.saveAs("C:/Users/For Programming/Documents/Python Scripts/OutletHDD/aaa.csv") #最後に全ての結果をCloseする。 #写真を先に消さないとバグる。 IMP.close() rm.close() rt.reset()
def anaParticles(imp, minSize, maxSize, minCirc): strName = imp.getShortTitle() imp.setTitle("original") ret = imp.duplicate() IJ.run(ret, "Enhance Contrast", "saturated=0.35") IJ.run(ret, "8-bit", "") IJ.run(ret, "Threshold", "method=Default white") IJ.run(ret, "Watershed", "") rt = ResultsTable() # strSetMeas = "area mean modal min center perimeter bounding fit shape feret's redirect='original' decimal=3" # N.B. redirect will not work without a displayed image, so we cannot use a gray level image strSetMeas = "area mean modal min center perimeter bounding fit shape feret's decimal=3" IJ.run("Set Measurements...", strSetMeas) # note this doies not get passed directly to ParticleAnalyzer, so # I did this, saved everything and looked for the measurement value in ~/Library/Preferences/IJ_Prefs.txt # measurements=27355 # meas = Measurements.AREA + Measurements.CIRCULARITY + Measurements.PERIMETER + Measurements.SHAPE_DESCRIPTORS # didn't work reliably meas = 27355 pa = ParticleAnalyzer(0, meas, rt, minSize, maxSize, minCirc, 1.0); pa.analyze(ret); rt.createTableFromImage(ret.getProcessor()) return [ret, rt]
def ana_particles(imp, minSize, maxSize, minCirc, bHeadless=True): """ana_particles(imp, minSize, maxSize, minCirc, bHeadless=True) Analyze particles using a watershed separation. If headless=True, we cannot redirect the intensity measurement to the original image because it is never displayed. If we display the original, we can and get the mean gray level. We may then compute the particle contrast from the measured Izero value for the image. No ability here to draw outlines on the original. """ strName = imp.getShortTitle() imp.setTitle("original") ret = imp.duplicate() ret.setTitle("work") IJ.run(ret, "Enhance Contrast", "saturated=0.35") IJ.run(ret, "8-bit", "") IJ.run(ret, "Threshold", "method=Default white") IJ.run(ret, "Watershed", "") rt = ResultsTable() # strSetMeas = "area mean modal min center perimeter bounding fit shape feret's redirect='original' decimal=3" # N.B. redirect will not work without a displayed image, so we cannot use a gray level image if bHeadless == True: strSetMeas = "area mean modal min center perimeter bounding fit shape feret's decimal=3" else: imp.show() strSetMeas = "area mean modal min center perimeter bounding fit shape feret's redirect='original' decimal=3" IJ.run("Set Measurements...", strSetMeas) # note this does not get passed directly to ParticleAnalyzer, so # I did this, saved everything and looked for the measurement value in ~/Library/Preferences/IJ_Prefs.txt # measurements=27355 # meas = Measurements.AREA + Measurements.CIRCULARITY + Measurements.PERIMETER + Measurements.SHAPE_DESCRIPTORS # didn't work reliably meas = 27355 pa = ParticleAnalyzer(0, meas, rt, minSize, maxSize, minCirc, 1.0) pa.analyze(ret) rt.createTableFromImage(ret.getProcessor()) return [ret, rt]
def countParticles(imp, roim, minSize, maxSize, minCircularity, maxCircularity): # Create a table to store the results table = ResultsTable() # Create the particle analyzer pa = ParticleAnalyzer( ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA | Measurements.MEAN | Measurements.ELLIPSE, table, minSize, maxSize, minCircularity, maxCircularity) pa.setRoiManager(roim) pa.setHideOutputImage(True) if pa.analyze(imp): print "All ok" else: print "There was a problem in analyzing", blobs areas = table.getColumn(0) intensities = table.getColumn(1) majors = table.getColumn(2)
def countParticles(imp, roim, minSize, maxSize, minCircularity, maxCircularity): # Create a table to store the results table = ResultsTable() # Create the particle analyzer pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA|Measurements.MEAN, table, minSize, maxSize, minCircularity, maxCircularity) #pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA|Measurements.MEAN, table, 10, Double.POSITIVE_INFINITY, 0.5, 1.0) #pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA|Measurements.MEAN, table, 5, 6, 0.5, 1.0) pa.setRoiManager(roim) pa.setHideOutputImage(True) if pa.analyze(imp): print "All ok" else: print "There was a problem in analyzing", blobs areas = table.getColumn(0) intensities = table.getColumn(1) if ( (areas!=None) and (intensities!=None)): for area, intensity in zip(areas,intensities): print str(area)+": "+str(intensity)
def getParticleCenters(imp): # Create a table to store the results rt = ResultsTable() paOpts = PA.SHOW_OUTLINES \ + PA.INCLUDE_HOLES \ + PA.EXCLUDE_EDGE_PARTICLES measurements = PA.CENTROID + PA.CENTER_OF_MASS MINSIZE = 1000 MAXSIZE = Double.POSITIVE_INFINITY pa = PA(paOpts,measurements, rt, MINSIZE, MAXSIZE) pa.setHideOutputImage(True) if not pa.analyze(imp): print "There was a problem in analyzing", imp # The measured centroids are listed in the first column of the results table, as a float array: centroids_x = rt.getColumn(rt.X_CENTROID) centroids_y = rt.getColumn(rt.Y_CENTROID) coms_x = rt.getColumn(rt.X_CENTER_OF_MASS) coms_y = rt.getColumn(rt.Y_CENTER_OF_MASS) return (centroids_x,centroids_y, coms_x, coms_y)
def process(self,imp): # extract nucleus channel, 8-bit and twice binned imp.setC(self.nucleusChannel) ip = imp.getChannelProcessor().duplicate() ip = ip.convertToByteProcessor() ip = ip.bin(4) nucleus = ImagePlus("nucleus_channel", ip) # threshold image and separate clumped nuclei IJ.run(nucleus, "Auto Threshold", "method=Otsu white setthreshold show"); IJ.run(nucleus, "Make Binary", "thresholded remaining black"); IJ.run(nucleus, "Watershed", ""); directory = imp.getTitle() directory = directory.replace(" ", "_")\ .replace(",", "_")\ .replace("#", "_series")\ .replace("...", "")\ .replace(".","_") directory = os.path.join(self.exportDir, directory) sliceDirectory = os.path.join(directory, "slices") print directory print sliceDirectory if not os.path.exists(sliceDirectory): os.makedirs(sliceDirectory) # Create a table to store the results table = ResultsTable() # Create a hidden ROI manager, to store a ROI for each blob or cell #roim = RoiManager(True) # remove small particles and border particles pa = ParticleAnalyzer(\ ParticleAnalyzer.ADD_TO_MANAGER | ParticleAnalyzer.EXCLUDE_EDGE_PARTICLES,\ Measurements.CENTER_OF_MASS,\ table,\ self.minArea, self.maxArea,\ 0.0,1.0) if pa.analyze(nucleus): print "All ok, number of particles: ", table.size() else: print "There was a problem in analyzing", imp, nucleus table.save(os.path.join(directory, "rt.csv")) # read the center of mass coordinates cmx = table.getColumn(0) cmy = table.getColumn(1) if self.debug: imp.show() i=0 for i in range(0, min(self.nCells,table.size())): # ROI around the cell cmx = table.getValue("XM",i) cmy = table.getValue("YM",i) x = 4 * cmx - (self.boxSize - 1) / 2 y = 4 * cmy - (self.boxSize - 1) / 2 if (x < self.edge or y < self.edge or x > imp.getWidth() - self.edge or y > imp.getHeight() - self.edge): continue roi = Roi(x,y,self.boxSize,self.boxSize) imp.setRoi(roi, False) cellStack = ImageStack(self.boxSize, self.boxSize) for z in range(1, imp.getNSlices() + 1): imp.setSlice(z) for c in range(1, imp.getNChannels() + 1): imp.setC(c) # copy ROI to stack imp.copy() impSlice = imp.getClipboard() cellStack.addSlice(impSlice.getProcessor()) if self.slices: sliceTitle = "cell_%s_z%s_c%s" % (str(i).zfill(4), str(z).zfill(3), str(c)) print sliceTitle IJ.saveAsTiff(impSlice, os.path.join(sliceDirectory, sliceTitle)) impSlice.close() title = "cell_" + str(i).zfill(4) cell = ImagePlus(title, cellStack) # save ROI image IJ.saveAsTiff(cell, os.path.join(directory, title)) cell.close() if self.debug: imp.updateAndDraw() wait = Wait("particle done") wait.show()
def process(subFolder, outputDirectory, filename): #IJ.close() imp = IJ.openImage(inputDirectory + subFolder + '/' + rreplace(filename, "_ch00.tif", ".tif")) imp.show() # Get the pixel values from the xml file for file in os.listdir(inputDirectory + subFolder): if file.endswith('.xml'): xml = os.path.join(inputDirectory + subFolder, file) xml = "C:/Users/Harris/Desktop/test_xml_for_parsing_pixel.xml" element_tree = ET.parse(xml) root = element_tree.getroot() for dimensions in root.iter('DimensionDescription'): num_pixels = int(dimensions.attrib['NumberOfElements']) if dimensions.attrib['Unit'] == "m": length = float(dimensions.attrib['Length']) * 1000000 else: length = float(dimensions.attrib['Length']) pixel_length = length / num_pixels else: pixel_length = 0.8777017 IJ.run( imp, "Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=" + str(pixel_length) + " pixel_height=" + str(pixel_length) + " voxel_depth=25400.0508001") ic = ImageConverter(imp) ic.convertToGray8() #IJ.setThreshold(imp, 2, 255) #Automatically selects the area of the organoid based on automated thresholding and creates a mask to be applied on #all other images IJ.setAutoThreshold(imp, "Mean dark no-reset") IJ.run(imp, "Convert to Mask", "") IJ.run(imp, "Analyze Particles...", "size=100000-Infinity add select") rm = RoiManager.getInstance() num_roi = rm.getCount() for i in num_roi: imp = getCurrentImage() rm.select(imp, i) IJ.setBackgroundColor(0, 0, 0) IJ.run(imp, "Clear Outside", "") IJ.run(imp, "Convert to Mask", "") IJ.run(imp, "Remove Outliers...", "radius=5" + " threshold=50" + " which=Dark") IJ.run(imp, "Remove Outliers...", "radius=5" + " threshold=50" + " which=Bright") # Save the mask and open it IJ.saveAs("tiff", inputDirectory + '/mask' + i) mask = IJ.openImage(inputDirectory + '/mask' + i + '.tif') if not displayImages: imp.changes = False imp.close() images = [None] * 5 intensities = [None] * 5 blobsarea = [None] * 5 blobsnuclei = [None] * 5 bigAreas = [None] * 5 imp.close() # Loop to open all the channel images for chan in channels: v, x = chan images[x] = IJ.openImage(inputDirectory + subFolder + '/' + rreplace(filename, "_ch00.tif", "_ch0" + str(x) + ".tif")) # Apply Mask on all the images and save them into an array apply_mask = ImageCalculator() images[x] = apply_mask.run("Multiply create 32 bit", mask, images[x]) ic = ImageConverter(images[x]) ic.convertToGray8() imp = images[x] # Calculate the intensities for each channel as well as the organoid area for roi in rm.getRoisAsArray(): imp.setRoi(roi) stats_i = imp.getStatistics(Measurements.MEAN | Measurements.AREA) intensities[x] = stats_i.mean bigAreas[x] = stats_i.area rm.close() # Opens the ch00 image and sets default properties #Get the pixel values from the xml file for file in os.listdir(subFolder): if file.endswith('.xml'): xml = os.path.join(inputDirectory + subFolder, file) xml = "C:/Users/Harris/Desktop/test_xml_for_parsing_pixel.xml" element_tree = ET.parse(xml) root = element_tree.getroot() for dimensions in root.iter('DimensionDescription'): num_pixels = int(dimensions.attrib['NumberOfElements']) if dimensions.attrib['Unit'] == "m": length = float(dimensions.attrib['Length']) * 1000000 else: length = float(dimensions.attrib['Length']) pixel_length = length / num_pixels else: pixel_length = 0.8777017 imp = IJ.openImage(inputDirectory + subFolder + '/' + filename) imp = apply_mask.run("Multiply create 32 bit", mask, imp) IJ.run( imp, "Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=" + str(pixel_length) + "pixel_height=" + str(pixel_length) + "voxel_depth=25400.0508001") # Sets the threshold and watersheds. for more details on image processing, see https://imagej.nih.gov/ij/developer/api/ij/process/ImageProcessor.html ic = ImageConverter(imp) ic.convertToGray8() IJ.run(imp, "Remove Outliers...", "radius=2" + " threshold=50" + " which=Dark") IJ.run(imp, "Gaussian Blur...", "sigma=" + str(blur)) IJ.setThreshold(imp, lowerBounds[0], 255) if displayImages: imp.show() IJ.run(imp, "Convert to Mask", "") IJ.run(imp, "Watershed", "") if not displayImages: imp.changes = False imp.close() # Counts and measures the area of particles and adds them to a table called areas. Also adds them to the ROI manager table = ResultsTable() roim = RoiManager(True) ParticleAnalyzer.setRoiManager(roim) pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA, table, 15, 9999999999999999, 0.2, 1.0) pa.setHideOutputImage(True) # imp = impM # imp.getProcessor().invert() pa.analyze(imp) areas = table.getColumn(0) # This loop goes through the remaining channels for the other markers, by replacing the ch00 at the end with its corresponding channel # It will save all the area fractions into a 2d array called areaFractionsArray areaFractionsArray = [None] * 5 for chan in channels: v, x = chan # Opens each image and thresholds imp = images[x] IJ.run( imp, "Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=0.8777017 pixel_height=0.8777017 voxel_depth=25400.0508001" ) ic = ImageConverter(imp) ic.convertToGray8() IJ.setThreshold(imp, lowerBounds[x], 255) if displayImages: imp.show() WaitForUserDialog("Title", "Adjust Threshold for Marker " + v).show() IJ.run(imp, "Convert to Mask", "") # Measures the area fraction of the new image for each ROI from the ROI manager. areaFractions = [] for roi in roim.getRoisAsArray(): imp.setRoi(roi) stats = imp.getStatistics(Measurements.AREA_FRACTION) areaFractions.append(stats.areaFraction) # Saves the results in areaFractionArray areaFractionsArray[x] = areaFractions roim.close() for chan in channels: v, x = chan imp = images[x] imp.deleteRoi() roim = RoiManager(True) ParticleAnalyzer.setRoiManager(roim) pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA, table, 15, 9999999999999999, 0.2, 1.0) pa.analyze(imp) blobs = [] for roi in roim.getRoisAsArray(): imp.setRoi(roi) stats = imp.getStatistics(Measurements.AREA) blobs.append(stats.area) blobsarea[x] = sum( blobs ) #take this out and use intial mask tissue area from the beginning blobsnuclei[x] = len(blobs) if not displayImages: imp.changes = False imp.close() roim.reset() roim.close() imp.close() # Creates the summary dictionary which will correspond to a single row in the output csv, with each key being a column summary = {} summary['Image'] = filename summary['Directory'] = subFolder # Adds usual columns summary['size-average'] = 0 summary['#nuclei'] = 0 summary['all-negative'] = 0 summary['too-big-(>' + str(tooBigThreshold) + ')'] = 0 summary['too-small-(<' + str(tooSmallThreshold) + ')'] = 0 # Creates the fieldnames variable needed to create the csv file at the end. fieldnames = [ 'Name', 'Directory', 'Image', 'size-average', 'too-big-(>' + str(tooBigThreshold) + ')', 'too-small-(<' + str(tooSmallThreshold) + ')', '#nuclei', 'all-negative' ] # Adds the columns for each individual marker (ignoring Dapi since it was used to count nuclei) summary["organoid-area"] = bigAreas[x] fieldnames.append("organoid-area") for chan in channels: v, x = chan summary[v + "-positive"] = 0 fieldnames.append(v + "-positive") summary[v + "-intensity"] = intensities[x] fieldnames.append(v + "-intensity") summary[v + "-blobsarea"] = blobsarea[x] fieldnames.append(v + "-blobsarea") summary[v + "-blobsnuclei"] = blobsnuclei[x] fieldnames.append(v + "-blobsnuclei") # Adds the column for colocalization between first and second marker if len(channels) > 2: summary[channels[1][0] + '-' + channels[2][0] + '-positive'] = 0 fieldnames.append(channels[1][0] + '-' + channels[2][0] + '-positive') # Adds the columns for colocalization between all three markers if len(channels) > 3: summary[channels[1][0] + '-' + channels[3][0] + '-positive'] = 0 summary[channels[2][0] + '-' + channels[3][0] + '-positive'] = 0 summary[channels[1][0] + '-' + channels[2][0] + '-' + channels[3][0] + '-positive'] = 0 fieldnames.append(channels[1][0] + '-' + channels[3][0] + '-positive') fieldnames.append(channels[2][0] + '-' + channels[3][0] + '-positive') fieldnames.append(channels[1][0] + '-' + channels[2][0] + '-' + channels[3][0] + '-positive') # Loops through each particle and adds it to each field that it is True for. areaCounter = 0 for z, area in enumerate(areas): log.write(str(area)) log.write("\n") if area > tooBigThreshold: summary['too-big-(>' + str(tooBigThreshold) + ')'] += 1 elif area < tooSmallThreshold: summary['too-small-(<' + str(tooSmallThreshold) + ')'] += 1 else: summary['#nuclei'] += 1 areaCounter += area temp = 0 for chan in channels: v, x = chan if areaFractionsArray[x][z] > areaFractionThreshold[ 0]: # theres an error here im not sure why. i remember fixing it before summary[chan[0] + '-positive'] += 1 if x != 0: temp += 1 if temp == 0: summary['all-negative'] += 1 if len(channels) > 2: if areaFractionsArray[1][z] > areaFractionThreshold[1]: if areaFractionsArray[2][z] > areaFractionThreshold[2]: summary[channels[1][0] + '-' + channels[2][0] + '-positive'] += 1 if len(channels) > 3: if areaFractionsArray[1][z] > areaFractionThreshold[1]: if areaFractionsArray[3][z] > areaFractionThreshold[3]: summary[channels[1][0] + '-' + channels[3][0] + '-positive'] += 1 if areaFractionsArray[2][z] > areaFractionThreshold[2]: if areaFractionsArray[3][z] > areaFractionThreshold[3]: summary[channels[2][0] + '-' + channels[3][0] + '-positive'] += 1 if areaFractionsArray[1][z] > areaFractionThreshold[1]: summary[channels[1][0] + '-' + channels[2][0] + '-' + channels[3][0] + '-positive'] += 1 # Calculate the average of the particles sizes if float(summary['#nuclei']) > 0: summary['size-average'] = round(areaCounter / summary['#nuclei'], 2) # Opens and appends one line on the final csv file for the subfolder (remember that this is still inside the loop that goes through each image) with open(outputDirectory + "/" + outputName + ".csv", 'a') as csvfile: writer = csv.DictWriter(csvfile, fieldnames=fieldnames, extrasaction='ignore', lineterminator='\n') if os.path.getsize(outputDirectory + "/" + outputName + ".csv") < 1: writer.writeheader() writer.writerow(summary) IJ.run(imp, "Close All", "")
def analyzeParticles(imp, minsize, maxsize, mincirc, maxcirc, #filename='Test.czi', addROIManager=False, #headless=False, exclude=True): if GraphicsEnvironment.isHeadless(): print('Headless Mode detected. Do not use ROI Manager.') addROIManager = False if addROIManager: # get the ROI manager instance rm = RoiManager.getInstance() if rm is None: rm = RoiManager() rm.runCommand("Associate", "true") if not exclude: options = PA.SHOW_ROI_MASKS \ + PA.SHOW_RESULTS \ + PA.DISPLAY_SUMMARY \ + PA.ADD_TO_MANAGER \ + PA.ADD_TO_OVERLAY \ if exclude: options = PA.SHOW_ROI_MASKS \ + PA.SHOW_RESULTS \ + PA.DISPLAY_SUMMARY \ + PA.ADD_TO_MANAGER \ + PA.ADD_TO_OVERLAY \ + PA.EXCLUDE_EDGE_PARTICLES if not addROIManager: if not exclude: options = PA.SHOW_ROI_MASKS \ + PA.SHOW_RESULTS \ + PA.DISPLAY_SUMMARY \ + PA.ADD_TO_OVERLAY \ if exclude: options = PA.SHOW_ROI_MASKS \ + PA.SHOW_RESULTS \ + PA.DISPLAY_SUMMARY \ + PA.ADD_TO_OVERLAY \ + PA.EXCLUDE_EDGE_PARTICLES measurements = PA.STACK_POSITION \ + PA.LABELS \ + PA.AREA \ + PA.RECT \ + PA.PERIMETER \ + PA.SLICE \ + PA.SHAPE_DESCRIPTORS \ + PA.CENTER_OF_MASS \ + PA.CENTROID results = ResultsTable() p = PA(options, measurements, results, minsize, maxsize, mincirc, maxcirc) p.setHideOutputImage(True) particlestack = ImageStack(imp.getWidth(), imp.getHeight()) for i in range(imp.getStackSize()): imp.setSliceWithoutUpdate(i + 1) ip = imp.getProcessor() # convert to a mask for the particle analyzer ip.invert() # do the particle analysis p.analyze(imp, ip) mmap = p.getOutputImage() # add the slide to the full stack particlestack.addSlice(mmap.getProcessor()) return particlestack, results
from ij.measure import ResultsTable from ij.measure import Measurements from ij.plugin.frame import RoiManager from ij.plugin.filter import ParticleAnalyzer from ij import IJ # get active image imp=IJ.getImage() # set up first ROI manager table1 = ResultsTable() roim1=RoiManager() pa1 = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA|Measurements.MEAN|Measurements.ELLIPSE, table1, 0, 100, 0, 1) pa1.setRoiManager(roim1) pa1.analyze(imp) # set up second ROI manager table2 = ResultsTable() # Pass true to second ROI manager so it will not be seen roim2=RoiManager(True) pa2 = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA|Measurements.MEAN|Measurements.ELLIPSE, table2, 100, 500, 0, 1) pa2.setRoiManager(roim2) pa2.analyze(imp) print "rois from first manager:" for roi in roim1.getRoisAsArray(): print roi print print "rois from second manager:" for roi in roim2.getRoisAsArray(): print roi
def process(subFolder, outputDirectory, filename): imp = IJ.openImage(inputDirectory + subFolder + '/' + rreplace(filename, "_ch00.tif", ".tif")) IJ.run( imp, "Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=0.8777017 pixel_height=0.8777017 voxel_depth=25400.0508001" ) ic = ImageConverter(imp) ic.convertToGray8() IJ.setThreshold(imp, 2, 255) IJ.run(imp, "Convert to Mask", "") IJ.run(imp, "Remove Outliers...", "radius=5" + " threshold=50" + " which=Dark") IJ.run(imp, "Remove Outliers...", "radius=5" + " threshold=50" + " which=Bright") imp.getProcessor().invert() rm = RoiManager(True) imp.getProcessor().setThreshold(0, 0, ImageProcessor.NO_LUT_UPDATE) boundroi = ThresholdToSelection.run(imp) rm.addRoi(boundroi) if not displayImages: imp.changes = False imp.close() images = [None] * 5 intensities = [None] * 5 blobsarea = [None] * 5 blobsnuclei = [None] * 5 bigAreas = [None] * 5 for chan in channels: v, x = chan images[x] = IJ.openImage(inputDirectory + subFolder + '/' + rreplace(filename, "_ch00.tif", "_ch0" + str(x) + ".tif")) imp = images[x] for roi in rm.getRoisAsArray(): imp.setRoi(roi) stats = imp.getStatistics(Measurements.MEAN | Measurements.AREA) intensities[x] = stats.mean bigAreas[x] = stats.area rm.close() # Opens the ch00 image and sets default properties imp = IJ.openImage(inputDirectory + subFolder + '/' + filename) IJ.run( imp, "Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=0.8777017 pixel_height=0.8777017 voxel_depth=25400.0508001" ) # Sets the threshold and watersheds. for more details on image processing, see https://imagej.nih.gov/ij/developer/api/ij/process/ImageProcessor.html ic = ImageConverter(imp) ic.convertToGray8() IJ.run(imp, "Remove Outliers...", "radius=2" + " threshold=50" + " which=Dark") IJ.run(imp, "Gaussian Blur...", "sigma=" + str(blur)) IJ.setThreshold(imp, lowerBounds[0], 255) if displayImages: imp.show() IJ.run(imp, "Convert to Mask", "") IJ.run(imp, "Watershed", "") if not displayImages: imp.changes = False imp.close() # Counts and measures the area of particles and adds them to a table called areas. Also adds them to the ROI manager table = ResultsTable() roim = RoiManager(True) ParticleAnalyzer.setRoiManager(roim) pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA, table, 15, 9999999999999999, 0.2, 1.0) pa.setHideOutputImage(True) #imp = impM # imp.getProcessor().invert() pa.analyze(imp) areas = table.getColumn(0) # This loop goes through the remaining channels for the other markers, by replacing the ch00 at the end with its corresponding channel # It will save all the area fractions into a 2d array called areaFractionsArray areaFractionsArray = [None] * 5 for chan in channels: v, x = chan # Opens each image and thresholds imp = images[x] IJ.run( imp, "Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=0.8777017 pixel_height=0.8777017 voxel_depth=25400.0508001" ) ic = ImageConverter(imp) ic.convertToGray8() IJ.setThreshold(imp, lowerBounds[x], 255) if displayImages: imp.show() WaitForUserDialog("Title", "Adjust Threshold for Marker " + v).show() IJ.run(imp, "Convert to Mask", "") # Measures the area fraction of the new image for each ROI from the ROI manager. areaFractions = [] for roi in roim.getRoisAsArray(): imp.setRoi(roi) stats = imp.getStatistics(Measurements.AREA_FRACTION) areaFractions.append(stats.areaFraction) # Saves the results in areaFractionArray areaFractionsArray[x] = areaFractions roim.close() for chan in channels: v, x = chan imp = images[x] imp.deleteRoi() roim = RoiManager(True) ParticleAnalyzer.setRoiManager(roim) pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA, table, 15, 9999999999999999, 0.2, 1.0) pa.analyze(imp) blobs = [] for roi in roim.getRoisAsArray(): imp.setRoi(roi) stats = imp.getStatistics(Measurements.AREA) blobs.append(stats.area) blobsarea[x] = sum(blobs) blobsnuclei[x] = len(blobs) if not displayImages: imp.changes = False imp.close() roim.reset() roim.close() # Creates the summary dictionary which will correspond to a single row in the output csv, with each key being a column summary = {} summary['Image'] = filename summary['Directory'] = subFolder # Adds usual columns summary['size-average'] = 0 summary['#nuclei'] = 0 summary['all-negative'] = 0 summary['too-big-(>' + str(tooBigThreshold) + ')'] = 0 summary['too-small-(<' + str(tooSmallThreshold) + ')'] = 0 # Creates the fieldnames variable needed to create the csv file at the end. fieldnames = [ 'Name', 'Directory', 'Image', 'size-average', 'too-big-(>' + str(tooBigThreshold) + ')', 'too-small-(<' + str(tooSmallThreshold) + ')', '#nuclei', 'all-negative' ] # Adds the columns for each individual marker (ignoring Dapi since it was used to count nuclei) summary["organoid-area"] = bigAreas[x] fieldnames.append("organoid-area") for chan in channels: v, x = chan summary[v + "-positive"] = 0 fieldnames.append(v + "-positive") summary[v + "-intensity"] = intensities[x] fieldnames.append(v + "-intensity") summary[v + "-blobsarea"] = blobsarea[x] fieldnames.append(v + "-blobsarea") summary[v + "-blobsnuclei"] = blobsnuclei[x] fieldnames.append(v + "-blobsnuclei") # Adds the column for colocalization between first and second marker if len(channels) > 2: summary[channels[1][0] + '-' + channels[2][0] + '-positive'] = 0 fieldnames.append(channels[1][0] + '-' + channels[2][0] + '-positive') # Adds the columns for colocalization between all three markers if len(channels) > 3: summary[channels[1][0] + '-' + channels[3][0] + '-positive'] = 0 summary[channels[2][0] + '-' + channels[3][0] + '-positive'] = 0 summary[channels[1][0] + '-' + channels[2][0] + '-' + channels[3][0] + '-positive'] = 0 fieldnames.append(channels[1][0] + '-' + channels[3][0] + '-positive') fieldnames.append(channels[2][0] + '-' + channels[3][0] + '-positive') fieldnames.append(channels[1][0] + '-' + channels[2][0] + '-' + channels[3][0] + '-positive') # Loops through each particle and adds it to each field that it is True for. areaCounter = 0 for z, area in enumerate(areas): log.write(str(area)) log.write("\n") if area > tooBigThreshold: summary['too-big-(>' + str(tooBigThreshold) + ')'] += 1 elif area < tooSmallThreshold: summary['too-small-(<' + str(tooSmallThreshold) + ')'] += 1 else: summary['#nuclei'] += 1 areaCounter += area temp = 0 for chan in channels: v, x = chan if areaFractionsArray[x][z] > areaFractionThreshold[ 0]: #theres an error here im not sure why. i remember fixing it before summary[chan[0] + '-positive'] += 1 if x != 0: temp += 1 if temp == 0: summary['all-negative'] += 1 if len(channels) > 2: if areaFractionsArray[1][z] > areaFractionThreshold[1]: if areaFractionsArray[2][z] > areaFractionThreshold[2]: summary[channels[1][0] + '-' + channels[2][0] + '-positive'] += 1 if len(channels) > 3: if areaFractionsArray[1][z] > areaFractionThreshold[1]: if areaFractionsArray[3][z] > areaFractionThreshold[3]: summary[channels[1][0] + '-' + channels[3][0] + '-positive'] += 1 if areaFractionsArray[2][z] > areaFractionThreshold[2]: if areaFractionsArray[3][z] > areaFractionThreshold[3]: summary[channels[2][0] + '-' + channels[3][0] + '-positive'] += 1 if areaFractionsArray[1][z] > areaFractionThreshold[1]: summary[channels[1][0] + '-' + channels[2][0] + '-' + channels[3][0] + '-positive'] += 1 # Calculate the average of the particles sizes if float(summary['#nuclei']) > 0: summary['size-average'] = round(areaCounter / summary['#nuclei'], 2) # Opens and appends one line on the final csv file for the subfolder (remember that this is still inside the loop that goes through each image) with open(outputDirectory + "/" + outputName + ".csv", 'a') as csvfile: writer = csv.DictWriter(csvfile, fieldnames=fieldnames, extrasaction='ignore', lineterminator='\n') if os.path.getsize(outputDirectory + "/" + outputName + ".csv") < 1: writer.writeheader() writer.writerow(summary)
+ PA.CLEAR_WORKSHEET \ # + PA.SHOW_RESULTS \ rt = ResultsTable() p = PA(options, PA.AREA + PA.STACK_POSITION, rt, MINSIZE, MAXSIZE) p.setHideOutputImage(True) # Morphological dilate binner.setup('dilate', None) clusters = 0 initialCells = 0 # dilate by 'SAMPLEITER' for i in range(SAMPLEITER+1): p.analyze(binimp) cellcounts = rt.getCounter() if i == 0: initialCells = cellcounts #IJ.log("iter:" + str(i) + " -- cell counts: " + str(cellcounts)) if i == SAMPLEITER: clusters = cellcounts binner.run(binimp.getProcessor()) rt.reset() #binimp.show() #binorg.show() IJ.log("==== " + imp3.getTitle() + " =====") IJ.log("Number of Nucleus : " + str(initialCells)) IJ.log("Clusters at dilation " + str(SAMPLEITER) + ": " + str(clusters)) IJ.log("Clusters/Nucleus " + str(float(clusters)/float(initialCells)))
def process(subDir, subsubDir, outputDirectory, filename): subFolder = subDir + "/" + subsubDir # Opens the d0 image and sets default properties imp = IJ.openImage(inputDirectory + subFolder + '/' + filename) IJ.run( imp, "Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=0.8777017 pixel_height=0.8777017 voxel_depth=25400.0508001" ) # Sets the threshold and watersheds. for more details on image processing, see https://imagej.nih.gov/ij/developer/api/ij/process/ImageProcessor.html ic = ImageConverter(imp) ic.convertToGray8() imp.updateAndDraw() dup = imp.duplicate() IJ.run( dup, "Convolve...", "text1=[-1 -1 -1 -1 -1\n-1 -1 -1 -1 -1\n-1 -1 24 -1 -1\n-1 -1 -1 -1 -1\n-1 -1 -1 -1 -1\n] normalize" ) stats = dup.getStatistics(Measurements.MEAN | Measurements.MIN_MAX | Measurements.STD_DEV) dup.close() blurry = (stats.mean < 18 and stats.stdDev < 22) or stats.max < 250 IJ.setThreshold(imp, lowerBounds[0], 255) IJ.run(imp, "Convert to Mask", "") IJ.run(imp, "Watershed", "") if displayImages: imp.show() WaitForUserDialog("Title", "Look at image").show() # Counts and measures the area of particles and adds them to a table called areas. Also adds them to the ROI manager table = ResultsTable() roim = RoiManager(True) ParticleAnalyzer.setRoiManager(roim) pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA, table, 15, 9999999999999999, 0.2, 1.0) pa.setHideOutputImage(True) pa.analyze(imp) if not displayImages: imp.changes = False imp.close() areas = table.getColumn(0) # This loop goes through the remaining channels for the other markers, by replacing the d0 at the end with its corresponding channel # It will save all the area fractions into a 2d array called areaFractionsArray areaFractionsArray = [] areaMeansArray = [] means = [] totalAreas = [] for chan in channels: v, x = chan # Opens each image and thresholds imp = IJ.openImage(inputDirectory + subFolder + '/' + filename.replace("d0.TIF", "d" + str(x) + ".TIF")) IJ.run( imp, "Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=0.8777017 pixel_height=0.8777017 voxel_depth=25400.0508001" ) ic = ImageConverter(imp) ic.convertToGray8() imp.updateAndDraw() stats = imp.getStatistics(Measurements.MEAN) means.append(stats.mean) areaMeans = [] for roi in roim.getRoisAsArray(): imp.setRoi(roi) stats = imp.getStatistics(Measurements.MEAN) areaMeans.append(stats.mean) IJ.setThreshold(imp, lowerBounds[x], 255) IJ.run(imp, "Convert to Mask", "") if displayImages: imp.show() WaitForUserDialog("Title", "Look at image").show() stats = imp.getStatistics(Measurements.AREA_FRACTION) totalAreas.append(stats.areaFraction) # Measures the area fraction of the new image for each ROI from the ROI manager. areaFractions = [] for roi in roim.getRoisAsArray(): imp.setRoi(roi) stats = imp.getStatistics(Measurements.AREA_FRACTION) areaFractions.append(stats.areaFraction) # Saves the results in areaFractionArray areaFractionsArray.append(areaFractions) areaMeansArray.append(sum(areaMeans) / len(areaMeans)) if not displayImages: imp.changes = False imp.close() roim.close() # Figures out what well the image is a part of ind = filename.index("p00_0_") row = filename[ind + 6:ind + 7] column = str(int(filename[ind + 7:ind + 9])) # Creates the summary dictionary which will correspond to a single row in the output csv, with each key being a column summary = {} # Finds the name of the well from the nameArray 2d array if row in nameArray: if column in nameArray[row]: summary['Name'] = nameArray[row][column] summary['Image'] = filename summary['Directory'] = subDir summary['SubDirectory'] = subsubDir summary['Row'] = row summary['Column'] = column # Adds usual columns summary['size-average'] = 0 summary['#nuclei'] = 0 summary['all-negative'] = 0 summary['too-big-(>' + str(tooBigThreshold) + ')'] = 0 summary['too-small-(<' + str(tooSmallThreshold) + ')'] = 0 summary['image-quality'] = blurry # Creates the fieldnames variable needed to create the csv file at the end. fieldnames = [ 'Name', 'Directory', 'SubDirectory', 'Image', 'Row', 'Column', 'size-average', 'image-quality', 'too-big-(>' + str(tooBigThreshold) + ')', 'too-small-(<' + str(tooSmallThreshold) + ')', '#nuclei', 'all-negative' ] # Adds the columns for each individual marker (ignoring Dapi since it was used to count nuclei) for chan in channels: v, x = chan summary[v + "-positive"] = 0 summary[v + "-intensity"] = means[x] summary[v + "-area"] = totalAreas[x] summary[v + "-intensity-in-nuclei"] = areaMeansArray[x] summary[v + "-area-fraction-in-nuclei"] = sum( areaFractionsArray[x]) / len(areaFractionsArray[x]) fieldnames.append(v + "-positive") fieldnames.append(v + "-intensity") fieldnames.append(v + "-area") fieldnames.append(v + "-intensity-in-nuclei") fieldnames.append(v + "-area-fraction-in-nuclei") # Adds the column for colocalization between first and second marker if len(channels) > 2: summary[channels[1][0] + '-' + channels[2][0] + '-positive'] = 0 fieldnames.append(channels[1][0] + '-' + channels[2][0] + '-positive') # Adds the columns for colocalization between all three markers if len(channels) > 3: summary[channels[1][0] + '-' + channels[3][0] + '-positive'] = 0 summary[channels[2][0] + '-' + channels[3][0] + '-positive'] = 0 summary[channels[1][0] + '-' + channels[2][0] + '-' + channels[3][0] + '-positive'] = 0 fieldnames.append(channels[1][0] + '-' + channels[3][0] + '-positive') fieldnames.append(channels[2][0] + '-' + channels[3][0] + '-positive') fieldnames.append(channels[1][0] + '-' + channels[2][0] + '-' + channels[3][0] + '-positive') # Loops through each particle and adds it to each field that it is True for. areaCounter = 0 if not (areas is None): for z, area in enumerate(areas): if not (area is None or summary is None): if area > tooBigThreshold: summary['too-big-(>' + str(tooBigThreshold) + ')'] += 1 elif area < tooSmallThreshold: summary['too-small-(<' + str(tooSmallThreshold) + ')'] += 1 else: summary['#nuclei'] += 1 areaCounter += area temp = 0 for y, chan in enumerate(channels): v, x = chan if areaFractionsArray[y][z] > areaFractionThreshold: summary[chan[0] + '-positive'] += 1 if x != 0: temp += 1 if temp == 0: summary['all-negative'] += 1 if len(channels) > 2: if areaFractionsArray[1][z] > areaFractionThreshold: if areaFractionsArray[2][z] > areaFractionThreshold: summary[channels[1][0] + '-' + channels[2][0] + '-positive'] += 1 if len(channels) > 3: if areaFractionsArray[1][z] > areaFractionThreshold: if areaFractionsArray[3][z] > areaFractionThreshold: summary[channels[1][0] + '-' + channels[3][0] + '-positive'] += 1 if areaFractionsArray[2][z] > areaFractionThreshold: if areaFractionsArray[3][z] > areaFractionThreshold: summary[channels[2][0] + '-' + channels[3][0] + '-positive'] += 1 if areaFractionsArray[1][ z] > areaFractionThreshold: summary[channels[1][0] + '-' + channels[2][0] + '-' + channels[3][0] + '-positive'] += 1 # Calculate the average of the particles sizes if float(summary['#nuclei']) > 0: summary['size-average'] = round(areaCounter / summary['#nuclei'], 2) # Opens and appends one line on the final csv file for the subfolder (remember that this is still inside the loop that goes through each image) with open(outputDirectory + "/" + outputName + ".csv", 'a') as csvfile: writer = csv.DictWriter(csvfile, fieldnames=fieldnames, extrasaction='ignore', lineterminator='\n') if os.path.getsize(outputDirectory + "/" + outputName + ".csv") < 1: writer.writeheader() writer.writerow(summary)
def merge_incorrect_splits_and_get_centroids(imp, centroid_distance_limit=100, size_limit=100): """if particles are found with centroids closer than centroid_distance_limit and both have size<size_limit, get average centroid""" imp.killRoi() rt = ResultsTable() out_imp = IJ.createImage("Nuclei centroids from {}".format(imp.getTitle()), imp.getWidth(), imp.getHeight(), 1, 8) out_imp.show() IJ.run(out_imp, "Select All", "") IJ.run(out_imp, "Set...", "value=0 slice") out_imp.show() cal = imp.getCalibration() mxsz = imp.width * cal.pixelWidth * imp.height * cal.pixelHeight print("mxsz = {}".format(mxsz)) roim = RoiManager() imp.show() pa = ParticleAnalyzer( ParticleAnalyzer.ADD_TO_MANAGER, ParticleAnalyzer.AREA | ParticleAnalyzer.SLICE | ParticleAnalyzer.CENTROID, rt, 0, size_limit) pa.setRoiManager(roim) roim.reset() rt.reset() pa.analyze(imp) MyWaitForUser("paise", "pause post-merge incorrect splits particel analysis") rt_xs = rt.getColumn(rt.getColumnIndex("X")).tolist() rt_ys = rt.getColumn(rt.getColumnIndex("Y")).tolist() centroids = [(x, y) for x, y in zip(rt_xs, rt_ys)] print("centroids = {}".format(centroids)) centroids_set = set() for c in centroids: ds = [ math.sqrt((c[0] - cx)**2 + (c[1] - cy)**2) for (cx, cy) in centroids ] close_mask = [d < centroid_distance_limit for d in ds] # if no other centroids are within centroid_distance_limit, add this centroid to the output set # otherwise, add the average position of this centroid and those within centroid_distance_limit to the output set centroids_set.add( (sum([msk * b[0] for msk, b in zip(close_mask, centroids)]) / sum(close_mask), sum([msk * b[1] for msk, b in zip(close_mask, centroids)]) / sum(close_mask))) roim.reset() rt.reset() pa = ParticleAnalyzer( ParticleAnalyzer.ADD_TO_MANAGER, ParticleAnalyzer.AREA | ParticleAnalyzer.SLICE | ParticleAnalyzer.CENTROID, rt, size_limit, mxsz) pa.setRoiManager(roim) pa.analyze(imp) MyWaitForUser("paise", "pause post-merge incorrect splits particel analysis 2") if rt.columnExists("X"): rt_xs = rt.getColumn(rt.getColumnIndex("X")).tolist() rt_ys = rt.getColumn(rt.getColumnIndex("Y")).tolist() centroids = [(x, y) for x, y in zip(rt_xs, rt_ys)] for c in centroids: centroids_set.add(c) centroids = list(centroids_set) cal = imp.getCalibration() centroids = [(c[0] / cal.pixelWidth, c[1] / cal.pixelHeight) for c in centroids] print("new number of nuclei identified = {}".format(len(centroids))) roim.reset() roim.close() for idx, c in enumerate(centroids): roi = OvalRoi(c[0], c[1], 10, 10) out_imp.setRoi(roi) IJ.run(out_imp, "Set...", "value={} slice".format(idx + 1)) imp.changes = False #imp.close(); return out_imp
BS.rollingBallBackground(dapi_ip, *[a[1] for a in bkgd_sub]) if SHOW_IMAGES: dapi.updateAndDraw() # IJ.setAutoThreshold("Otsu"); # IJ.run("Convert to Mask"); dapi_ip.autoThreshold() dapi.setProcessor(dapi_ip.convertToByteProcessor(False)) dapi_ip = dapi.getProcessor() # IJ.run("Watershed"); EDM().toWatershed(dapi_ip) dapi_ip.invert() # IJ.run("Analyze Particles...", "size=30-400 show=Masks"); pa_options = particle_analyzer(dapi.getCalibration().pixelWidth) PA = ParticleAnalyzer(*[a[1] for a in pa_options]) PA.analyze(dapi, dapi_ip) if SHOW_IMAGES: dapi.updateAndDraw() IJ.save(dapi, savename(stack)) dapi.close() rename_file(progress_name, done_name) print 'done'
# 1. options (could be SHOW_ROI_MASKS, SHOW_OUTLINES, SHOW_MASKS, SHOW_NONE, ADD_TO_MANAGER, and others; combined with bitwise-or) # 2. measurement options (see [http://imagej.net/developer/api/ij/measure/Measurements.html Measurements]) # 3. a ResultsTable to store the measurements # 4. The minimum size of a particle to consider for measurement # 5. The maximum size (idem) # 6. The minimum circularity of a particle # 7. The maximum circularity minSize = 30.0 maxSize = 10000.0 opts = ParticleAnalyzer.EXCLUDE_EDGE_PARTICLES | ParticleAnalyzer.SHOW_OVERLAY_OUTLINES print(opts) meas = Measurements.AREA | Measurements.MEAN | Measurements.CENTER_OF_MASS print(meas) pa = ParticleAnalyzer(opts, meas, results_table, minSize, maxSize) # pa.setHideOutputImage(False) pa.setRoiManager(roim) if pa.analyze(imp_work): imp_out = pa.getOutputImage() # imp_out.show() roim.runCommand(blobs, "Show All with labels") blobs.show() results_table.show("Results") roim.show() print "All ok" else: print "There was a problem in analyzing", blobs # The measured areas are listed in the first column of the results table, as a float array: areas = results_table.getColumn(0)
import ij from ij import IJ import ij.plugin import ij.gui import ij.measure from ij.plugin.filter import ParticleAnalyzer as PA # Make the background black...I'm not sure why it doesn't do this automatically! IJ.run("Options...", "iterations=1 black count=1") options = PA.FOUR_CONNECTED + \ PA.INCLUDE_HOLES + \ PA.SHOW_OUTLINES rt = ij.measure.ResultsTable() analyzer = PA(options, PA.AREA, rt, 0, 10**9) image = IJ.getImage() analyzer.analyze(image) #IJ.run("Analyze Particles...", "include add slice");
def process(subFolder, outputDirectory, filename): imp = IJ.openImage(inputDirectory + subFolder + '/' + filename) imp.show() IJ.run( imp, "Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=0.8777017 pixel_height=0.8777017 voxel_depth=25400.0508001" ) ic = ImageConverter(imp) dup = imp.duplicate() dup_title = dup.getTitle() ic.convertToGray8() imp.updateAndDraw() IJ.run("Threshold...") IJ.setThreshold(218, 245) IJ.run(imp, "Convert to Mask", "") rm = RoiManager() imp.getProcessor().setThreshold(0, 0, ImageProcessor.NO_LUT_UPDATE) boundroi = ThresholdToSelection.run(imp) rm.addRoi(boundroi) imp.changes = False imp.close() images = [None] * 5 intensities = [None] * 5 blobsarea = [None] * 5 blobsnuclei = [None] * 5 cells = [None] * 5 bigareas = [None] * 5 IJ.run(dup, "Colour Deconvolution", "vectors=[H DAB]") images[0] = getImage(dup_title + "-(Colour_1)") images[1] = getImage(dup_title + "-(Colour_2)") images[2] = getImage(dup_title + "-(Colour_3)") images[2].close() for chan in channels: v, x = chan imp = images[x] imp.show() for roi in rm.getRoiManager().getRoisAsArray(): imp.setRoi(roi) stats = imp.getStatistics(Measurements.MEAN | Measurements.AREA) intensities[x] = stats.mean bigareas[x] = stats.area rm.runCommand(imp, "Show None") rm.close() # Opens the ch00 image and sets default properties imp = images[0].duplicate() IJ.run( imp, "Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=0.8777017 pixel_height=0.8777017 voxel_depth=25400.0508001" ) # Sets the threshold and watersheds. for more details on image processing, see https://imagej.nih.gov/ij/developer/api/ij/process/ImageProcessor.html imp.show() setTempCurrentImage(imp) ic = ImageConverter(imp) imp.updateAndDraw() IJ.run(imp, "Gaussian Blur...", "sigma=" + str(blur)) imp.updateAndDraw() imp.show() IJ.run("Threshold...") IJ.setThreshold(30, lowerBounds[0]) if displayImages: imp.show() WaitForUserDialog( "Title", "Adjust threshold for nuclei. Current region is: " + region).show() IJ.run(imp, "Convert to Mask", "") # Counts and measures the area of particles and adds them to a table called areas. Also adds them to the ROI manager table = ResultsTable() roim = RoiManager() pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA, table, 5, 9999999999999999, 0.05, 1.0) pa.setHideOutputImage(True) imp = IJ.getImage() # imp.getProcessor().invert() pa.analyze(imp) imp.changes = False imp.close() areas = table.getColumn(0) # This loop goes through the remaining channels for the other markers, by replacing the ch00 at the end with its corresponding channel # It will save all the area fractions into a 2d array called areaFractionsArray areaFractionsArray = [None] * 5 maxThresholds = [] for chan in channels: v, x = chan # Opens each image and thresholds imp = images[x] IJ.run( imp, "Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=0.8777017 pixel_height=0.8777017 voxel_depth=25400.0508001" ) imp.show() setTempCurrentImage(imp) ic = ImageConverter(imp) ic.convertToGray8() imp.updateAndDraw() rm.runCommand(imp, "Show None") rm.runCommand(imp, "Show All") rm.runCommand(imp, "Show None") imp.show() IJ.selectWindow(imp.getTitle()) IJ.run("Threshold...") IJ.setThreshold(20, lowerBounds[x]) if displayImages: WaitForUserDialog( "Title", "Adjust threshold for " + v + ". Current region is: " + region).show() ip = imp.getProcessor() maxThresholds.append(ip.getMaxThreshold()) IJ.run(imp, "Convert to Mask", "") # Measures the area fraction of the new image for each ROI from the ROI manager. areaFractions = [] for roi in roim.getRoiManager().getRoisAsArray(): imp.setRoi(roi) stats = imp.getStatistics(Measurements.AREA_FRACTION) areaFractions.append(stats.areaFraction) # Saves the results in areaFractionArray areaFractionsArray[x] = areaFractions roim.close() for chan in channels: v, x = chan imp = images[x] imp.deleteRoi() imp.updateAndDraw() setTempCurrentImage(imp) roim = RoiManager() pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA, table, 15, 9999999999999999, 0.2, 1.0) pa.analyze(imp) blobs = [] cell = [] for roi in roim.getRoiManager().getRoisAsArray(): imp.setRoi(roi) stats = imp.getStatistics(Measurements.AREA) blobs.append(stats.area) if stats.area > tooSmallThresholdDAB and stats.area < tooBigThresholdDAB: cell.append(stats.area) blobsarea[x] = sum(blobs) blobsnuclei[x] = len(blobs) cells[x] = len(cell) imp.changes = False imp.close() roim.reset() roim.close() # Creates the summary dictionary which will correspond to a single row in the output csv, with each key being a column summary = {} summary['Image'] = filename summary['Directory'] = subFolder # Adds usual columns summary['size-average'] = 0 summary['#nuclei'] = 0 summary['all-negative'] = 0 summary['too-big-(>' + str(tooBigThreshold) + ')'] = 0 summary['too-small-(<' + str(tooSmallThreshold) + ')'] = 0 # Creates the fieldnames variable needed to create the csv file at the end. fieldnames = [ 'Directory', 'Image', 'size-average', 'too-big-(>' + str(tooBigThreshold) + ')', 'too-small-(<' + str(tooSmallThreshold) + ')', '#nuclei', 'all-negative' ] for row in info: if row['Animal ID'] == filename.replace('s', '-').replace( 'p', '-').split('-')[0]: for key, value in row.items(): fieldnames.insert(0, key) summary[key] = value # Adds the columns for each individual marker (ignoring Dapi since it was used to count nuclei) summary["tissue-area"] = bigareas[0] fieldnames.append("tissue-area") for chan in channels: v, x = chan summary[v + "-HEMO-cells"] = 0 fieldnames.append(v + "-HEMO-cells") summary[v + "-intensity"] = intensities[x] fieldnames.append(v + "-intensity") summary[v + "-area"] = blobsarea[x] fieldnames.append(v + "-area") summary[v + "-area/tissue-area"] = blobsarea[x] / bigareas[0] fieldnames.append(v + "-area/tissue-area") summary[v + "-particles"] = blobsnuclei[x] fieldnames.append(v + "-particles") summary[v + "-cells"] = cells[x] fieldnames.append(v + "-cells") summary[v + "-particles/tissue-area"] = blobsnuclei[x] / bigareas[0] fieldnames.append(v + "-particles/tissue-area") fieldnames.append(v + "-HEMO-Cells/tissue-area") # Adds the column for colocalization between first and second marker if len(channels) > 2: summary[channels[1][0] + '-' + channels[2][0] + '-positive'] = 0 fieldnames.append(channels[1][0] + '-' + channels[2][0] + '-positive') # Adds the columns for colocalization between all three markers if len(channels) > 3: summary[channels[1][0] + '-' + channels[3][0] + '-positive'] = 0 summary[channels[2][0] + '-' + channels[3][0] + '-positive'] = 0 summary[channels[1][0] + '-' + channels[2][0] + '-' + channels[3][0] + '-positive'] = 0 fieldnames.append(channels[1][0] + '-' + channels[3][0] + '-positive') fieldnames.append(channels[2][0] + '-' + channels[3][0] + '-positive') fieldnames.append(channels[1][0] + '-' + channels[2][0] + '-' + channels[3][0] + '-positive') # Loops through each particle and adds it to each field that it is True for. areaCounter = 0 for z, area in enumerate(areas): if area > tooBigThreshold: summary['too-big-(>' + str(tooBigThreshold) + ')'] += 1 elif area < tooSmallThreshold: summary['too-small-(<' + str(tooSmallThreshold) + ')'] += 1 else: summary['#nuclei'] += 1 areaCounter += area temp = 0 for chan in channels: v, x = chan if areaFractionsArray[x][z] > areaFractionThreshold[0]: summary[chan[0] + '-HEMO-cells'] += 1 if x != 0: temp += 1 if temp == 0: summary['all-negative'] += 1 if len(channels) > 2: if areaFractionsArray[1][z] > areaFractionThreshold[1]: if areaFractionsArray[2][z] > areaFractionThreshold[2]: summary[channels[1][0] + '-' + channels[2][0] + '-positive'] += 1 if len(channels) > 3: if areaFractionsArray[1][z] > areaFractionThreshold[1]: if areaFractionsArray[3][z] > areaFractionThreshold[3]: summary[channels[1][0] + '-' + channels[3][0] + '-positive'] += 1 if areaFractionsArray[2][z] > areaFractionThreshold[2]: if areaFractionsArray[3][z] > areaFractionThreshold[3]: summary[channels[2][0] + '-' + channels[3][0] + '-positive'] += 1 if areaFractionsArray[1][z] > areaFractionThreshold[1]: summary[channels[1][0] + '-' + channels[2][0] + '-' + channels[3][0] + '-positive'] += 1 # Calculate the average of the particles sizes for chan in channels: v, x = chan summary[v + "-cells/tissue-area"] = summary[v + "-cells"] / bigareas[0] if float(summary['#nuclei']) > 0: summary['size-average'] = round(areaCounter / summary['#nuclei'], 2) if displayImages: fieldnames = ["Directory", "Image"] for chan in channels: v, x = chan summary[v + "-threshold"] = maxThresholds[x] fieldnames.append(v + "-threshold") allMaxThresholds[v + "-" + region].append(maxThresholds[x]) # Opens and appends one line on the final csv file for the subfolder (remember that this is still inside the loop that goes through each image) with open(outputName, 'a') as csvfile: writer = csv.DictWriter(csvfile, fieldnames=fieldnames, extrasaction='ignore', lineterminator='\n') if os.path.getsize(outputName) < 1: writer.writeheader() writer.writerow(summary)
def processImages(cfg, wellName, wellPath, images): stats = [[[dict() for t in range(cfg.getValue(ELMConfig.numT))] for z in range(cfg.getValue(ELMConfig.numZ))] for c in range(cfg.getValue(ELMConfig.numChannels))] times = {} for c in range(0, cfg.getValue(ELMConfig.numChannels)): chanStr = 'ch%(channel)02d' % {"channel" : c}; chanName = cfg.getValue(ELMConfig.chanLabel)[c] # Set some config based upon channel if (cfg.getValue(ELMConfig.chanLabel)[c] in cfg.getValue(ELMConfig.chansToSkip)): continue if (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.BRIGHTFIELD): minCircularity = 0.001 # We want to identify one big cell ball, so ignore small less circular objects if cfg.params[ELMConfig.imgType] == "png": minSize = 5; else: minSize = 500 elif (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.BLUE) \ or (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.RED) \ or (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.GREEN): # minCircularity = 0.001 minSize = 5 elif (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.YELLOW): minCircularity = 0.001 minSize = 5 # Process images in Z stack for z in range(0, cfg.getValue(ELMConfig.numZ)): zStr = cfg.getZStr(z); for t in range(0, cfg.getValue(ELMConfig.numT)): tStr = cfg.getTStr(t) if (cfg.getValue(ELMConfig.imgType) == "png"): # Brightfield uses the whole iamge if (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.BRIGHTFIELD): currIP = IJ.openImage(images[c][z][t][0]) else: # otherwise, we'll plit off channels chanIdx = 2 if (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.RED): chanIdx = 0 elif (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.GREEN): chanIdx = 1; img = IJ.openImage(images[c][z][t][0]) imgChanns = ChannelSplitter.split(img); img.close() currIP = imgChanns[chanIdx]; else: currIP = IJ.openImage(images[c][z][t][0]) resultsImage = currIP.duplicate() dbgOutDesc = wellName + "_" + zStr + "_" + chanStr + "_" + tStr if (cfg.getValue(ELMConfig.numT) > 1): outputPath = os.path.join(wellPath, "images") if not os.path.exists(outputPath): os.makedirs(outputPath) else: outputPath = wellPath if cfg.getValue(ELMConfig.debugOutput): WindowManager.setTempCurrentImage(currIP) IJ.saveAs('png', os.path.join(outputPath, "Orig_" + dbgOutDesc + ".png")) # We need to get to a grayscale image, which will be done differently for different channels startTime = time.time() currIP = ELMImageUtils.getThresholdedMask(currIP, c, z, t, chanName, cfg, outputPath, dbgOutDesc) endTime = time.time() if not 'grayscale' in times: times['grayscale'] = [] times['grayscale'].append(endTime-startTime) if (not currIP): resultsImage.close() stats[c][z][t][ELMConfig.UM_AREA] = [] continue startTime = time.time() # Create a table to store the results table = ResultsTable() # Create a hidden ROI manager, to store a ROI for each blob or cell #roim = RoiManager(True) # Create a ParticleAnalyzer measurements = Measurements.AREA + Measurements.MEAN + Measurements.STD_DEV + Measurements.MIN_MAX + Measurements.CENTROID + Measurements.RECT + Measurements.ELLIPSE paFlags = ParticleAnalyzer.IN_SITU_SHOW | ParticleAnalyzer.SHOW_MASKS | ParticleAnalyzer.CLEAR_WORKSHEET pa = ParticleAnalyzer(paFlags, measurements, table, minSize, Double.POSITIVE_INFINITY, minCircularity, 1.0) #pa.setHideOutputImage(True) # The Result image is copied when CurrIP can still have calibration from loading # We want the output to be in terms of pixels, for ease of use, so adjust calibration resultsImage.setCalibration(currIP.getCalibration()) Analyzer.setRedirectImage(resultsImage) if not pa.analyze(currIP): print "There was a problem in analyzing", currIP endTime = time.time() if not 'pa' in times: times['pa'] = [] times['pa'].append(endTime-startTime) #for i in range(0, roim.getCount()) : # r = roim.getRoi(i); # r.setColor(Color.red) # r.setStrokeWidth(2) # The measured areas are listed in the first column of the results table, as a float array: newAreas = [] maxArea = 0 if table.getColumn(ResultsTable.AREA): for pixArea in table.getColumn(ResultsTable.AREA): a = pixArea * cfg.getValue(ELMConfig.pixelHeight) * cfg.getValue(ELMConfig.pixelWidth) newAreas.append(a) if (a > maxArea): maxArea = a # Threshold areas idxToRemove = set() if cfg.hasValue(ELMConfig.areaMaxPercentThreshold): areaPercentThresh = cfg.getValue(ELMConfig.areaMaxPercentThreshold) for i in range(0,len(newAreas)): if newAreas[i] < (areaPercentThresh * maxArea): idxToRemove.add(i) if cfg.hasValue(ELMConfig.areaAbsoluteThreshold): areaAbsoluteThresh = cfg.getValue(ELMConfig.areaAbsoluteThreshold) for i in range(0,len(newAreas)): if newAreas[i] < areaAbsoluteThresh: idxToRemove.add(i) for i in sorted(idxToRemove, reverse=True): del newAreas[i] stats[c][z][t][ELMConfig.UM_AREA] = newAreas centroidX = [] centroidY = [] roiX = [] roiY = [] roiWidth = [] roiHeight = [] rArea = [] # Store all of the other data for col in range(0,table.getLastColumn()): newData = table.getColumn(col) if not newData is None: if col == ResultsTable.X_CENTROID: for idx in idxToRemove: centroidX.append(newData[idx]) if col == ResultsTable.Y_CENTROID: for idx in idxToRemove: centroidY.append(newData[idx]) if col == ResultsTable.ROI_X: for idx in idxToRemove: roiX.append(int(newData[idx])) if col == ResultsTable.ROI_Y: for idx in idxToRemove: roiY.append(int(newData[idx])) if col == ResultsTable.ROI_WIDTH: for idx in idxToRemove: roiWidth.append(int(newData[idx])) if col == ResultsTable.ROI_HEIGHT: for idx in idxToRemove: roiHeight.append(int(newData[idx])) if col == ResultsTable.AREA: for idx in idxToRemove: rArea.append(newData[idx]) for i in sorted(idxToRemove, reverse=True): del newData[i] stats[c][z][t][table.getColumnHeading(col)] = newData IJ.saveAs('png', os.path.join(outputPath, "PreFiltered_Segmentation_" + dbgOutDesc + "_particles.png")) # Remove the segmentation masks for the objects removed currProcessor = currIP.getProcessor() ff = FloodFiller(currProcessor) currIP.getProcessor().setValue(0) calib = resultsImage.getCalibration() sortedAreaIndices = [i[0] for i in sorted(enumerate(rArea), key=lambda x:x[1])] for idx in range(0, len(sortedAreaIndices)): i = sortedAreaIndices[idx] centX = int(calib.getRawX(centroidX[i])) centY = int(calib.getRawY(centroidY[i])) # Since the centroid isn't guaranteed to be part of the blob # search around until an active pixel is found found = False halfWidth = min([roiHeight[i], roiWidth[i]]) for offset in range(0,halfWidth): if found: break for x in range(centX-offset,centX+offset+1): if found: break for y in range(centY-offset,centY+offset+1): if not currProcessor.getPixel(x,y) == 0x0: found = True finalX = x finalY = y break if not found: print "\t\tZ = " + str(z) + ", T = " + str(t) + ", chan " + chanName + ": ERROR: Never found active pixel for filtered blob, centroid: " + str(centX) + ", " + str(centY) else: currProcessor.setRoi(roiX[i], roiY[i], roiWidth[i], roiHeight[i]) ff.fill8(finalX,finalY) #IJ.saveAs('png', os.path.join(outputPath, "Segmentation_" + dbgOutDesc + "_" + str(idx) + ".png")) #outImg = pa.getOutputImage() IJ.saveAs('png', os.path.join(outputPath, "Segmentation_" + dbgOutDesc + "_particles.png")) if cfg.hasValue(ELMConfig.createSegMask) and cfg.getValue(ELMConfig.createSegMask) == True: # Create segmentation mask segMask = currIP.duplicate() segMask.setTitle("SegMask_" + dbgOutDesc) # Iterate by smallest area first # We are more likely to correctly label small areas if len(newAreas) > 0: segProcessor = segMask.getProcessor() if (len(newAreas) > 255): segProcessor = segProcessor.convertToShort(True) segMask.setProcessor(segProcessor) ff = FloodFiller(segProcessor) sortedAreaIndices = [i[0] for i in sorted(enumerate(stats[c][z][t]['Area']), key=lambda x:x[1])] for idx in range(0, len(sortedAreaIndices)): row = sortedAreaIndices[idx] centX = int(stats[c][z][t]['X'][row]) centY = int(stats[c][z][t]['Y'][row]) roiX = int(stats[c][z][t]['BX'][row]) roiY = int(stats[c][z][t]['BY'][row]) roiWidth = int(stats[c][z][t]['Width'][row]) roiHeight = int(stats[c][z][t]['Height'][row]) area = stats[c][z][t]['Area'][row] halfRoiHeight = roiHeight/2 + 1 halfRoiWidth = roiWidth/2 + 1 # Since the centroid isn't guaranteed to be part of the blob # search around until an active pixel is found found = False for xOffset in range(0,halfRoiWidth): if found: break for yOffset in range(0, halfRoiHeight): if found: break for x in range(centX-xOffset,centX+xOffset+1): if found: break for y in range(centY-yOffset,centY+yOffset+1): # original image and this image for masked pixel # By checking original image, we avoid confusion with a label of 255 if segProcessor.getPixel(x,y) == 255 and currProcessor.getPixel(x,y) == 255: found = True finalX = x finalY = y break if not found: print "\t\tZ = " + str(z) + ", T = " + str(t) + ", chan " + chanName + ": ERROR: Never found active pixel for seg mask, centroid, roi, area (px): " \ + str(centX) + ", " + str(centY) + ", " + str(roiX) + ", " + str(roiY) + ", " + str(roiWidth) + ", " + str(roiHeight) + ", " + str(area) else: segProcessor.setRoi(roiX, roiY, roiWidth, roiHeight) segProcessor.setColor(row + 1) ff.fill8(finalX,finalY) lut = LutLoader.openLut(cfg.getValue(ELMConfig.lutPath)) segMask.setLut(lut) WindowManager.setTempCurrentImage(segMask); IJ.saveAs('png', os.path.join(outputPath, "SegMask_" + dbgOutDesc + "_particles.png")) startTime = time.time() width = currIP.getWidth(); height = currIP.getHeight(); overlayImage = resultsImage.duplicate() overlayImage.setTitle("Overlay_" + dbgOutDesc + "_particles") if not overlayImage.getType() == ImagePlus.COLOR_RGB: imgConvert = ImageConverter(overlayImage) imgConvert.convertToRGB() overlayProcessor = overlayImage.getProcessor() currProcessor = currIP.getProcessor() if (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.BRIGHTFIELD): maskColor = 0x0000ff00 elif (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.YELLOW): maskColor = 0x000000ff elif (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.RED): maskColor = 0x0000ff00 elif (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.GREEN): maskColor = 0x00ff0000 elif (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.BLUE): maskColor = 0x00ffff00 for x in range(0, width): for y in range(0,height): currPix = currProcessor.getPixel(x,y); if not currPix == 0x00000000: overlayProcessor.putPixel(x, y, maskColor) endTime = time.time() if not 'overlay' in times: times['overlay'] = [] times['overlay'].append(endTime-startTime) WindowManager.setTempCurrentImage(overlayImage); IJ.saveAs('png', os.path.join(outputPath, "Overlay_" + dbgOutDesc + "_particles.png")) #currIP.hide() currIP.close() resultsImage.close() timesAvg = {} for key in times: timeList = times[key] timesAvg[key] = sum(timeList) / len(timeList); print("processImage times " + str(timesAvg)) return stats
from java.lang import Double imp = IJ.getImage() # Create a table to store the results table = ResultsTable() # Create a hidden ROI manager, to store a ROI for each blob or cell roim = RoiManager(True) # Create a ParticleAnalyzer, with arguments: # 1. options (could be SHOW_ROI_MASKS, SHOW_OUTLINES, SHOW_MASKS, SHOW_NONE, ADD_TO_MANAGER, and others; combined with bitwise-or) # 2. measurement options (see [http://rsb.info.nih.gov/ij/developer/api/ij/measure/Measurements.html Measurements]) # 3. a ResultsTable to store the measurements # 4. The minimum size of a particle to consider for measurement # 5. The maximum size (idem) # 6. The minimum circularity of a particle # 7. The maximum circularity pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA + Measurements.CENTER_OF_MASS + Measurements.SHAPE_DESCRIPTORS + Measurements.INTEGRATED_DENSITY, table, 0, Double.POSITIVE_INFINITY, 0.0, 1.0) pa.setHideOutputImage(True) if pa.analyze(imp): print "All ok" table.show("foooo"); else: print "There was a problem in analyzing", blobs
print(dupes) for dupe in dupes: # get centroidys rt = ResultsTable(); #rm = RoiManager.getInstance(); #print(rm) rm = RoiManager(False); pa = ParticleAnalyzer((ParticleAnalyzer.ADD_TO_MANAGER | ParticleAnalyzer.SHOW_MASKS), (Measurements.CENTROID | Measurements.STACK_POSITION), rt, 500, 30000, 0.0, 1.0) pa.setHideOutputImage(False) keep_rois = []; pa.analyze(imp); IJ.run("Set Measurements...", "centroid redirect=None decimal=3"); frames = imp.getNFrames(); for fridx in range(0, frames): rt.reset(); imp.setSliceWithoutUpdate(fridx + 1); ip = imp.getProcessor(); if not pa.analyze(imp, ip): raise Exception("something went wrong analysing particles!") rt.show("centroids"); rm = RoiManager.getInstance(); if rm.getCount() > 0: rois = rm.getRoisAsArray(); centroidsx = rt.getColumn(rt.getColumnIndex('X')); centroidsy = rt.getColumn(rt.getColumnIndex('Y'));
#Threshold and watershed IJ.run(channel, "Convert to Mask", "") IJ.run(channel, "Watershed", "") IJ.run("Set Measurements...", "area mean limit display redirect=None decimal=1"); table = ResultsTable() roim = RoiManager(True) ParticleAnalyzer.setRoiManager(roim) #Analyses particles: finds all the objects that match criteria pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER | ParticleAnalyzer.EXCLUDE_EDGE_PARTICLES, Measurements.AREA, table, minimum_size[i], maximum_size[i], 0.1, 1.0) pa.setHideOutputImage(True) pa.analyze(channel) if thresholdMode: happy=False while(happy==False): IJ.run("Threshold...") WaitForUserDialog("Title", "Adjust threshold for " + color[i]).show() summary[color[i] + "-threshold-used"] = ImageProcessor.getMinThreshold(channel.getProcessor()) channel.show() summary[color[i] + "-threshold-used"] = ImageProcessor.getMinThreshold(channel.getProcessor()) copy=channel.duplicate() copy.show()
if not rm: rm = RoiManager() else: rm.reset() #IJ.run(imp,"Analyze Particles...", "size=112-Infinity exclude add") rt=ResultsTable() pa=ParticleAnalyzer(EXCLUDE_EDGE_PARTICLES | ADD_TO_MANAGER, 0, rt, 112/4, 200, 0.0, 1.0) pa.analyze(imp) # time.sleep(2) print 'Size of results: ',rt.size() # rm.runCommand("select","all") # rm.runCommand("Fill","3") save_path=saving_dir+"\\mask_%s" % (image[image.rindex('\\')+1:]) # print(save_path) impMask = IJ.createImage("Mask", "8-bit grayscale-mode", imp.getWidth(), imp.getHeight(), imp.getNChannels(), imp.getNSlices(), imp.getNFrames()) impMask.show() IJ.setForegroundColor(255, 255, 255) rm.runCommand(impMask,"Deselect") rm.runCommand(impMask,"Draw") if doFileSave and FileSaver(impMask).saveAsTiff(save_path):
def __calRois(self, imp, indice) : """ Returns the ROIs of a slice given (identified with its n°) in a stack """ ##imp=self.__dictImages[nameimages] # IL FAUT RÉCUPÉRER L'IMAGE DU STACK !!!!! #if self.__batch : imp.hide() #else : imp.show() #imp.hide() imp.show() if self.__batch : imp.hide() imp.setSlice(indice) imp.killRoi() ip = imp.getProcessor() bs=BackgroundSubtracter() #if str(self.__subback) == "0" or str(self.__subback) == "1" : self.__subback = bool(int(self.__subback)) #if self.__subback == True : IJ.run(imp, "Subtract Background...", "rolling="+str(self.__radius)+" light") if self.__subback == True : bs.rollingBallBackground(ip, self.__radius, False, True, False, True, False) if self.__runmacro : imp.show() imp.setSlice(indice) imp.updateAndDraw() IJ.runMacroFile(self.__macropath, imp.getTitle()) imp.updateAndDraw() #if str(self.__manthresh) == "0" or str(self.__manthresh) == "1" : self.__manthresh = bool(int(self.__manthresh)) #if self.__manthresh : IJ.setThreshold(imp, self.__minthr, self.__maxthr) if self.__manthresh : ip.setThreshold(self.__minthr, self.__maxthr, ImageProcessor.RED_LUT) else : self.__setThreshold(imp, indice) rt=ResultsTable() pa1=ParticleAnalyzer(ParticleAnalyzer.SHOW_MASKS+ParticleAnalyzer.EXCLUDE_EDGE_PARTICLES , Measurements.AREA, rt, self.__minArea, self.__maxArea, self.__minCirc, self.__maxCirc) pa1.setHideOutputImage(True) pa1.analyze(imp) masks=pa1.getOutputImage() masks.getProcessor().erode() masks.getProcessor().dilate() masks.getProcessor().invertLut() masks.getProcessor().threshold(1) rm = RoiManager.getInstance() if (rm==None): rm = RoiManager() rm.runCommand("reset") #rm.hide() pa2=ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER+ParticleAnalyzer.CLEAR_WORKSHEET+ParticleAnalyzer.EXCLUDE_EDGE_PARTICLES , Measurements.AREA, rt, self.__minArea, self.__maxArea, self.__minCirc, self.__maxCirc) pa2.analyze(masks) masks.close() temparray=rm.getRoisAsArray() for r in temparray : tempnameroi=r.getName() r.setPosition(indice) r.setName(str(indice)+"-"+tempnameroi) r.setStrokeWidth(1) if len(self.__params) > 0 : for k in self.__params: #if k[0]=="Area": self.__minArea, self.__maxArea = str(k[1]), str(k[2]) if k[0]=="Area": self.__minArea, self.__maxArea = k[1], k[2] for k in self.__params: #if k[0]=="Circ": self.__minCirc, self.__maxCirc = str(k[1]), str(k[2]) if (k[0]=="Circ") and k[3] : self.__minCirc, self.__maxCirc = k[1], k[2] else : self.__minCirc, self.__maxCirc = 0, 1 self.__rr.setRoisarray(temparray, imp) self.__rr.setRange(indice, self.__params) return self.__rr.includeRois else : return temparray
def updatepressed(event): self.__image=IJ.getImage() rm = RoiManager.getInstance() if (rm==None): rm = RoiManager() rm.runCommand("reset") self.__image.killRoi() IJ.run("Threshold...") IJ.setAutoThreshold(self.__image, "MaxEntropy") rt=ResultsTable() pa=ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER+ParticleAnalyzer.CLEAR_WORKSHEET , Measurements.AREA+Measurements.ELLIPSE+Measurements.MEAN, rt, 0.00, 10000.00, 0.00, 1.00) pa.analyze(self.__image) self.__roisArray=[] self.__roisArray=rm.getRoisAsArray() #for i in range(rm.getCount()) : # rm.select(i) # rm.runCommand("Set Color", "0000FF", 2) IJ.resetThreshold(self.__image) rt.show("tempRT") areas=rt.getColumn(ResultsTable.AREA) means=rt.getColumn(ResultsTable.MEAN) majors=rt.getColumn(ResultsTable.MAJOR) minors=rt.getColumn(ResultsTable.MINOR) #print 0 if self.__slidersDict["Area_max"].getMaximum() < int(max(areas)+1): # print 1 self.__slidersDict["Area_max"].setMaximum(int(max(areas))+1) if self.__slidersDict["Area_min"].getMaximum() < int(max(areas)+1): # print 2 self.__slidersDict["Area_min"].setMaximum(int(max(areas))+1) if self.__slidersDict["Mean_max"].getMaximum() < int(max(means)+1): # print 3 self.__slidersDict["Mean_max"].setMaximum(int(max(means))+1) if self.__slidersDict["Mean_min"].getMaximum() < int(max(means)+1): # print 4 self.__slidersDict["Mean_min"].setMaximum(int(max(means))+1) if self.__slidersDict["Major_max"].getMaximum() < int(max(majors)): # print 5 self.__slidersDict["Major_max"].setMaximum(int(max(majors))+1) if self.__slidersDict["Major_min"].getMaximum() < int(max(majors)+1): # print 6 self.__slidersDict["Major_min"].setMaximum(int(max(majors))+1) if self.__slidersDict["Minor_max"].getMaximum() < int(max(minors)+1): # print 7 self.__slidersDict["Minor_max"].setMaximum(int(max(minors))+1) if self.__slidersDict["Minor_min"].getMaximum() < int(max(minors)+1): # print 8 self.__slidersDict["Minor_min"].setMaximum(int(max(minors))+1) if self.__slidersDict["AR_max"].getMaximum() < int((max(majors)+1)/min(minors)+1): # print 9 self.__slidersDict["AR_max"].setMaximum(int((max(majors)+1)/(min(minors)))) if self.__slidersDict["AR_min"].getMaximum() < int((max(majors)+1)/min(minors)): # print 10 self.__slidersDict["AR_min"].setMaximum(int((max(majors)+1)/(min(minors)))) #print 11 for sb in self.__slidersDict.values(): sb.repaint() #rm.runCommand("reset") #temprois=self.getIncludeRois() #IJ.run(self.__image, "Remove Overlay", "") #o=Overlay() #for roi in temprois: # o.addElement(roi) #self.__image.killRoi() #self.__image.setOverlay(o) self.__image.updateAndDraw()
imp = IJ.openImage(binimgpath) # paOpt = PA.CLEAR_WORKSHEET +\ paOpt = PA.SHOW_OUTLINES + PA.EXCLUDE_EDGE_PARTICLES # +\ # PA.INCLUDE_HOLES #+ \ # PA.SHOW_RESULTS measOpt = PA.AREA + PA.CENTROID + PA.SLICE # + PA.SHAPE_DESCRIPTORS + PA.INTEGRATED_DENSITY rt = ResultsTable() MINSIZE = 2 MAXSIZE = 10000 pa = PA(paOpt, measOpt, rt, MINSIZE, MAXSIZE) pa.setHideOutputImage(True) # pa.processStack = True for i in range(imp.getStackSize()): imp.setSlice(i + 1) pa.analyze(imp) # pa.getOutputImage().show() rt.show("cells") # rt = ResultsTable.open2(path) dotlinker = DotLinker(loadmethod, rt) # better there is a constructor also with linkkost function object. dotlinker.setTrajectoryThreshold(5) dotlinker.setShowTrackTable(False) # dotlinker = DotLinker(loadmethod) linkcostfunction = dotlinker.setLinkCostFunction(lcAD) linkcostfunction.setParameters(5.0, 2.0) rtout = dotlinker.doLinking(False) rtout.show("Tracks") vd = ViewDynamicsArea(imp)
summary[color[i] + "-threshold-used"] = ImageProcessor.getMinThreshold(channel.getProcessor()) #Threshold and watershed IJ.run(channel, "Convert to Mask", "") IJ.run(channel, "Watershed", "") table = ResultsTable() roim = RoiManager(True) ParticleAnalyzer.setRoiManager(roim) #Analyses particles: finds all the objects that match criteria pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER | ParticleAnalyzer.EXCLUDE_EDGE_PARTICLES, Measurements.AREA, table, minimum_size, maximum_size, 0.1, 1.0) pa.setHideOutputImage(True) pa.analyze(channel) if thresholdMode: channel.show() WaitForUserDialog("Title", "Look at threshold for" + color[i]).show() #adds count to summary if table.getColumnIndex("Area") != -1: summary[color[i] + "-ROI-count"] = len(table.getColumn(table.getColumnIndex("Area"))) channel.changes = False channel.close()
def generate_background_rois(input_mask_imp, params, membrane_edges, dilations=5, threshold_method=None, membrane_imp=None): """automatically identify background region based on auto-thresholded image, existing membrane edges and position of midpoint anchor""" if input_mask_imp is None and membrane_imp is not None: segmentation_imp = Duplicator().run(membrane_imp) # do thresholding using either previous method if threhsold_method is None or using (less conservative?) threshold method if (threshold_method is None or not (threshold_method in params.listThresholdMethods())): mask_imp = make_and_clean_binary(segmentation_imp, params.threshold_method) else: mask_imp = make_and_clean_binary(segmentation_imp, threshold_method) segmentation_imp.close() else: input_mask_imp.killRoi() mask_imp = Duplicator().run(input_mask_imp) rois = [] IJ.setForegroundColor(0, 0, 0) roim = RoiManager(True) rt = ResultsTable() for fridx in range(mask_imp.getNFrames()): mask_imp.setT(fridx + 1) # add extra bit to binary mask from loaded membrane in case user refined edges... # flip midpoint anchor across the line joining the two extremes of the membrane, # and fill in the triangle made by this new point and those extremes poly = membrane_edges[fridx].getPolygon() l1 = (poly.xpoints[0], poly.ypoints[0]) l2 = (poly.xpoints[-1], poly.ypoints[-1]) M = (0.5 * (l1[0] + l2[0]), 0.5 * (l1[1] + l2[1])) Mp1 = (params.manual_anchor_midpoint[0][0] - M[0], params.manual_anchor_midpoint[0][1] - M[1]) p2 = (M[0] - Mp1[0], M[1] - Mp1[1]) new_poly_x = list(poly.xpoints) new_poly_x.append(p2[0]) new_poly_y = list(poly.ypoints) new_poly_y.append(p2[1]) mask_imp.setRoi(PolygonRoi(new_poly_x, new_poly_y, PolygonRoi.POLYGON)) IJ.run(mask_imp, "Fill", "slice") mask_imp.killRoi() # now dilate the masked image and identify the unmasked region closest to the midpoint anchor ip = mask_imp.getProcessor() dilations = 5 for d in range(dilations): ip.dilate() ip.invert() mask_imp.setProcessor(ip) mxsz = mask_imp.getWidth() * mask_imp.getHeight() pa = ParticleAnalyzer( ParticleAnalyzer.ADD_TO_MANAGER | ParticleAnalyzer.SHOW_PROGRESS, ParticleAnalyzer.CENTROID, rt, 0, mxsz) pa.setRoiManager(roim) pa.analyze(mask_imp) ds_to_anchor = [ math.sqrt((x - params.manual_anchor_midpoint[0][0])**2 + (y - params.manual_anchor_midpoint[0][1])**2) for x, y in zip( rt.getColumn(rt.getColumnIndex("X")).tolist(), rt.getColumn(rt.getColumnIndex("Y")).tolist()) ] if len(ds_to_anchor) > 0: roi = roim.getRoi(ds_to_anchor.index(min(ds_to_anchor))) rois.append(roi) else: rois.append(None) roim.reset() rt.reset() roim.close() mask_imp.close() return rois
def analyze_homogeneity(image_title): IJ.selectWindow(image_title) raw_imp = IJ.getImage() IJ.run(raw_imp, "Duplicate...", "title=Homogeneity duplicate") IJ.selectWindow('Homogeneity') hg_imp = IJ.getImage() # Get a 2D image if hg_imp.getNSlices() > 1: IJ.run(hg_imp, "Z Project...", "projection=[Average Intensity]") hg_imp.close() IJ.selectWindow('MAX_Homogeneity') hg_imp = IJ.getImage() hg_imp.setTitle('Homogeneity') # Blur and BG correct the image IJ.run(hg_imp, 'Gaussian Blur...', 'sigma=' + str(HOMOGENEITY_RADIUS) + ' stack') # Detect the spots IJ.setAutoThreshold(hg_imp, HOMOGENEITY_THRESHOLD + " dark") rm = RoiManager(True) table = ResultsTable() pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, ParticleAnalyzer.EXCLUDE_EDGE_PARTICLES, Measurements.AREA, # measurements table, # Output table 0, # MinSize 500, # MaxSize 0.0, # minCirc 1.0) # maxCirc pa.setHideOutputImage(True) pa.analyze(hg_imp) areas = table.getColumn(table.getHeadings().index('Area')) median_areas = compute_median(areas) st_dev_areas = compute_std_dev(areas, median_areas) thresholds_areas = (median_areas - (2 * st_dev_areas), median_areas + (2 * st_dev_areas)) roi_measurements = {'integrated_density': [], 'max': [], 'area': []} IJ.setForegroundColor(0, 0, 0) for roi in rm.getRoisAsArray(): hg_imp.setRoi(roi) if REMOVE_CROSS and hg_imp.getStatistics().AREA > thresholds_areas[1]: rm.runCommand('Fill') else: roi_measurements['integrated_density'].append(hg_imp.getStatistics().INTEGRATED_DENSITY) roi_measurements['max'].append(hg_imp.getStatistics().MIN_MAX) roi_measurements['integrated_densities'].append(hg_imp.getStatistics().AREA) rm.runCommand('Delete') measuremnts = {'mean_integrated_density': compute_mean(roi_measurements['integrated_density']), 'median_integrated_density': compute_median(roi_measurements['integrated_density']), 'std_dev_integrated_density': compute_std_dev(roi_measurements['integrated_density']), 'mean_max': compute_mean(roi_measurements['max']), 'median_max': compute_median(roi_measurements['max']), 'std_dev_max': compute_std_dev(roi_measurements['max']), 'mean_area': compute_mean(roi_measurements['max']), 'median_area': compute_median(roi_measurements['max']), 'std_dev_area': compute_std_dev(roi_measurements['max']), } # generate homogeinity image # calculate interpoint distance in pixels nr_point_columns = int(sqrt(len(measuremnts['mean_max']))) # TODO: This is a rough estimation that does not take into account margins or rectangular FOVs inter_point_dist = hg_imp.getWidth() / nr_point_columns IJ.run(hg_imp, "Maximum...", "radius="+(inter_point_dist*1.22)) # Normalize to 100 IJ.run(hg_imp, "Divide...", "value=" + max(roi_measurements['max'] / 100)) IJ.run(hg_imp, "Gaussian Blur...", "sigma=" + (inter_point_dist/2)) hg_imp.getProcessor.setMinAndMax(0, 255) # Create a LUT based on a predefined threshold red = zeros(256, 'b') green = zeros(256, 'b') blue = zeros(256, 'b') acceptance_threshold = HOMOGENEITY_ACCEPTANCE_THRESHOLD * 256 / 100 for i in range(256): red[i] = (i - acceptance_threshold) green[i] = (i) homogeneity_LUT = LUT(red, green, blue) hg_imp.setLut(homogeneity_LUT) return hg_imp, measuremnts
def nucleusSegmentation(imp2): """ Segmentation of nucleus image. Nucleus are selected that: 1. No overlapping with dilated regions 2. close to circular shape. Deformed nuclei are rejected. Outputs a binary image. """ #Convert to 8bit ImageConverter(imp2).convertToGray8() #blur slightly using Gaussian Blur radius = 2.0 accuracy = 0.01 GaussianBlur().blurGaussian( imp2.getProcessor(), radius, radius, accuracy) # Auto Local Thresholding imps = ALT().exec(imp2, "Bernsen", 15, 0, 0, True) imp2 = imps[0] #ParticleAnalysis 0: prefiltering by size and circularity rt = ResultsTable() paOpt = PA.CLEAR_WORKSHEET +\ PA.SHOW_MASKS +\ PA.EXCLUDE_EDGE_PARTICLES +\ PA.INCLUDE_HOLES #+ \ # PA.SHOW_RESULTS measOpt = PA.AREA + PA.STD_DEV + PA.SHAPE_DESCRIPTORS + PA.INTEGRATED_DENSITY MINSIZE = 20 MAXSIZE = 10000 pa0 = PA(paOpt, measOpt, rt, MINSIZE, MAXSIZE, 0.8, 1.0) pa0.setHideOutputImage(True) pa0.analyze(imp2) imp2 = pa0.getOutputImage() # Overwrite imp2.getProcessor().invertLut() #impNuc = imp2.duplicate() ## for the ring. impNuc = Duplicator().run(imp2) #Dilate the Nucleus Area ## this should be 40 pixels in Cihan's method, but should be smaller. #for i in range(20): # IJ.run(imp2, "Dilate", "") rf = RankFilters() rf.rank(imp2.getProcessor(), RIMSIZE, RankFilters.MAX) #Particle Analysis 1: get distribution of sizes. paOpt = PA.CLEAR_WORKSHEET +\ PA.SHOW_NONE +\ PA.EXCLUDE_EDGE_PARTICLES +\ PA.INCLUDE_HOLES #+ \ # PA.SHOW_RESULTS measOpt = PA.AREA + PA.STD_DEV + PA.SHAPE_DESCRIPTORS + PA.INTEGRATED_DENSITY rt1 = ResultsTable() MINSIZE = 20 MAXSIZE = 10000 pa = PA(paOpt, measOpt, rt1, MINSIZE, MAXSIZE) pa.analyze(imp2) #rt.show('after PA 1') #particle Analysis 2: filter nucleus by size and circularity. #print rt1.getHeadings() if (rt1.getColumnIndex('Area') > -1): q1, q3, outlier_offset = getOutlierBound(rt1) else: q1 = MINSIZE q3 = MAXSIZE outlier_offset = 0 print imp2.getTitle(), ": no Nucleus segmented,probably too many overlaps" paOpt = PA.CLEAR_WORKSHEET +\ PA.SHOW_MASKS +\ PA.EXCLUDE_EDGE_PARTICLES +\ PA.INCLUDE_HOLES #+ \ # PA.SHOW_RESULTS rt2 = ResultsTable() #pa = PA(paOpt, measOpt, rt, q1-outlier_offset, q3+outlier_offset, circq1-circoutlier_offset, circq3+circoutlier_offset) pa = PA(paOpt, measOpt, rt2, q1-outlier_offset, q3+outlier_offset, 0.8, 1.0) pa.setHideOutputImage(True) pa.analyze(imp2) impDilatedNuc = pa.getOutputImage() #filter original nucleus filteredNuc = ImageCalculator().run("AND create", impDilatedNuc, impNuc) return filteredNuc