# How to decide threshold values for different structures in CT based on histogram?

**URL:** <https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661>\
**Category:** Support\
**Created:** [December 14, 2017, 7:10pm UTC](https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661 "2017-12-14T19:10:28Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Emily\_BM](https://avatars.discourse-cdn.com/v4/letter/e/439d5e/32.png) [@Emily\_BM](https://discourse.slicer.org/u/Emily_BM)\
**Post date:** [December 14, 2017, 7:10pm UTC](https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661/1 "2017-12-14T19:10:28Z")

</div>

how to decide threshold values for different structures in CT based on histogram?  
Operating system:  
Slicer version:  
Expected behavior:  
Actual behavior:

---

<div class="post-metadata">

**Author:** ![thewtex](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/thewtex/32/32_2.png) [@thewtex](https://discourse.slicer.org/u/thewtex)\
**Post date:** [December 15, 2017, 7:29pm UTC](https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661/2 "2017-12-15T19:29:09Z")

</div>

Hi @Emily_BM,

There are many histogram-based thresholding algorithms available in ITK.

Checkout [this histogram-based thresholding Insight Journal article](http://hdl.handle.net/10380/3279)

![big](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/0/5/05e7c0773ad23cf36759fadcae7c6323282b5780.jpeg)

or [this article](http://www.insight-journal.org/browse/publication/132) or the [ITK thresholding classes’ documentation](https://itk.org/Insight/Doxygen/html/group__ITKThresholding.html).

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [May 21, 2018, 2:20am UTC](https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661/3 "2018-05-21T02:20:12Z")

</div>

Somehow I’ve come across this old topic now.

@thewtex, what is your experience, do you find these histogram-based thresholding methods useful in practice?

I usually choose threshold value manually, based on live preview (provided for example by Segment Editor’s Threshold effect). If a good global threshold value exists then I can find it within 5-10 seconds. How automatic methods could make this faster or simpler? Also, don’t you need manual adjustment anyways?

For automated processing, instead of simple global thresholding, we had much better results with grow-cut or watershed based segmentation, with seed regions determined by registering an atlas.

---

<div class="post-metadata">

**Author:** ![thewtex](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/thewtex/32/32_2.png) [@thewtex](https://discourse.slicer.org/u/thewtex)\
**Post date:** [May 21, 2018, 12:57pm UTC](https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661/4 "2018-05-21T12:57:39Z")

</div>

@lassoan yes, I find them very useful in practice.

I usually start with the classic (multiple) Otsu threshold, then possibly try other methods.

We could make this faster and simpler in Slicer creating a module that just runs all the automatic thresholding algorithms and displays the results. Something like scikit-image `try_all_threshold`:

[http://scikit-image.org/docs/dev/api/skimage.filters.html#try-all-threshold](http://scikit-image.org/docs/dev/api/skimage.filters.html#try-all-threshold)

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [May 21, 2018, 1:28pm UTC](https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661/5 "2018-05-21T13:28:13Z")

</div>

Very interesting. I find that global thresholding is typically usable for only a few structures, such as skin surface, bones, maybe contrasted vessels/tumors, and they always require post-processing.

Can you attach screenshots that illustrate how you use it? What can you usually segment with it? Does it save you time or offer better results in some way than moving a slider manually? Are there some usable links to local/adaptive variants?

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [May 22, 2018, 3:43pm UTC](https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661/6 "2018-05-22T15:43:34Z")

</div>

I would definitely second this feature.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [May 22, 2018, 6:01pm UTC](https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661/7 "2018-05-22T18:01:33Z")

</div>

@muratmaga For what kind of images and structures you would use automatic threshold value recommendation? How long does it take to set the threshold value manually (based on live preview in slice views)? - It is important to know these, because the priority of a feature request is higher if it saves a lot of time and can be used for many cases.

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [May 22, 2018, 7:40pm UTC](https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661/8 "2018-05-22T19:40:27Z")

</div>

My typical use case for this is would be contrast (iodine based) enhanced microCT scans of dissected soft tissues (e.g., from mice or pathology samples), in which diffusion of contrast may vary from sample to sample. IN these case, I would be calculating some sort of a tissue to total volume fraction. I currently use Fiji for this specific use-case.

The importance of the feature for me is more for reproducibility and being objective more so than saving time.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [May 23, 2018, 4:16pm UTC](https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661/9 "2018-05-23T16:16:20Z")

</div>

Reproducibility is a good point. While usually the difference should be negligible between different operators, it my be still more elegant to say that threshold was selected by using XYZ algorithm.

I’ll add automatic threshold setting to Threshold effect in Segment Editor module.

@muratmaga Do you always compute the threshold on the entire image, or on a region of interest / masked region?

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [May 23, 2018, 4:35pm UTC](https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661/10 "2018-05-23T16:35:48Z")

</div>

@lassoan

Hard to generalize, but often volumes are already cropped down to contain only the sample of interest. So I am inclined to say entire image.

Mail]([Outlook](https://go.microsoft.com/fwlink/?LinkId=550986)) for Windows 10

 ![](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/1X/677f06bdf711468707faf594c72c7993f90d2513.png)

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [May 27, 2018, 2:21pm UTC](https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661/11 "2018-05-27T14:21:11Z")

</div>

I’ve implemented the feature (r27207). It will be available in nightly builds that you download tomorrow or later.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/9/d/9d414f5b58ae867afd2aca8e016cd4397f7e6e88.png)

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [June 18, 2018, 3:26pm UTC](https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661/12 "2018-06-18T15:26:40Z")

</div>

@lassoan

I finally tested this. Looks great, thank you. Is there something wrong with Shanbhag method? Everything else seems to produce reasonable threshold, but Shanbhag results in an empty selection (i.e, values too high, MRhead dataset). This is with a nightly from a week ago .

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [June 18, 2018, 4:07pm UTC](https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661/13 "2018-06-18T16:07:42Z")

</div>

It is normal that only certain methods provide meaningful threshold for a certain image. Shanbhag method seems to be sensitive to large uniform background regions.

---

<div class="post-metadata">

**Author:** ![anandmulay3](https://avatars.discourse-cdn.com/v4/letter/a/ac8455/32.png) [@anandmulay3](https://discourse.slicer.org/u/anandmulay3)\
**Post date:** [June 20, 2018, 2:14pm UTC](https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661/14 "2018-06-20T14:14:39Z")

</div>

hi @lassoan  
how can we add this auto threshold method in our scripted module ??  
i have seen that triangle gives highest threshold object(metal object etc.)  
do we have any method to catch bone??

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [June 21, 2018, 2:33am UTC](https://discourse.slicer.org/t/how-to-decide-threshold-values-for-different-structures-in-ct-based-on-histogram/1661/15 "2018-06-21T02:33:53Z")

</div>

You can follow the example [here](https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository#How_to_run_segment_editor_effects_from_a_script) and call [autoThreshold](https://github.com/Slicer/Slicer/blob/master/Modules/Loadable/Segmentations/EditorEffects/Python/SegmentEditorThresholdEffect.py#L257) method to compute the threshold.

Note that automatic threshold computation will not solve any difficult segmentation problem. It is mainly for standardizing threshold selection for trivial cases.
