public class ZonalStatsDescriptor
extends javax.media.jai.OperationDescriptorImpl
Use of this operator is similar to the standard JAI statistics operators such as
HistogramDescriptor where the source image is
simply passed through to the destination image and the results of the operation are
retrieved as a property. For this operator the property name can be reliably
referred to via the ZONAL_STATS_PROPERTY constant.
The operator uses the StreamingSampleStats class for its
calculations, allowing it to handle very large images for statistics other than
Statistic.MEDIAN, for which the
Statistic.APPROX_MEDIAN alternative is provided.
Note that the source names for this operator are "dataImage" and "zoneImage" rather than the more typical JAI names "source0", "source1".
If a zone image is provided it must be of integral data type. By default, an identity mapping is used between zone and data images, ie. zone image pixel at x, y is mapped to the data image pixel at x, y. Any data image pixels that do not have a corresponding zone image pixel are ignored, thus the zone image bounds can be a subset of the data image bounds.
The user can also provide an AffineTransform to map data image
positions to zone image positions. For example, multiple data image pixels
could be mapped to a single zone image pixel.
The range of data image values that contribute to the analysis can be constrained
in two ways: with the "ranges" parameter and the "noDataRanges" parameter.
Each of these parameters take a Collection of Range objects.
The "ranges" parameter allows you to define values to include or exclude from
the calculations, the choice being specified by the associated "rangesType" parameter.
If "rangesType" is Range.Type#INCLUDE you can also request that
statistics be calculated separately for each range of values by setting the
"rangeLocalStats" parameter to Boolean.TRUE.
The "noDataRanges" parameter allows you to define values to treat as NODATA. As well as being excluded from calculations of statistics, the frequency of NODATA values is tracked by the operator and can be retrieved from the results.
Example of use...
RenderedImage myData = ...
RenderedImage myZones = ...
ParameterBlockJAI pb = new ParameterBlockJAI("ZonalStats");
pb.setSource("dataImage", myData);
pb.setSource("zoneImage", myZones);
Statistic[] stats = {
Statistic.MIN,
Statistic.MAX,
Statistic.MEAN,
Statistic.APPROX_MEDIAN,
Statistic.SDEV
};
pb.setParameter("stats", stats);
RenderedOp op = JAI.create("ZonalStats", pb);
ZonalStats stats = (ZonalStats) op.getProperty(ZonalStatsDescriptor.ZONAL_STATS_PROPERTY);
// print results to console
for (Result r : stats.results()) {
System.out.println(r);
}
The ZonalStats object returned by the getProperty method above allows
you to examine results by image band, zone and statistic as shown here...
ZonalStats stats = (ZonalStats) op.getProperty(ZonalStatsDescriptor.ZONAL_STATS_PROPERTY);
// print all results for band 0
for (Result r : stats.band(0).results()) {
System.out.println(r);
}
// print all result for band 2, zone 5
for (Result r : stats.band(2).zone(5).results()) {
System.out.println(r);
}
// print MEAN values for all zones in band 0
for (Result r : stats.band(0).statistics(Statistic.MEAN).results()) {
System.out.println(r);
}
Using the operator to calculate statistics for an area within the data image...
RenderedImage myData = ...
Rectangle areaBounds = ...
ROI roi = new ROIShape(areaBounds);
ParameterBlockJAI pb = new ParameterBlockJAI("ZonalStats");
pb.setSource("dataImage", myData);
pb.setParameter("roi", roi);
pb.setParameter("stats", someStats);
RenderedOp op = JAI.create("ZonalStats", pb);
ZonalStats stats = (ZonalStats) op.getProperty(ZonalStatsDescriptor.ZONAL_STATS_PROPERTY);
// print results to console
for (Result r : stats.results()) {
System.out.println(r);
}
Using an AffineTransform to map data image position to zone image position...
ParameterBlockJAI pb = new ParameterBlockJAI("ZonalStats");
pb.setSource("dataImage", myDataImage);
pb.setSource("zoneImage", myZoneImage);
pb.setParameter("stats", someStats);
AffineTransform tr = new AffineTransform( ... );
pb.setParameter("zoneTransform", tr);
Asking for statistics on multiple bands.
By default the stats are calculated on a single default 0 index band. It is possible also to request calculations on multiple bands, by passing the band indexes as a parameter.
ParameterBlockJAI pb = new ParameterBlockJAI("ZonalStats");
pb.setSource("dataImage", myDataImage);
pb.setSource("zoneImage", myZoneImage);
pb.setParameter("stats", someStats);
// ask for stats on band 0 and 2 of the image
pb.setParameter("bands", new Integer[]{0, 2});
RenderedOp op = JAI.create("ZonalStats", pb);
// get the results
ZonalStats> stats = (ZonalStats) op.getProperty(ZonalStatsDescriptor.ZONAL_STATS_PROPERTY);
// results by band
List resultsBand0 = stats.band(0).results;
List resultsBand2 = stats.band(2).results;
Excluding data values from the analysis with the "noDataRanges" parameter:
ParameterBlockJAI pb = new ParameterBlockJAI("ZonalStats");
...
// exclude values between -5 and 5 inclusive
List<Range<Double>> excludeList = CollectionFactory.newList();
excludeList.add(Range.create(-5, true, 5, true));
pb.setParameter("noDataRanges", excludeList);
// after we run the operator and get the results we can examine
// how many sample values were included in the calculation
List results = zonalStats.results();
for (Result r : results) {
int numUsed = r.getNumAccepted();
int numExcluded = r.getNumOffered() - numUsed;
...
}
Parameters
| Name | Type | Description | Default value |
|---|---|---|---|
| stats | Statistic[] | Statistics to calculate | NO DEFAULT |
| bands | Integer[] | Image bands to sample | {0} |
| roi | ROI | An optional ROI to constrain sampling | null |
| zoneTransform | AffineTransform | Maps data image positions to zone image positions | null (identity transform) |
| ranges | Collection<Range> | Ranges of values to include or exclude | null (include all data values) |
| rangesType | Range.Type | How to treat values supplied via the "ranges" parameter | Range.Type.INCLUDE |
| rangeLocalStats | Boolean | If Ranges are supplied via the "ranges" parameter, whether to calculate statistics for each of them separately | Boolean.FALSE |
| noDataRanges | Collection<Range> | Ranges of values to treat specifically as NODATA | null (no NODATA values defined) |
Result,
Statistic,
StreamingSampleStats,
ZonalStats,
Serialized Form| Modifier and Type | Field and Description |
|---|---|
static String |
ZONAL_STATS_PROPERTY
Property name used to retrieve the results
|
| Constructor and Description |
|---|
ZonalStatsDescriptor()
Constructor.
|
| Modifier and Type | Method and Description |
|---|---|
boolean |
validateArguments(String modeName,
ParameterBlock pb,
StringBuffer msg)
Validates supplied parameters.
|
arePropertiesSupported, getDestClass, getDestClass, getInvalidRegion, getName, getNumParameters, getNumSources, getParamClasses, getParamDefaults, getParamDefaultValue, getParameterListDescriptor, getParamMaxValue, getParamMinValue, getParamNames, getPropertyGenerators, getPropertyGenerators, getRenderableDestClass, getRenderableSourceClasses, getResourceBundle, getResources, getSourceClasses, getSourceClasses, getSourceNames, getSupportedModes, isImmediate, isModeSupported, isRenderableSupported, isRenderedSupported, validateArguments, validateRenderableArgumentspublic static final String ZONAL_STATS_PROPERTY
public boolean validateArguments(String modeName, ParameterBlock pb, StringBuffer msg)
validateArguments in interface javax.media.jai.OperationDescriptorvalidateArguments in class javax.media.jai.OperationDescriptorImplmodeName - the rendering modepb - the parameter blockmsg - a StringBuffer to receive error messagestrue if parameters are valid; false otherwiseCopyright © 2009–2018. All rights reserved.