QuPath Intro: Choose your own analysis(adventure)

Starting a project

Should you start a project?

Well, unless you want to quickly open an image and take a look at it, the answer is “almost always.” Some features will only work in projects, many scripts will only work in projects (as exported files and folders look specifically along the “project” file path). It will also allow you to quickly and uniformly apply your script/pipeline to a large set of images.
As of 0.2.0m3, some image types with multiple scenes or sub-files will only open in projects.

To start a project you will need an empty folder.

0.1.2+ - Use the Create project button in the Project tab, select your folder.

0.2.0 - Drag an empty folder into the open QuPath window

Also
0.2.0 - Drag a project folder OR *.qpproj file into an open QuPath window to open the project

Import images

Import options by version

I recommend placing the images you want to analyze within the project folder whenever possible. This makes the project as a whole more portable, as you can copy it onto the network, a USB drive, etc, and open it anywhere without disrupting the file path to the images.

0.1.2+ - Drag a single image into the QuPath window that has a project active. Or in the Project tab, click Import images which will allow you to navigate to the image location and select large numbers of images.

0.2.0 - Select and drag large numbers of images into an open QuPath project. Requires a project to be open, follow the dialog instructions after.

0.2.0 - BONUS - Use the Add images button to add entire projects, which can be used to create a massive multiproject project. You may want to familiarize yourself with adding Metadata to images through the Project tab if you do this. Also be aware that the deletion of objects or images will result in their deletion from the original project. You have not copied the files, you are referencing them.

New interface shown here:


Image provider: This can normally be left as default, though I have found that if I am SURE I want to use OpenSlide (certain NDPI files), I can save some time during the import process by pre-selecting OpenSlide, as QuPath doesn’t have to go through the process of trying and failing to open each image with BioFormats.
Set Image Type: I normally set this if I am importing a large set of images, since it will save me time in case QuPath gets it wrong for all of them. For one or two images I leave it blank as QuPath does usually get it right, and it is easy enough to change in the off chance a brightfield image is set as fluorescent.
Rotation: Mostly for rotating TMAs to the “correct” orientation. Clockwise.

For whole slide image formats, the Auto-generate pyramids setting will not matter, and for TIFF files without a pyramid, it is worth waiting for this as images will load VERY slowly and be clunky to use without it.

Never tried importing objects from an image file, so not sure of cases where this would be used.

Once you import an image, a project file (project.qpproj) will be generated in the project folder. You can rename this file, though in newer versions of QuPath the File->Recent projects makes use of the folder name rather than the project name, so this is not as important.

Project files themselves are the .qpproj file within the originally empty project folder. This is what you would run, or drag into an open QuPath window, or open through the file menu. You can also drag the entire project folder itself into QuPath to save a step. The data files are stored in the “data” folder, and are named based on their association with an image file in 0.1.2. In 0.2.0 each data file is stored within a numbered subfolder, and it can be tricky to figure out which image goes with which data file.
The qpdata files store all of the objects you see in the overlays (annotations, detections) in a Java serialized object. If you are doing something destructive with your data, it is sometimes a good idea to back this folder up somewhere else so you can return to a previous step if you don’t like the results after a “Run for project.”

In 0.2.0 you will get a “classifiers” folder by default, which will, at least, contain a classes.json file with a list of your current classes as seen in the Annotations tab.

Additional folders can be created (like the Images folder mentioned above) without interfering with the project itself, though I don’t recommend editing file/folder names generated by QuPath until you are comfortable with how the project structure as a whole works.

You now have a project and area ready to either learn more about how objects in QuPath work, or jump into your analysis.

Objects in QuPath

Images in QuPath are not modified, basically ever, but data objects of two general types are created, annotations, and detections. These objects are not “burned in” to the image, but are instead visualized as an overlay. The objects themselves contain data relevant to the pixels “below” them.

Annotations are intended as large, generally simple, structures and have measurements that update automatically as they are changed. This makes them slower to render and handle in terms of analysis, and having many annotations or highly detailed annotations (with a lot of vertices) can lead to massive slowdowns. Detections are generally smaller, simple objects that are not structurally modifiable, but the rigidity of their data means the program can support many more of them. These are general rules, and there are exceptions. Spots, for example, are annotations.

