Estimating the gradient properly can be a difficult task because of the inherent noise in volume data. This is noise is especially exacerbated when computing directional derivatives (especially the second directional derivative). Thus I thought it proper to write an adequate gradient estimator first. To compute the gradient all one needs to do is to compute the partial derivative for each axis, ie.
I have experimented with four gradient operators:
-
Intemediate Difference Operator
-
Central Different Operator
-
Zucker-Hummel Operator
-
Sobel 3D Operator
Intermediate Difference Operator
The intermediate difference operator is a really simple operator, for each axis, we look at one neighbour and the value at the current voxel thus giving a total of voxels to sample from.
The operator for the x axis is:
We just extend the idea for the y and z axis.
From my experience this operator provided the least desirable images.
The central difference operator is similar to the intermediate difference operator except that we now look at 2 neighbours and igore the value at the current voxel. Thus we sample from 6 neighbours. The operator for the x axis is:
Again we extend the idea for the y and z axis.
From experience this operator provides acceptable results considering it is over 4 times faster than Zucker-Hummel or Sobel 3D.
The Zucker-Hummel operator looks at all 27 neighbours in a 3x3x3 grid. I could not find the original paper describing this operator, thus my implementation is based off of the implementation as descrived in "Confocal Volume Rendering: Fast Segmentation-Free Visualization of Internal Structures" by Mullick et al.
You find their description at the end of their paper.
It is worth noting that the description provided by Mullick et al. contains a terrible number of errors. Be very careful when using their equations. Thanks to various readers who pointed out the errors in their operator.
The Zucker-Hummel operator smoothes out the gradients much better than the Central Difference.
The Sobel 3D operator applies a 3x3x3 kernel to compute each of the partial derivatives.
The kernel for the x direction that I used is:
| ||
x-1 | x | x+1 |
To obtain the kernel for the y and z directions we just rotate this kernel as required
Thus the kernel for y becomes:
y-1 | y | y+1 |
And the kernel for z becomes:
z-1 | z | z+1 |
From my experience the Sobel 3D operator provides not only the most 'correct' gradients but the filtering properties of the kernel are very effective in reducing noise and aliasing artefacts.
In order to compare these various gradient estimators I have rendered the CT Visible Human data set with an ISO renderer. The parameters for my render are as follows:
- 512x512 final output image
- 300 samples / ray
- Trilinear and Nearest Neighbour filtering
- ISO Threshold was set to 0.55 of the volume value which translates to about 140.25 as the volume value
- Lighting properties:
- 20% ambient
- 60% diffuse
- 70% specular
- phong exponent was 16
- Light was rotated about the x-axis 45 degrees
CLICK ON THE IMAGES TO VIEW THE FULL VERSION
UPDATE: The images generated for the Zucker-Hummel operator are not correct since various bugs in the code have been fixed, yet images not re-rendered.
Nearest Neighbour Filtering
Tri-linear Filtering