A histogram is often useful to visualize the distribution of values in a volume data set.
The getHistogram() method in SoVolumeData( C++ | Java | .NET ) returns a histogram for the volume as an array of integers and a count. The count is the number of bins in the histogram. Depending on the number of bins and the range of values the histogram represents, each bin may represent a single voxel value or a range of voxel values. When a volume is converted to LDM format, VolumeViz (by default) builds a histogram and stores the histogram in the LDM file header. When an application calls the getHistogram() method, VolumeViz asks the volume reader for the histogram. If the volume is in LDM format, the reader will normally have a histogram available (read from the file header) and the getHistogram() method returns quickly. Custom volume readers that have a pre-computed histogram can also satisfy this request quickly. For most volume data formats (and for in-memory volumes) the histogram must be computed by the getHistogram() method, which can take a lot of time for a large volume. In this case, if the application may need to re-use the histogram in subsequent runs, the application should store the histogram.
Internally VolumeViz uses the class SoVolumeHistogram( C++ | Java | .NET ) to build and manage a histogram. Applications can also use this class directly to build and query a histogram. An instance of SoVolumeHistogram( C++ | Java | .NET ) is not directly associated with an SoVolumeData( C++ | Java | .NET ) node. Instead the SoVolumeHistogram( C++ | Java | .NET ) builds a histogram from one or more buffers of data passed to the addValues() method. This allows the application to build a histogram for a region of a volume or even a single slice. The data access API (discussed in Section 1.10, “Data Access and Computing” can be used to get the data from the volume.
The current implementation of SoVolumeHistogram( C++ | Java | .NET ) has some limitations, in particular it is not possible to specify the number of bins in the histogram or the value range for integer data types. Applications using integer data types larger than one byte may wish to implement their own histogram computation to avoid these limitations.
For 1 byte data (SbDataType SIGNED_BYTE or UNSIGNED_BYTE): SoVolumeHistogram( C++ | Java | .NET ) always builds a histogram with 256 bins, spanning the range of possible values (-128 to 127 or 0 to 255). This case works well and the histogram corresponds to the (usual) 256 entries in the color map.
For integer data types larger than 1 byte: SoVolumeHistogram( C++ | Java | .NET ) always builds a histogram with 65536 bins (i.e. index is an unsigned short), spanning the range of possible values of the data type. For example, if the volume contains SIGNED_SHORT data values, the histogram has 65536 bins spanning the range -32768 to 32767. However if the actual range of data values is, for example, -2048 to 2047 (12 bit data), most of the bins in the histogram will be empty and the first non-empty bin in the histogram will be bin number 30720. Note that SoVolumeHistogram( C++ | Java | .NET ) ignores the setInputValueRange() method for integer data types. For these data types we recommend that the application build a new histogram from the non-empty bins.
For floating point data: SoVolumeHistogram( C++ | Java | .NET ) always builds a histogram with 65536 bins, spanning the specified data range or spanning the range -20000 to 20000 if range was specified. The data range may be specified when the volume is converted to LDM format (see section 22.2.5) and may be given to SoVolumeHistogram( C++ | Java | .NET ) using the setInputValueRange() method.
VolumeViz does not provide a class to plot the histogram. This can be done using standard Open Inventor primitives. Plotting a histogram can also be done more conveniently using the graphing classes in the MeshViz extension, for example PoRegularMesh1D( C++ | Java | .NET ), PoLinearBar( C++ | Java | .NET ), PoCurveFilling( C++ | Java | .NET ) and PoLinearAxis( C++ | Java | .NET ).