Overall, ~99% of projects will involve creating one or a few Annotation objects, and then generating further Detection objects within them. Those Detections will then be classified or measured in some way in order to produce a general number (% positive), which can then be saved in the “parent” annotation object. A list of annotation measurements across a variety of images can then be generated for a summary at the end of a project. The simplest example would be a list of image names that each had a single annotation, with the percentage of positive cells as the primary statistic of interest.

Ready to get started? Or skip to the end and learn how to generate summary data for your project?

What is your image?

Multichannel- This category includes fluorescence, MIBI, or any other collection of grayscale channels combined together into a stack that can be represented in 2D. I believe QuPath can handle up to 32 bit depth channels.

Brightfield- This category handles 8bit RGB images. This is the industry standard for whole slide imaging, mostly due to the file sizes already being quite large. Some software/programs may default to a higher bit count, which QuPath will not currently handle (Our Zen software for Observers seems to default to 14bit RGB images, which will not open without conversion).

If Other: What is it? Start a new topic. Phase contrast images of cells probably won’t work very well, though I have seen some success there using StarDist. You would need to train your own model at this point, however. Possibly some Vectra brightfield images taken in more than RGB channels would fit here.

Brightfield

With any brightfield image, the first step (aside from verifying that the correct image type is selected in the Image tab) should be verifying that your color vectors are fairly accurate.

Color deconvolution

This can be done through the Analyze->Preprocessing->Estimate stain vectors, and it is usually a good idea when utilizing this to accept the mention setting background is usually a good idea to make seeing the color vectors easier. Select an area with an annotation (keep that annotation selected, as it should be after you draw it), and run the command.

Most commands take this background value into account when generating data, so do make sure to get a bit of background in the annotation you are using to set your vectors( the one exception to that is the Cell Detection command in 0.1.2).

Ideally, you will want the lines for your two stains (which do not have to be DAB and Hematoxylin, regardless of their labels) to match their angles with the pixels they represent. You can do this manually by dragging the balls at the end of the vectors, or click Auto in the lower left. Pete has more information about optimizing these here, along with other ways of selecting vectors if you watch the whole video. I highly recommend the use of the 1,2,3, and 4 keys while iterating through various color vector settings.

Now that you have some decent color vectors set, what type of image are you looking at?

Do you have a single field of view? Tissue in a whole slide or large tiled image? A Tissue MicroArray?

Single field of view

For single field of view images, you usually will want to analyze the entire image. In the Objects menu, there is an option to Create full image annotation, or in a script you can use

createSelectAllObject(true)

The true selects the object, so that whatever you run on the next line will have that object already selected. If you are running scripts multiple times on the same set of images, note that this does not clear all objects in the image in the same way that Simple Tissue Detection does. You may want to include a

clearAllObjects()

line in order to prevent many overlapping sets of objects.

What is your analysis? Are you counting cells, measuring areas, or something more complex(advanced scripting)?

Whole slide image

0.2.0 Simple thresholding for tissue detection, click here for more!!

image
In place of the old tissue detection function, in 0.2.0 we now have access to Create thresholder which fulfills most of the same functions, and gives you more flexibility over what is detected. When you first run the command, you should get a dialog as shown in the lower right.

Resolution determines how fine of details you want for the outline of your tissue. Lower will be faster and result in blockier objects, while higher will be faster and result in finer detail. If pushed to extremes, the highest resolutions, while also allowing very small holes, can put some strain on your system! I would recommend starting low and increasing until you are happy, rather than the other way around. You have less control here than with the simple tissue detection.

Channel: In a brightfield image you will generally have R G and B as your baseline data, along with the color deconvolution channels and a few mathematical options. Average channels is probably the best way to “find tissue” in most cases. A fluorescence image will have the different fluorescent channels, but at the moment you cannot choose to combine multiple channels. Instead you could run two Simple thresholders and merge the results. You have far, far more control here than with the simple tissue detection.

Prefilter: If you are detecting tissue, just use Gaussian. There are some really cool use cases for some of the other filters, so feel free to play around with them.

Smoothing sigma: Higher numbers lead to smoother and less precise results. Increasing this will also generally reduce the number of vertices and be easier on your system (run faster).

Threshold: The important stuff! For most brightfield images I have found that values from 170-240 are best. If you are using deconvolved channels (and interactively changing the vectors), your Background settings will have an impact on this. For brightfield images “Below threshold” will be your tissue, while in fluorescent images “Above threshold” will be your area of interest.

