# Improve markups label visibility

**URL:** <https://discourse.slicer.org/t/improve-markups-label-visibility/17022>\
**Category:** Support\
**Tags:** markups\
**Created:** [April 10, 2021, 3:22pm UTC](https://discourse.slicer.org/t/improve-markups-label-visibility/17022 "2021-04-10T15:22:01Z")\
**Posts on this page:** 13\
**Page:** 1

<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:** [April 10, 2021, 3:22pm UTC](https://discourse.slicer.org/t/improve-markups-label-visibility/17022/1 "2021-04-10T15:22:01Z")

</div>

Sometimes markups labels are difficult to read over complex background. Should we enable shadow and bold style by default to improve visibility?

Examples:

Current default (no bold or shadow):  
 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/2/3/2338fffd91fd5bce434585bfb45097aaaea80893.jpeg)

Shadow:  
 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/b/6/b62126ee6eab6358cccf36b918188db424f76f98.jpeg)

Bold:  
 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/f/2/f2adb28b66a63b19ba761cc246577c13550ea5f2.jpeg)

Shadow+bold:  
 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/d/6/d676c87f73d4bd2873ef5a039b110ce22a3e638c.jpeg)

Shadow+bold (with smaller font size):  
 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/8/9/89d15ba94fd5ba2c5602b00d3f8983c7ad11ad32.jpeg)

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [April 10, 2021, 3:48pm UTC](https://discourse.slicer.org/t/improve-markups-label-visibility/17022/2 "2021-04-10T15:48:21Z")

</div>

A shadow plus bold, slightly smaller font looks good to me. A screen-space halo would be even better but I don’t think that’s available in VTK.

OHIF defaults to a yellow which is more readable sometimes but not always.

![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/e/b/ebb547669346ca58920027f68d9d9a6c96a84567.jpeg)

They use a convention I do like though, which is that the markup is green while it’s being actively defined (e.g. when only one point of a line has been placed) the then it gets it’s final color when completed.

---

<div class="post-metadata">

**Author:** ![rbumm](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/rbumm/32/9404_2.png) [@rbumm](https://discourse.slicer.org/u/rbumm)\
**Post date:** [April 10, 2021, 5:37pm UTC](https://discourse.slicer.org/t/improve-markups-label-visibility/17022/3 "2021-04-10T17:37:15Z")

</div>

Shadow and bold look great!

---

<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:** [April 10, 2021, 6:43pm UTC](https://discourse.slicer.org/t/improve-markups-label-visibility/17022/4 "2021-04-10T18:43:54Z")

</div>

> [@pieper](#):
>
> OHIF defaults to a yellow which is more readable sometimes but not always.

In anatomical drawings/labelling, it is common to pair these lines with a color that is much darker in contrast (e.g., white/black, yellow/blue etc), so that part of the line remains visible regardless both in areas of high/low contrast. On option like this would be great actually!

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [April 10, 2021, 7:32pm UTC](https://discourse.slicer.org/t/improve-markups-label-visibility/17022/5 "2021-04-10T19:32:29Z")

</div>

> [@muratmaga](#):
>
> it is common to pair these lines with a color that is much darker in contrast (e.g., white/black, yellow/blue etc)

Yes, that’s what the drop shadow does, but our default markup color is too dark. I’ve never really cared for that red color actually. It carries over from the days when you needed to use bland colors so they could be recorded to VHS tape (clearly no longer a requirement).

---

<div class="post-metadata">

**Author:** ![hherhold](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/hherhold/32/12199_2.png) [@hherhold](https://discourse.slicer.org/u/hherhold)\
**Post date:** [April 10, 2021, 7:50pm UTC](https://discourse.slicer.org/t/improve-markups-label-visibility/17022/6 "2021-04-10T19:50:12Z")

</div>

+1 on drop shadow on by default. Incidentally, sometimes enabling shadow doesn’t seem to work - any idea why that might happen?

---

<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:** [April 10, 2021, 7:54pm UTC](https://discourse.slicer.org/t/improve-markups-label-visibility/17022/7 "2021-04-10T19:54:10Z")

</div>

> [@hherhold](#):
>
> sometimes enabling shadow doesn’t seem to work - any idea why that might happen

We would need more information to investigate. Preferably step-by-step instructions to reproduce.

---

<div class="post-metadata">

**Author:** ![hherhold](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/hherhold/32/12199_2.png) [@hherhold](https://discourse.slicer.org/u/hherhold)\
**Post date:** [April 11, 2021, 1:03am UTC](https://discourse.slicer.org/t/improve-markups-label-visibility/17022/8 "2021-04-11T01:03:31Z")

</div>

Yeah, sorry, that was a pretty useless observation. I’ll try to get something more concrete… I just have a few scenes where drop shadows don’t seem to show. I’ll work on steps to reproduce.

---

<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:** [April 11, 2021, 1:30am UTC](https://discourse.slicer.org/t/improve-markups-label-visibility/17022/9 "2021-04-11T01:30:15Z")

</div>

> [@pieper](#):
>
> Yes, that’s what the drop shadow does, but our default markup color is too dark.

I meant the line/curve itself as well, not just the markups label. Even in your example above, part of the the yellow line is hard to see.

Also in the stable version, the two unselected and active color is either identical or too close to differentiate (I really can’t tell). I set them to be different, and then hit Save as Defaults, but this is not retained after Slicer is restarted. Is this a bug or a color defaults are not meant to be saved ? In comparison glyph/text size changes are saved and retained correctly.

![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/c/b/cb1034a5ecd4b1b768e277fa41cb661ba2291b4b.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:** [April 11, 2021, 1:46pm UTC](https://discourse.slicer.org/t/improve-markups-label-visibility/17022/10 "2021-04-11T13:46:01Z")

</div>

Currently, only “basic” display properties can be saved as default. This made sense when there were not too many display properties, but now there are dozens, and it is very hard to select a meaningful subset. So, I’ll change the implementation to save/restore all display properties.

I agree that we would need high-contrast outline for lines and markers as well. One option is to use additional rendering passes, such as Gaussian or glow pass, but that would require some work (adding two additional rendering layers and improve image quality of these rendering passes, because glow pass is optimized for adding bright glow and not dark shadow and the outline is not continuous; Gaussian step is hardcoded to 5 pixels, which is not sufficient as a border).

Example of glow pass:

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/1/e/1e37f2168888a3a98b78a82a5e09adca61a2c701.jpeg)

> **Code to test custom rendering passes**
>
> ```python
> newRenderer=False
> gaussian=False
> 
> if newRenderer:
> iren = vtk.vtkRenderWindowInteractor()
> renWin = vtk.vtkRenderWindow()
> renWin.SetMultiSamples(0)
> iren.SetRenderWindow(renWin)
> renderer = vtk.vtkRenderer()
> rendererOutline = vtk.vtkRenderer()
> rendererOutline.SetLayer(1)
> renWin.SetNumberOfLayers(2)
> renWin.AddRenderer(rendererOutline)
> renWin.AddRenderer(renderer)
> else:
> layoutManager = slicer.app.layoutManager()
> view = layoutManager.sliceWidget('Red').sliceView()
> renderWindow = view.renderWindow()
> renderers = renderWindow.GetRenderers()
> renderer = renderers.GetItemAsObject(0)
> renderWindow.SetNumberOfLayers(renderWindow.GetNumberOfLayers()+2)
> renderer = vtk.vtkRenderer()
> rendererOutline = vtk.vtkRenderer()
> if gaussian:
> renderer.SetLayer(renderWindow.GetNumberOfLayers()-1)
> rendererOutline.SetLayer(renderWindow.GetNumberOfLayers()-2)
> else:
> renderer.SetLayer(renderWindow.GetNumberOfLayers()-2)
> rendererOutline.SetLayer(renderWindow.GetNumberOfLayers()-1)
> renderWindow.AddRenderer(renderer)
> renderWindow.AddRenderer(rendererOutline)
> 
> basicPasses = vtk.vtkRenderStepsPass()
> if gaussian:
> glowPass = vtk.vtkGaussianBlurPass()
> else:
> glowPass = vtk.vtkOutlineGlowPass()
> glowPass.SetOutlineIntensity(1.0)
> 
> glowPass.SetDelegatePass(basicPasses)
> 
> # Apply the render pass to the highlight renderer
> rendererOutline.SetPass(glowPass)
> 
> outlineColor = [1.0, 1.0, 1.0]
> 
> # Create mapper and actor for the main renderer
> coneSource = vtk.vtkConeSource()
> coneMapperMain = vtk.vtkPolyDataMapper()
> coneMapperMain.SetInputConnection(coneSource.GetOutputPort())
> coneActorMain = vtk.vtkActor()
> coneActorMain.SetMapper(coneMapperMain)
> renderer.AddActor(coneActorMain)
> 
> # Create mapper and actor for the outline
> coneMapperOutline = vtk.vtkPolyDataMapper()
> coneMapperOutline.SetInputConnection(coneSource.GetOutputPort())
> coneActorOutline = vtk.vtkActor()
> coneActorOutline.SetMapper(coneMapperOutline)
> coneActorOutline.GetProperty().SetColor(outlineColor)
> coneActorOutline.GetProperty().LightingOff()
> rendererOutline.AddActor(coneActorOutline)
> 
> fontSize=20
> textActor = vtk.vtkTextActor()
> textActor.SetDisplayPosition(100, 100);
> textActor.SetVisibility(True)
> textActor.GetTextProperty().SetFontSize(fontSize)
> textActor.GetTextProperty().SetColor(0,0,0)
> textActor.SetInput("This is a test")
> renderer.AddActor(textActor)
> 
> textActorOutline = vtk.vtkTextActor()
> textActorOutline.SetDisplayPosition(100, 100);
> textActorOutline.SetVisibility(True)
> textActorOutline.GetTextProperty().SetColor(outlineColor)
> textActorOutline.GetTextProperty().SetFontSize(fontSize)
> textActorOutline.SetInput("This is a test")
> rendererOutline.AddActor(textActorOutline)
> 
> if newRenderer:
> renWin.SetSize(400, 400)
> renderer.ResetCamera()
> camera = renderer.GetActiveCamera()
> camera.Azimuth(-40.0)
> camera.Elevation(20.0)
> renderer.ResetCamera()
> rendererOutline.SetActiveCamera(camera)
> renWin.Render()
> iren.Start()
> 
> ```

Another option is to render thicker dark line in the same renderer behind the normal line:

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

With enabling FXAA anti-aliasing (to make the line edges smoother):

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

> **Code snippet to enable FXAA anti-aliasing**
>
> ```python
> view = slicer.app.layoutManager().sliceWidget('Red').sliceView()
> #view = slicer.app.layoutManager().threeDWidget(0).threeDView()
> renderWindow = view.renderWindow()
> renderers = renderWindow.GetRenderers()
> for renderer in renderers:
> renderer.UseFXAAOn()
> 
> ```

Probably we should expose FXAA anti-aliasing option to users, too. It performs smart smoothing in the rendered image (only smoothing at sharp edges), which may impact anything in the rendering layer, but if we render markups in a separate layer (which is easy to do in slice views) then we can ensure that only markups edges are smoothed.

---

<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:** [April 11, 2021, 8:16pm UTC](https://discourse.slicer.org/t/improve-markups-label-visibility/17022/11 "2021-04-11T20:16:09Z")

</div>

I’ve submitted a pull request to enable bold and shadow by default for markup labels, a potential fix for the issue when shadow cannot be enabled, and saving/restoring all markups display properties as default:

> <https://github.com/Slicer/Slicer/pull/5580>

I’ve added an issue to track the remaining enhancement ideas:

> <https://github.com/Slicer/Slicer/issues/5579>
>
> Markup lines and text are not well visible when their color is similar to background color.
> Edges of markup lines and curves...

---

<div class="post-metadata">

**Author:** ![hherhold](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/hherhold/32/12199_2.png) [@hherhold](https://discourse.slicer.org/u/hherhold)\
**Post date:** [May 12, 2021, 9:50pm UTC](https://discourse.slicer.org/t/improve-markups-label-visibility/17022/12 "2021-05-12T21:50:00Z")

</div>

I think I was able to find out _what_ was happening with shadows not showing up but not _why_. In a scene where I didn’t see any drop shadows, the scene MRML had the `textProperty` setting for the `MarkupsFiducialDisplay` node set with `text-shadow:0px 0px 2px rgba(0,0,0,1.0);`. All I had to do was manually change it to `text-shadow:2px 2px 2px rgba(0,0,0,1.0);` and drop shadows showed up.

---

<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, 2021, 2:37pm UTC](https://discourse.slicer.org/t/improve-markups-label-visibility/17022/13 "2021-05-22T14:37:13Z")

</div>

These corrupted values were saved in the scene due to a bug (that I fixed in April).
