# CT opacity gradient piecewise function

**URL:** https://discourse.vtk.org/t/ct-opacity-gradient-piecewise-function/1274
**Category:** Support
**Created:** [July 4, 2019, 3:35pm UTC](https://discourse.vtk.org/t/ct-opacity-gradient-piecewise-function/1274 "2019-07-04T15:35:56Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![socd06](https://discourse.vtk.org/user_avatar/discourse.vtk.org/socd06/32/619_2.png) [@socd06](https://discourse.vtk.org/u/socd06)
#### Post date: [July 4, 2019, 3:35pm UTC](https://discourse.vtk.org/t/ct-opacity-gradient-piecewise-function/1274/1 "2019-07-04T15:35:56Z")

</div>

Hi, I’m going through examples from the textbook and user guide and I recently started working on [https://lorensen.github.io/VTKExamples/site/Cxx/Medical/MedicalDemo4/](https://lorensen.github.io/VTKExamples/site/Cxx/Medical/MedicalDemo4/)  
To volume render DICOM CT data.  
I can’t figure out what the exact opacity gradient piecewise function should be.

The example originally states:

> // The gradient opacity function is used to decrease the opacity  
> // in the “flat” regions of the volume while maintaining the opacity  
> // at the boundaries between tissue types. The gradient is measured  
> // as the amount by which the intensity changes over unit distance.  
> // For most medical data, the unit distance is 1mm.  
> vtkSmartPointer volumeGradientOpacity =  
> vtkSmartPointer::New();  
> volumeGradientOpacity-\>AddPoint(0, 0.0);  
> volumeGradientOpacity-\>AddPoint(90, 0.5);  
> volumeGradientOpacity-\>AddPoint(100, 1.0);`

Does this mean the point at 100 is equal to 1mm or does this change depending on the data used? Is there a formula or rule of thumb for this?

I’m using the [CQ500 CT dataset](http://headctstudy.qure.ai/dataset)  
which is 512x512 1mm slice thickness, I’m also not sure of the voxel size because of the metadata, I’ll read more on that if need be

---

<div class="post-metadata">

### Author: ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)
#### Post date: [July 4, 2019, 3:48pm UTC](https://discourse.vtk.org/t/ct-opacity-gradient-piecewise-function/1274/2 "2019-07-04T15:48:36Z")

</div>

> [@socd06](#):
>
> Does this mean the point at 100 is equal to 1mm or does this change depending on the data used? Is there a formula or rule of thumb for this?

Gradient opacity function X axis is gradient, Y axis is opacity. So X axis unit is something like voxel intensity change / mm.

Usually you don’t need to use gradient opacity (it creates a glass-like transparency effect), but if you need this then it is usually quite data dependent. It can create artifacts in noisy images, so you may want to keep the value at constant 1.0 and just slightly decrease it and/or filter the image to reduce noise.

You can use interactive transfer function editor in [Volume Rendering module](https://www.slicer.org/wiki/Documentation/Nightly/Modules/VolumeRendering) of [3D Slicer](https://www.slicer.org/) to design transfer functions that work well for you. You can also find a couple of presets for various imaging modalities and anatomies. Once you have the transfer functions you like, you can save the functions in a text file (see file format description [here](https://www.slicer.org/wiki/Documentation/Nightly/Modules/VolumeRendering#Format_of_Volume_Property_.28.vp.29_file)).

---

<div class="post-metadata">

### Author: ![socd06](https://discourse.vtk.org/user_avatar/discourse.vtk.org/socd06/32/619_2.png) [@socd06](https://discourse.vtk.org/u/socd06)
#### Post date: [July 5, 2019, 2:19pm UTC](https://discourse.vtk.org/t/ct-opacity-gradient-piecewise-function/1274/3 "2019-07-05T14:19:51Z")

</div>

Thanks for replying,  
I was just using 3D Slicer and the Volume Rendering module to get a better idea of how this worked. I also read a bit of the users manual and in it, the following is the typical gradient opacity for 8-bit unsigned data (page 160)

> vtkPiecewiseFunction gtfun  
> gtfun AddPoint 0 0.0  
> gtfun AddPoint 3 0.0  
> gtfun AddPoint 6 1.0  
> gtfun AddPoint 255 1.0

If I’m working with CT data which normally is unsigned int (16-bit) then something like this should work?

> volumeScalarOpacity-\>AddPoint(0, 0.00);  
> volumeScalarOpacity-\>AddPoint(150, 0.25);  
> volumeScalarOpacity-\>AddPoint(350, 0.50);  
> volumeScalarOpacity-\>AddPoint(850, 1);

---

<div class="post-metadata">

### Author: ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)
#### Post date: [July 5, 2019, 3:22pm UTC](https://discourse.vtk.org/t/ct-opacity-gradient-piecewise-function/1274/4 "2019-07-05T15:22:00Z")

</div>

Regardless how you store the data (8-bit or 16-bit integer, floating-point, …) the optimal gradient opacity transfer function choice depends entirely on your data and what parts of it you want to hide by making (semi)transparent.

Note that gradient opacity transfer function is rarely used. I would consider it as a “special effect” that must be used judiciously. You need to focus on getting scalar opacity and color transfer functions right, then tune material properties, and after that maybe play around with gradient opacity.

---

<div class="post-metadata">

### Author: ![socd06](https://discourse.vtk.org/user_avatar/discourse.vtk.org/socd06/32/619_2.png) [@socd06](https://discourse.vtk.org/u/socd06)
#### Post date: [July 5, 2019, 3:25pm UTC](https://discourse.vtk.org/t/ct-opacity-gradient-piecewise-function/1274/5 "2019-07-05T15:25:05Z")

</div>

Got it, I’d say my scalar opacity and color tfunctions are working fine so far. I’ll see if the conclusion I thought of makes my rendering better or worse. Thanks for the feedback.