Above and Below threshold: Apply your classes here. Generally one of these will be left Unclassified or blank, and the other given some other class. Remember that you can add a class called “Tissue*” in the annotations tab, though using the “Region*” default class might be your best bet here. The * will prevent the tissue annotation from being used in any future analyses (like creating a pixel classifier).

Region: Generally leave as Everywhere, though in some cases, you may need to manually create areas to search within. Some slide scanners are weird.

Classifier name: Name and save your thresholder.

Once you have saved the thresholder, you can then use the Measure, Create objects and Classify buttons.
Measure: Do not run this before creating an object, but you can add measurements to the full image concerning the objects you have created.

Create Objects:


New object type: In general you will want your new object type to be an Annotation, so that you can use it for other analyses like another thresholder, or a pixel classifier, or cell detection.
Minimum object size: All “little bits” smaller than this value will be ignored. 30-60,000 have usually been good values for me when I want to avoid little bits of tissue and fuzz, but this will be very project dependent.
Minimum hole size: Always the hardest to wrap my head around, but larger values here mean fewer holes. 0 includes all holes, at least as far as your Smoothing sigma and Resolution allow. Keep increasing this if you have unwanted holes in your resulting annotation.

Classify: This is not used for tissue detection, but if you have objects, you could classify them by whatever pixel type they are inside of. I have not really explored this option much, but I suspect it uses centroids of the detections to determine what class to give them.

… menu:

Save prediction image generates an OME-TIFF file that is essentially binary, with your classes as black masks, but each class has its own Index value (1,2,3 etc). I am not yet sure how to use these.

Enable buttons for unsaved classifiers will allow you to perform the simple tissue detection without saving it. Generally, you will want to save it.

Summary- I tend to start with a low Resolution, Average channels, Gaussian, a sigma of 3-5, and a threshold of around 180-200.


Here I can see that I am missing some tissue around the edge, and I feel like the tissue edge is too “blobby,” so I will reduce the sigma, choose a higher resolution (lower value), and a higher threshold (brightfield, so higher numbers include more area).

That looks more like what I want. At this point I can save it and Create objects, choosing to analyze the Full Image.

I choose some settings to remove spare bits of tissue or background, and make sure any holes in the tissue are larger than 5000, or else they get filled in. That will prevent the annotation from getting too unwieldy. A moment later, nothing appears to change, but if I look in the Annotations tab, I can see a new annotation roughly the shape of my tissue. Pressing the C button to turn off the classifier, I can see that my tissue is now outlined reasonably well. In the future I might increase the Minimum hole size to eliminate some of the elongated empty spaces at the bottom of the tissue.

If I want to run this tissue detection on other images, since I saved it, I can go to the Workflow tab, and copy that line out of the script. It should look something like the following.
createAnnotationsFromPixelClassifier("Tissue", 1000000.0, 5000.0)
If I wanted to increase the minimum size of my holes, it is as easy as adjusting the number in the script:
createAnnotationsFromPixelClassifier("Tissue", 1000000.0, 10000.0)
image
More information on this process here: https://qupath.readthedocs.io/en/latest/docs/tutorials/thresholding.html

What is your analysis? Are you counting cells, measuring areas, or something more complex(advanced scripting)?

Tissue microarrays

(to be expanded upon at a later date)

TMA suggestions

Command: TMA->TMA dearrayer

The basics of this are fairly straightforward, though getting exactly the results you want can be tricky.

TMA core diameter should be as close as possible to exactly correct. Small differences in this value can have a massive impact on the accuracy of the array. Use the line tool or the scalebar in the lower left corner to refine your estimate.

Faint tissue thresholding can be a problem, as can missing fields. If your tissue is too faint, you may find creating a predetermined array from a script to be more effective.

If your TMA detection is only slightly off, you can make use of the add row or add column functions within the TMA menu to adjust the dimensions of the array. Note that the new rows or columns default to being missing, or turned off. Missing cores are ignored when running functions like Simple tissue detection. You can select the whole array in the Hierarchy and then right click on it in the Viewer in order to set all cores to valid. Or run a quick script.

getTMACoreList().each{
    it.setMissing(false)
}
fireHierarchyUpdate()
println("done")

Tissue detection can then be run on all cores. Note that the TMA object can be adjusted (drag individual cores around, tweak the size) ONLY PRIOR TO RUNNING SIMPLE TISSUE DETECTION. Make sure you are happy with fine tuning any ellipse positions prior to running anything that locks the TMA grid into place.

