# How do I detect tissue?

```{admonition} What will I learn?
- How to detect tissue regions with a QuPath thresholder.
- How to detect tissue regions with a QuPath pixel classifier.
- How to detect tissue regions with an ImageJ auto-threshold method.
```


A common task in image analysis is to identify regions that are clearly different from their surroundings.
This could be a difference in lightness, or an obvious change in hue or colour, among other possibilities.

The annotation tools described in [How do I draw annotations?](how_do_i_draw_annotations.md) can be useful here, but it can be faster and more reproducible to use a threshold or classifier to segment the image.

We will use the `CMU-1.svs` image from the [OpenSlide test data](https://openslide.cs.cmu.edu/download/openslide-testdata/Aperio/):

```{figure} ../../images/detecting_tissue/1-gui.jpg
The `CMU-1.svs` image opened in QuPath
```

## Thresholding images

A simple form of region detection is known as **thresholding**.
Here, we aim to find a single value that can "split" the image into two classes of pixel: usually, background pixels and foreground pixels.
We typically compare every pixel's value to this threshold, and based on whether they are above or below the threshold, we assign them to either background or foreground.

In brightfield images, typically we assign dark pixels to the foreground, whereas in fluorescence images, typically dark pixels belong to the background.

```{admonition} Question
1. Open `CMU-1.svs`.
2. Mouse over the background and tissue regions and inspect the pixel values displayed in the bottom right of the viewer.

Is there a value you could use to "split" these two classes of pixels?
```


### QuPath's thresholder

```{admonition} What to do
1. Run {menuselection}`Classifer --> Pixel classification --> Create thresholder`.
2. In the dropdown menu for {guilabel}`Channel` select {guilabel}`Average Channels`.
3. In the dropdown menu for {guilabel}`Below threshold` select {guilabel}`Region*`.
4. Adjust {guilabel}`Threshold` until the you think the tissue is properly detected (and most of the background isn't).
5. Adjust {guilabel}`Smoothing sigma` until you are happy with the output.
```

After adjusting these settings, you should see an overlay that previews the result of applying this threshold:

```{figure} ../../images/detecting_tissue/2-thresholder_settings.jpg
Example threshold settings for `CMU-1.svs`
```


```{note}
In the thresholder, you can adjust a number of additional parameters.
These are described in detail in the [QuPath docs](https://qupath.readthedocs.io/en/stable/docs/tutorials/thresholding.html#adjusting-parameters).
```

### Saving a thresholder

If you're happy with the preview overlay of the thresholder and want to apply it using the same parameters to other images, you'll need to save the thresholder somehow.

QuPath can do this by creating a very simple 'pixel classifier', which contains the information about resolution, smoothing, channel and threshold value.
This pixel classifier is usually saved in the QuPath project.

```{margin}
{{C}}
```

```{admonition} What to do
1. Enter a memorable name in the {guilabel}`Classifier name` field.
2. Click {guilabel}`Save`.  
3. Click {guilabel}`Create objects` which will present you with more options.
  Here, you can decide whether to create objects across the full image, within annotated regions, or within the *selected* regions.
4. Select {guilabel}`Full image` and click {guilabel}`OK`.
  :::{figure} ../../images/detecting_tissue/3-thresholder_selection.jpg
  Thresholder selection sub-window
  :::
  After this, you can select another set of options.
  These give you control over the exact types of objects that will be created, whether holes and fragments are cleaned up, and what to do with existing objects.
5. Click {guilabel}`OK` on this dialog:
  :::{figure} ../../images/detecting_tissue/4-thresholder_create.jpg
  Thresholder object creation settings
  :::
```

The final result should be detected tissue regions, including QuPath classifications.

```{figure} ../../images/detecting_tissue/5-thresholder_done.jpg
Results of running QuPath thresholder
```


## QuPath pixel classifiers

You can think of a thresholder as a *pixel classifier*.
That is, a classifier that takes pixel values as input and outputs a class name for each pixel in the image depending on its values.

In the case of a thresholder, we "train" the classifier by manually adjusting the parameters that identify pixels as belonging to one class or another.
However, QuPath also provides more sophisticated settings for training pixel classifiers.

### Classifying regions

Within the thresholded areas we detected just now, we can identify differing tissue regions.
Here, we'll work to distinguish the regions with densely-packed, strongly-staining nuclei and the rest of the tissue we detected.

```{figure} ../../images/detecting_tissue/6-classifier_parents.jpg
Pixel classifier parent objects
```

Within the thresholded areas we detected just now, we can identify differing tissue regions.
Here, we'll work to distinguish the regions with densely-packed, strongly-staining nuclei and the rest of the tissue we detected.

```{figure} ../../images/detecting_tissue/7-classifier_pane.jpg
Pixel classifier pane
```

```{margin}
{{C}}
```

```{admonition} What to do
1. Draw an annotation in the background (white) region and assign it the class {guilabel}`Ignore*`.
2. Draw an annotation in the densely-packed, purple-ish region and assign it the class {guilabel}`Negative`.
3. Draw an annotation in the other, red-ish tissue region and assign it the class {guilabel}`Positive`.
4. Click{guilabel}`Live prediction` to enable an overlay that shows the results of applying the trained pixel classifier to the image.
```

```{figure} ../../images/detecting_tissue/8-classifier_preview.jpg
Pixel classifier live preview
```

You can add more annotations to refine the predictions.

```{tip}
Generally, it is better to add small and diverse annotations rather than large annotations of similar regions.
Providing large amounts of similar regions will only serve to make training slower without increasing accuracy for difficult regions.

You should also aim to have roughly the same number of training samples for each class (shown in the pie chart), or at least proportional to the size of each class in the image.
```

```{note}
There are additional options for the pixel classifier, some of which are the same as the thresholder settings shown previously.
These are described in detail in the [QuPath docs](https://qupath.readthedocs.io/en/stable/docs/tutorials/pixel_classification.html#adjusting-other-options).
```


### Saving and applying a pixel classifier

Once you are happy with the settings of the pixel classifier, you can save it into the project under a suitable name.
As with the thresholder, this will enable some options and make the classifier available for scripting.


```{margin}
{{C}}
```

```{admonition} What to do
1. In the {guilabel}`Train pixel classifier` window, enter a memorable name under {guilabel}`Classifier name`.
2. Click {guilabel}`Save`.
3. Click {guilabel}`Create objects` and follow the same process as with the thresholder.  
  In this case it will be the current selection since we are doing it **inside** the annotation, rather than the full image.
  :::{figure} ../../images/detecting_tissue/9-classifier_selection.jpg
  Pixel classifier parent object selection
  :::
4. Choose options for the objects created:
  :::{figure} ../../images/detecting_tissue/10-classifier_create.jpg
  Pixel classifier object creation settings
  :::
```

After a short wait (longer with high-resolution classifiers) we are left with regions corresponding to the classes we added to the training annotations earlier:

```{figure} ../../images/detecting_tissue/11-classifier_done.jpg
Results of running QuPath pixel classifier
```

```{admonition} Challenge
1. Open `CMU-1-Small-Region.svs`.
2. Load the pixel classifier you just saved ({menuselection}`Classify --> Pixel classification --> Load pixel classifier...`)
3. Apply the pixel classifier to the entire image.
4. How good are the results?  
  Would seeing this result affect how you would train the classifier?  
  Would you expect similar results on an image from a different scanner, or of a different tissue section?
```

## Using ImageJ threshold methods in QuPath

Thresholders and pixel classifiers require manual input.
This is fine for small projects with similar images, but identifying a single threshold that works across many images in a project can be challenging. 
ImageJ provides methods for automatically identifying and applying a threshold that can be useful here.

QuPath includes an [ImageJ script runner](https://qupath.readthedocs.io/en/stable/docs/advanced/imagej.html) for sending regions to and from ImageJ with QuPath, and for running ImageJ macros and scripts.

```{margin}
{{C}}
```

```{admonition} What to do
1. Run {menuselection}`Extensions --> ImageJ --> ImageJ script runner`.
2. In the script runner, select {menuselection}`File --> Open example --> Auto threshold.ijm`.
  :::{figure} ../../images/detecting_tissue/12-imagej_runner_script.jpg
  ImageJ script runner
  :::
3. For {guilabel}`Apply to`, select {guilabel}`Whole image`, and for {guilabel}`Return Roi as` select {guilabel}`Annotation`.
3. Click {guilabel}`Run ImageJ macro`.
```

After clicking {guilabel}`Run ImageJ macro`, QuPath will send an appropriately-sized image to ImageJ, run our macro, and retrieve any ROI or overlay objects as specified in the settings:

```{figure} ../../images/detecting_tissue/13-imagej_results.jpg
Results of ImageJ thresholder in QuPath
```

```{tip}
You can find more information on the ImageJ script runner in the [QuPath docs](https://qupath.readthedocs.io/en/latest/docs/advanced/imagej.html).
```

## Challenge: the biggest circle

You've learned a lot about thresholding images!
Now, combine it with your knowledge of QuPath's measurements for this puzzle.

```{admonition} Puzzle
1. Open [`circles.png`](https://github.com/user-attachments/assets/88c4fc2f-bf8d-442c-8685-4ced700032ad) in QuPath.
2. Try to find the largest circle.
3. Find its area in pixels{sup}`2`.
```
