org.jaitools.media.jai.zonalstats
Class ZonalStatsDescriptor

java.lang.Object
  extended by javax.media.jai.OperationDescriptorImpl
      extended by org.jaitools.media.jai.zonalstats.ZonalStatsDescriptor
All Implemented Interfaces:
Serializable, javax.media.jai.OperationDescriptor, javax.media.jai.RegistryElementDescriptor

public class ZonalStatsDescriptor
extends javax.media.jai.OperationDescriptorImpl

Calculates a number of summary statistics, either for the whole data image or within zones defined in a separate zone image. When used without a zone image, all data image pixels are treated as belonging to a single zone 0. Optionally, an ROI can be provided to constrain which areas of the data image will be sampled for calculation of statistics.

Use of this operator is similar to the standard JAI statistics operators such as javax.media.jai.operator.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
NameTypeDescriptionDefault value
statsStatistic[]Statistics to calculateNO DEFAULT
bandsInteger[]Image bands to sample{0}
roiROIAn optional ROI to constrain samplingnull
zoneTransformAffineTransform Maps data image positions to zone image positions null (identity transform)
rangesCollection<Range>Ranges of values to include or excludenull (include all data values)
rangesTypeRange.Type How to treat values supplied via the "ranges" parameter Range.Type.INCLUDE
rangeLocalStatsBoolean If Ranges are supplied via the "ranges" parameter, whether to calculate statistics for each of them separately Boolean.FALSE
noDataRangesCollection<Range> Ranges of values to treat specifically as NODATA null (no NODATA values defined)

Since:
1.0
Version:
$Id$
Author:
Michael Bedward, Andrea Antonello, Daniele Romagnoli, GeoSolutions S.A.S.
See Also:
Result, Statistic, StreamingSampleStats, ZonalStats, Serialized Form

Field Summary
static String ZONAL_STATS_PROPERTY
          Property name used to retrieve the results
 
Fields inherited from class javax.media.jai.OperationDescriptorImpl
resources, sourceNames, supportedModes
 
Fields inherited from interface javax.media.jai.OperationDescriptor
NO_PARAMETER_DEFAULT
 
Constructor Summary
ZonalStatsDescriptor()
          Constructor.
 
Method Summary
 boolean validateArguments(String modeName, ParameterBlock pb, StringBuffer msg)
          Validates supplied parameters.
 
Methods inherited from class javax.media.jai.OperationDescriptorImpl
arePropertiesSupported, getDefaultSourceClass, 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, makeDefaultSourceClassList, validateArguments, validateParameters, validateParameters, validateRenderableArguments, validateRenderableSources, validateSources, validateSources
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

ZONAL_STATS_PROPERTY

public static final String ZONAL_STATS_PROPERTY
Property name used to retrieve the results

See Also:
Constant Field Values
Constructor Detail

ZonalStatsDescriptor

public ZonalStatsDescriptor()
Constructor.

Method Detail

validateArguments

public boolean validateArguments(String modeName,
                                 ParameterBlock pb,
                                 StringBuffer msg)
Validates supplied parameters.

Specified by:
validateArguments in interface javax.media.jai.OperationDescriptor
Overrides:
validateArguments in class javax.media.jai.OperationDescriptorImpl
Parameters:
modeName - the rendering mode
pb - the parameter block
msg - a StringBuffer to receive error messages
Returns:
true if parameters are valid; false otherwise


Copyright © 2009-2013. All Rights Reserved.