File->TMA Viewer can be helpful for looking at any TMA results. There is also an option to create a TMA data grid in software like Excel, and then import that into the measurements list for each TMA core (say patient endpoints).

What is your analysis? Are you counting cells, measuring areas, or something more complex(advanced scripting)?

Counting cells

If counting cells, are you sure that is the best option? Cell counts can be one of the trickiest analyses to perform due to variations in cell morphology, occasional high background in staining, and the constant effect of cells that have nuclei in a different slice of the tissue. Worse, some cells have inherently difficult morphologies, like macrophages, and others, like CD8 positive T cells can easily obscure the nucleus. So while CD8 is technically not a nuclear marker, you end up with a population of cells that have a hematoxylin center with a CD8 marked rim, and also a high percentage of cells that are just a blob of CD8 marker with no nuclear marker. In many cases, you may be better off (and more biologically accurate) presenting your data as an area measurement.

That said, if you are sure you want to go for it… here are your options:

Cell detection (or Positive cell detection), fast cell counts, Manual spots

If none of these work, you still have the option of creating your own cell detection through ImageJ macros, though that would likely require some advanced scripting.

Cell Detection

Overview

Analyze->Cell Analysis->Cell detection

Positive cell detection and cell detection are the two main workhorses for counting and classifying cells in QuPath. They are nearly identical, with Positive cell detection having a few extra options that are specific to DAB measurements. Note: that does not mean that they can only be used with DAB, just that they only work with a second color vector called DAB. I suggest keeping your Image type as Brightfield (H-DAB) regardless of your actual stains if you want to use Positive Cell Detection.

Each method functions by finding a “nucleus” object from a modified version of the image that, hopefully, isolates nuclei. For example, only the hematoxylin stain within a brightfield image. Once that object is found, it will attempt to expand a cytoplasm around it. This cytoplasmic expansion is blind, and so the cytoplasm will always have the same shape as the nucleus, unless it runs into another cytoplasmic expansion. If there is another nucleus within cytoplasmic expansion range, the two cytoplasms will stop halfway between the two nuclei.

Options and measurements

The command interface

Choose detection image: The default QuPath options are limited to Hematoxylin, or OD sum. Hematoxylin refers to whatever is in the Hematoxylin color vector (Image tab), and so it is, essentially, the “one color channel” option. You can adjust it to whatever color you want. OD sum is the total optical density of the image, and can be seen using the 5 key, or selecting Optical density sum in the Brightness and contrast dialog. Generally, use Hematoxylin when you have an effective nuclear stain that exists exclusively in 100% of your cells, and use OD sum when you have some sort of marker that may exist in your nucleus and obscure the hematoxylin (eg. KI67).

Requested pixel size: Downsampling. Snaps to the closest multiple of the pixel size (I believe). Higher values will run faster, lower values should give more precise outlines. Going below your pixel width/height is not useful.

Background radius and Max background intensity: These two options are linked, and are useful for preventing masses of cells from showing up in high background areas like black marker, smudges, and tissue folds. The first thing I tend to change if I am having difficulties is to remove the background radius measurement.

Standard settings over a tissue fold.

Reducing the Max background intensity prevents many of the cells around the fold from being generated.

Mean filter radius and Sigma: If your cells are being split too often, increase these. If your cells are being merged together incorrectly, lower these. They are two slightly different ways of achieving roughly the same thing, but it may require some trial and error to establish the best results for your particular experiment. In general, Median filter radius is slower, so I tend to use it less. Increasing either or both of these too much will result in an empty halo of “extra nucleus” around any detected nuclei.

Minimum area: Minimum allowed area for the nucleus. Note that this is prior to the application of Smooth boundaries, so you will occasionally see nuclear areas below your threshold if that option is selected.

Maximum area: Same as minimum, with the same caveat.

Threshold: This is the big one! It determines how “high” the pixel values have to be to be considered a potential nucleus. Anything below this is ignored. To get an idea of what the detection algorithm is looking at, use the “2” key for Hematoxylin, or the “5” key for Optical density sum, and then mouse over the values in the resulting image. The lower right corner of the viewer will show the values of the pixel the cursor is currently over (in addition to the coordinates above it). In general, you will need a lower threshold than the positive pixels you find, due to the blur mixing the positive signal with whitespace.

