Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
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
Exemple #4
0
    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 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 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)
Exemple #7
0
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)
Exemple #8
0
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)
Exemple #9
0
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 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)
Exemple #11
0
				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()
            dupes.append(x)
        seen[x] += 1

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();
Exemple #13
0
	binorg.show()

# Count nucleus setting
MAXSIZE = imp3.getWidth()*imp3.getHeight();
MINSIZE = 100;
#options = PA.SHOW_ROI_MASKS \
#    + PA.EXCLUDE_EDGE_PARTICLES \
#    + PA.INCLUDE_HOLES \
#    + PA.SHOW_RESULTS \

options = PA.INCLUDE_HOLES \
	+ 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))
	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
Exemple #15
0
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)
Exemple #16
0
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)
Exemple #17
0
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", "")
Exemple #18
0
    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
Exemple #19
0
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