Cursor, sadly, not shown.

Split by shape: Default checked, I have never found any need to uncheck this, but give it a shot if you have very oddly shaped nuclei that are being split into multiple cells. Doing so generally has a very negative effect on separating any tightly clustered nuclei.

Cell Expansion: This determines how far the nucleus (base object) will expand. Pixels within this cell expansion will contribute to the “Cytoplasm” measurements in the detection object. If this is set to zero, the resulting object will be a nucleus, and not a cell object. That prevents certain other methods from being run on it, like Subcellular detection or setCellIntensityClassifications(). I would recommend always using at least 1 pixel expansion. See this thread for other concerns when using Cytoplasm based measurements.

Include cell nucleus: Unchecking removes the cell nucleus. This can reduce video lag and the number of measurements for a cell. Cytoplasmic measurements are still included despite the lack of a nucleus.

Smooth boundaries: Generates smoother cell and nuclear edges. It appears that cell measurements are based off of these lines, so this is not simply a visual change.

Make measurements: You want these, right? No check, no data. This has been useful only in situations where I have a multiplex brightfield image, and the terrible, horrible, things I had to do to get appropriate cell segmentation made the initial measurements not terribly useful.

Once you have cell objects, you might want to classify them.

Positive cell detection only

Information specific to the positive version of the command

Score compartment: a selection of 6 measurements to use for your threshold(s). I would recommend not using Max. Ever. Positive cell detection now works for Fluorescent images as well, and behaves as a built in Classify->Object classification->Create single measurement classifier, though it allows for three different thresholds.

Choosing a threshold: As noted several other places on the forums, there is no such thing as a correct, objective threshold for positivity. Ideally, there would be some ground truth, but that frequently comes from our interpretation, the amount of background generated by a given antibody, and other biological concerns (PDL1 being strongly expressed on muscle cells that are not of interest to someone studying cancer). One possible way to choose is to have a good negative control. Another would be having a pathologist or someone familiar with your marker explaining what background is expected, and what constitutes positive in regards to your study. In the end, you will have to make some decision, and there are a couple of tools in QuPath to help with this.

Choosing thresholds for positivity

Measure->Measurement maps: By adjusting the lower slider on the color scale for a given measurement, you can find a good threshold where all of your positive cells show up as red. Below is an example showing the lower (Maximum) threshold has been reduced to 0.09 for Cytopasmic Eosin staining, and the resulting cells that would be positive for such a measurement.


As of 0.2.0 there are new color map options that are better suited to visualizing data sets fairly, and making them useful for people with colorblindness.
image
Combining these options with the filter on the measurement list should allow you to quickly visualize your measurements of interest.

Measure->Show detection measurements->Show histograms: Sometimes, especially if you have a bimodal distribution, you can use the histogram for a particular measurement to help determine a particular cutoff. Alternatively, you can use this dialog to look at detection objects near your threshold in an already classified set of objects; this can help you decide if the “close calls” are being made correctly enough.

Note: don’t always require “nuclear” measurements to be nuclear (link to CD8 thread). As mentioned above, when using OD sum to generate your nuclei, you may also be picking up cytoplasm as part of the nucleus. That is okay, as long as you can still determine the positivity of your detection.

Sometimes you may need features that are not available by default, for example using other color deconvolution vectors, or measuring the angle of the cell. You can find additional information on adding features here.

If you still need a more complex classifier, check here, or go straight to converting this into a script you can run on the whole project.

1 Like

Fast cell counts (brightfield)

A faster, less complicated option for finding cell objects. Creates a circle, not an outline of the cell.

One of the primary advantages of this method is that is has a merged Hematoxylin+DAB “channel.” That means, in cases where you have more than two stains (H-DAB+Red/purple/etc), you can do slightly better than pure Optical density sum, which would tend to pick up things like purple very strongly.


These objects are detections, not cells, so keep that in mind for any further analyses (in other words, options like subcellular detection, or setCellIntensityClassifications() will not work).

If you still need a more complex classifier, check here, or go straight to converting this into a script you can run on the whole project.

Points tool

Pointers on points

Manual spots can be placed for cases where counts of a small number of rare or complex objects are desired. The fact that they are annotations means that they can be dragged around after being placed. Despite any adjustments to their radius, they are actually only single points, so measurements are not particularly meaningful. Annotation spots can be classified by right clicking on one of a set, then selecting a class from the context menu. This changes the class for an entire set of points.

To create a new set, and apply a new class, click the “Add” button, which will create a new “points” object. Delete any points you don’t want by first selecting the points tool, selecting the set of points that contains that point, and then ALT+left clicking on it. Having any other tool active (like the move tool) will not work.

These spots can also be converted to detection objects (ellipses or other) using a script, and measurements can be generated within the ellipse detections (since they are no longer single point spots), or they can be reclassified.

Once you have annotated your slides with spots, you may still be interested in using a script to create a summary spreadsheet. Note that EACH SET of points is a separate annotation object, and thus will have its own line on any resulting spreadsheet. For this reason it might be a good idea to trythe script converting the spots into classified detections, so that all sets of points will go on a single line in the resulting document.

If this wasn’t for you, maybe choose a different cell detection method, or try an area measurement?

Measuring areas

Positive pixel count: Measuring one stain vs everything else. Your basic % area tool.

Removed in 0.2.0

Create cytokeratin annotations: Similar to positive pixel count, except with a few additional options and generates annotations rather than detections. You can run cell detections within these. Even… different cell detections for the different areas!

Tiles: When you quickly want a lot of squares. Good starter analysis. Create detections or annotations.

SLIC superpixel segmentation: My personal favorite due to flexibility, but requires more coding to really get the most out of it. Create detections only… at first.

Subcellular detections: Very workaroundy, and likely to attract some Pete based aggro, but annotation objects can be turned into cell objects with a script, and the resulting area can be analyzed using subcellular detections.

Much of this will likely be obsolete once the Pixel classifier is fully functional. If none of this sounds right for your area measurements, you may want to look into 0.2.0m# for that feature. Be aware that it is not yet able to be run across a project, and has to be trained on each individual image. Another option is using the flexibility of ImageJ or scripting to perform your own, custom analysis.

Positive pixel count, deprecated as of 0.2.0

There are several ways to measure areas, the most popular of which is Analyze->Region identification->Positive pixel count (experimental).

Basically, a selected annotation will be divided up into positive, negative, and neither pixels. Summary measurements will be added to the parent annotation. The positive pixel and negative pixels will be detection objects, while pixels that meet neither threshold will be left blank. Here you can see the red (positive) pixels, blue (negative/hematoxylin pixels), and some empty space that was below the hematoxylin threshold.

Resulting measurements include:

Positive % of stained pixels: Positive/(Positive+Negative)*100

Positive % of total ROI area: Positive/(Positive+Negative+Neither)*100

The first one ignores white space/areas below the hematoxylin threshold.

0.1.2 warning: In 0.1.2, each area analyzed by the tool required at least one “negative” pixel, or else the percentage positive would error out. This problem could usually be compensated for by placing a negative value in the Hematoxylin threshold (‘Negative’), but if your whole project will revolve around this feature, I would recommend figuring out the setup of version 0.1.3 or trying out 0.2.0m#.

Downsample factor: As normal, a pure increase in pixel size. Larger values will run faster, but be less accurate.

Gaussian sigma: Blur. Increase this for smoother annotations or to increase performance due to masses of different pixel objects on screen.

Hematoxylin threshold (‘Negative’): Essentially the threshold for tissue versus whitespace.

Eosin/DAB threshold (‘Positive’): Pixels above this threshold in the second deconvolved channel will be considered Positive.

IMPORTANT: I have often flipped my positive and negative vectors and thresholds due to one specific interaction between positive and negative. If a pixel is above both the negative and positive threshold, it is considered “positive.” In cases where there is dark background in another stain that is causing problems (Masson’s trichrome, H-DAB+Red, background from black shadows, etc), I have swapped my color vectors so that Hematoxylin has the color vector for my marker of interest. That way if there is something that is very dark in the other channel, it will be treated as “negative.” More details on that and dealing with the area issues mentioned next in this thread and the links contained within it.

Positive pixel count frequently struggles over large areas, and I strongly recommend creating annotation tiles (see tiles section) before running it, and then summing the results either in a script or in a spreadsheet program after.

Were you looking for something else for your area measurement? Or would you like to review a how to generate a simple script to summarize your measurements?

Cytokeratin tool No longer exists in 0.2.0, replaced by sequential uses of simple thresholder.

Cytokeratin tool (not exclusively for cytokeratin)

Analyze->Region identification->Create cytokeratin annotations (experimental): A fairly specific version of the positive pixel tool, but gives you annotations (already classified as Tumor and Stroma) rather than detections, so that you can run cell detection in one or the other. Does not need to be used on cytokeratin, any kind of broad background stain will work.

Downsample factor: As normal, a pure increase in pixel size. Larger values will run faster, but be less accurate.

Gaussian sigma: Blur. Increase this for smoother annotations or to increase performance due to masses of different pixel objects on screen.

Tissue threshold: Essentially the threshold for tissue versus whitespace.

Eosin/DAB threshold: Pixels above this threshold in the second deconvolved channel will be considered Positive.

Separation distance: This places a small separation between the tumor and stroma regions that are generated, which can help with half of a cell being represented in each annotation.

Just like the positive pixel tool, if you run into problems with this tool you may need to downsample and blur further, or create tile annotations first to break up the area analyzed at any one time.

Were you looking for something else for your area measurement? Or would you like to review a how to generate a simple script to summarize your measurements?

Tiles

*Analyze->Tiles & superpixels->Create tiles*:

Overview: Takes an annotation area object and breaks it up into tiles.

Basic, but does the trick for simple analyses. One option is to create detections that can have measurements (Add intensity features), and then be classified. It can also be used to create annotations for various slow detection methods to work on a large scale, like positive pixel detection, sending regions to ImageJ, or creating image tiles for output for AI training/processing.

Tile size: How large each square is on a side.

Trim to ROI: Creates non-square tiles if the tile at any given position would otherwise extend outside of the parent annotation. Prevents including too much whitespace in the measurements of tiles on the edge of tissue.

Make annotation tiles: What it says. Annotation tiles can have other things generated inside of them, while detections cannot. Whether you want this depends on your final purpose. Don’t select it if you want to simply classify a bunch of tiles as positive or negative to quickly get a rough positive area measurement (or run a more complex classifier). Do check it for most other things.

Remove parent annotation: Project specific, but generally I would check this if Make annotation tiles is also checked. If you check only Make annotation tiles, and attempt to “selectAnnotations()” and run some sort of cell detection, as soon as the parent annotations is chosen, it will wipe out all Tile annotations within it. If you want tile annotations, but also want to end up with one large annotation at the end, I would check both of these, and then Objects->Merge selected annotations at some point later in the pipeline.

Were you looking for something else for your area measurement? Or would you like to review a how to generate a simple script to summarize your measurements?

SLICs (Superpixels. Big Pixels.)

The best things in life are pixels

Analyze->Tiles & superpixels->SLIC superpixel segmentation:

Now we get to the good stuff. This option pairs well with another tool in the same menu:

Analyze->Tiles & superpixels->Tile classifications to annotations.

Overview: Create detection tile objects that follow the outline of similarly stained pixels. This works in both brightfield and multichannel images.

Another tiling method, but this time you only have the option of starting with detections. They follow the outline of similarly stained pixels, and are a very flexible area classification tool. Once the SLICs are classified, similarly classified areas can be merged into annotations (see short guide here), which can then be used to search for cells or other objects. The most obvious example would be determining a “Tumor vs Stroma” area in something like an H&E, or in complex images such as those generated with MIBI. Decision tree or other trainable classifiers can be used on the large number of measurements that can be applied to these through Analyze->Calculate features->Add intensity features. More information on adding features here.

Getting SLICs that work for your project is too project specific to get into, but generally for large tissue based features I prefer larger, more regular tiles, while for cell detection or positive area detection I make them as small and irregular as I can tolerate (smaller and less regular = more processing time). Also, if you are using Haralick features to analyze texture, you will need either larger tiles, or you will want to use information from surrounding areas to help classify the tile.

The buttons and knobs

Gaussian sigma: Blur. Increase this for smoother tiles or to increase performance.

Superpixel spacing: Depending on your target and classification method, this can vary quite a bit. I usually start with 50 and then lower it as I want to get more precise with the edges of what I am measuring.

Number of iterations: I usually don’t change this, and haven’t noticed a major effect by increasing it. You may be able to speed up large areas by decreasing it, but always test on a small region first to see the impact.

Regularization: Can have a massive impact on the shape of the superpixels. The value seems to be very correlated with the size of the superpixel.
For example regularization 10.


Regularization 0.01, shown with heatmap of Eosin staining to emphasize the difference.

Measurement maps + SLICs can be used to accentuate many features of the tissue, even with relatively simple measurements, as shown.

Tissue segmentation and classification with SLICs has been a fairly standard way for me to start complex projects. Classification will require the addition of new feature measurements, of which there are a variety!

Functionality has in large part been superseded by the pixel classifier, but there are still some things you can do with SLICs that simply can’t be done with the current pixel classifier. Chief among these is the combination of large scale features and small scale ones, and the use of all of the Haralick features to classify objects.

If you want to measure areas classified as a certain object, you can either sum the detection area measurements within classes with a script, or convert classified detections into annotations, which have an automatic area measurement.

Were you looking for something else for your area measurement? Or would you like to review a how to generate a simple script to summarize your measurements?

1 Like

Subcellular detections

Replaced by simple thresholder

Analyze->Cell Analysis->Subcellular detection: Create an annotation, turn it into a cell object using a script, perform your subcellular detection. Can work better for small, oddly shaped areas. This option is primarily used for multichannel images, as stand-in for Positive pixel detection, which is brightfield only. It requires pixel size information (Image tab). This is definitely not the intended use for Subcellular detections, as it is more of a spot counter.
For the LuCa 7 channel sample (a field of view image), I would start by creating a full image annotation, then run the script linked to turn it into a cell object, followed by creating another whole image annotation (making data wrangling easier later on). So:

createSelectAllObject(true);
//Paste script in here
createSelectAllObject(true);

Ok, I was wrong, I do need to make one minor adjustment to the pasted script, as indicated in the script comments.
def targets = getObjects{return it.getLevel()!=1 && it.isAnnotation()}
needs to be changed to
def targets = getObjects{return it.isAnnotation()}

Now my hierarchy looks like this.
image
After playing with the settings a little, I ended up with this.


Note that this isn’t generally a good idea, and as you can see here, really didn’t do a great job of splitting some of the tumor cells. YMMV, but it is another option to try if other options aren’t working. It will take additional scripting to convert this into useful data, so expect to do a little coding if you go this route.

Were you looking for something else for your area measurement? Or would you like to review a how to generate a simple script to summarize your measurements?

Multichannel

If you are here, your images should be something like a fluorescence, MIBI, CyTOF, etc. image that is composed of multiple grayscale, largely independent, channels. While QuPath doesn’t perform linear unmixing, exactly, some of the same functionality can be performed in a script to alter detection measurements that are generated. Some of the R^2 or colocalization scripts can be used to check for bleed-through.

If you have this sort of project, do you have a single field of view? Tissue of some sort?

1 Like

Single field of view

For single field of view images, you usually will want to analyze the entire image. In the Objects menu, there is an option to Create full image annotation, or in a script you can use

createSelectAllObject(true)

The true selects the object, so that whatever you run on the next line will have that object already selected. If you are running scripts multiple times on the same set of images, note that this does not clear all objects in the image in the same way that Simple Tissue Detection does. You may want to include a

clearAllObjects()

line in order to prevent many overlapping sets of objects.

What is your analysis? Are you counting cells, measuring areas, or something more complex (advanced scripting)?

Tissue detection in multichannel images

Try the simple thresholder here (except you will use “above” instead of below threshold for your classifier) if you have one dominant channel (DAPI with some Gaussian blur?), or use the pixel classifier for more complex projects and images.

Now obsolete as of the simple thresholder and pixel classifier

Much of this will likely be obsolete once the Pixel classifier is fully functional.

Simple tissue detection: Seems to only take into account the first channel of the image. If you can adjust your input such that this channel is DAPI, or some highly autofluorescent channel, you might be able to use Simple Tissue Detection in the same way as the brightfield instructions, only with Dark background checked.

Very likely this won’t be the case, so I recommend checking out this thread which contains both a script for, and a rough description of how to perform, tissue detection in a multichannel image.

The script is a great example of how to use ImageJ to handle some image analysis, and could be a good starting point to build off of for more complex ImageJ based analyses. I can go into more detail if there is enough interest.

Alternatively, you can fairly quickly draw areas using the brush tool or wand tool. The wand tool, in particular, can be very useful here as it takes into account what is visible on screen. That means you can turn off interfering channels, and/or enhance the brightness of useful channels, in order to make the tool more convenient to use.

What is your analysis? Are you counting cells, measuring areas, or something more complex (advanced scripting)?