/// <summary> /// Prepares the result of the operation. /// </summary> /// <returns>The resulting object.</returns> protected override ISpectralGeometry PrepareResult() { _offset = new Int32[Source.Raster.NumberOfBands]; _factor = new Double[Source.Raster.NumberOfBands]; for (Int32 bandIndex = 0; bandIndex < Source.Raster.NumberOfBands; bandIndex++) { Int32 minIntensity = 0, maxIntensity = Source.Raster.HistogramValues[bandIndex].Count - 1; while (minIntensity < Source.Raster.HistogramValues[bandIndex].Count && Source.Raster.HistogramValues[bandIndex][minIntensity] == 0) { minIntensity++; } while (maxIntensity >= 0 && Source.Raster.HistogramValues[bandIndex][maxIntensity] == 0) { maxIntensity--; } if (minIntensity == maxIntensity) { _offset[bandIndex] = 0; _factor[bandIndex] = 1; } else { _offset[bandIndex] = -minIntensity; _factor[bandIndex] = (Double)RasterAlgorithms.RadiometricResolutionMax(Source.Raster.RadiometricResolution) / (maxIntensity - minIntensity); } } return(base.PrepareResult()); }
/// <summary> /// Computes the specified spectral value. /// </summary> /// <param name="rowIndex">The zero-based row index of the value.</param> /// <param name="columnIndex">The zero-based column index of the value.</param> /// <param name="bandIndex">The zero-based band index of the value.</param> /// <returns>The spectral value at the specified index.</returns> protected override UInt32 Compute(Int32 rowIndex, Int32 columnIndex, Int32 bandIndex) { // if threshold is specified, the magnitude of the gradient is computed if (_threshold > 0) { Double gradientRow = -Source.Raster.GetNearestValue(rowIndex - 1, columnIndex, bandIndex) + Source.Raster.GetNearestValue(rowIndex + 1, columnIndex, bandIndex); Double gradientColumn = -Source.Raster.GetNearestValue(rowIndex, columnIndex - 1, bandIndex) + Source.Raster.GetNearestValue(rowIndex, columnIndex + 1, bandIndex); // if the threshold is not reached, the original value is returned if (Math.Sqrt(gradientRow * gradientRow + gradientColumn * gradientColumn) < _threshold) { return(Source.Raster.GetValue(rowIndex, columnIndex, bandIndex)); } } Double filteredValue = 0; for (Int32 filterRowIndex = -_unsharpFilter.Radius; filterRowIndex <= _unsharpFilter.Radius; filterRowIndex++) { for (Int32 filterColumnIndex = -_unsharpFilter.Radius; filterColumnIndex <= _unsharpFilter.Radius; filterColumnIndex++) { filteredValue += Source.Raster.GetNearestValue(rowIndex + filterRowIndex, columnIndex + filterColumnIndex, bandIndex) * _unsharpFilter.Kernel[filterRowIndex + _unsharpFilter.Radius, filterColumnIndex + _unsharpFilter.Radius]; } } filteredValue = filteredValue / _unsharpFilter.Factor + _unsharpFilter.Offset; return(RasterAlgorithms.Restrict((1 + _amount) * Source.Raster.GetValue(rowIndex, columnIndex, bandIndex) - _amount * filteredValue, Source.Raster.RadiometricResolution)); }
/// <summary> /// Initializes a new instance of the <see cref="ClassificationChangeDetection{TResult}" /> class. /// </summary> /// <param name="source">The source.</param> /// <param name="operationMethod">The method.</param> /// <param name="parameters">The parameters.</param> /// <exception cref="System.ArgumentNullException"> /// The source is null. /// or /// The method is null. /// or /// The method requires parameters which are not specified. /// </exception> /// <exception cref="System.ArgumentException"> /// The source is invalid. /// or /// The target is invalid. /// or /// The specified source and result are the same objects, but the method does not support in-place operations. /// or /// The parameters do not contain a required parameter value. /// or /// The type of a parameter does not match the type specified by the method. /// or /// A parameter value does not satisfy the conditions of the parameter. /// </exception> protected ClassificationChangeDetection(ISpectralGeometry source, OperationMethod operationMethod, IDictionary <OperationParameter, Object> parameters) : base(source, default(TResult), operationMethod, parameters) { ISpectralGeometry reference = ResolveParameter <ISpectralGeometry>(SpectralOperationParameters.ClassificationReferenceGeometry); if (source.Raster == null) { throw new ArgumentException("The source geometry does not contain a raster image.", nameof(source)); } if (source.Raster.NumberOfBands != 1) { throw new ArgumentException("The source geometry does not contain a single band.", nameof(source)); } if (reference.Raster == null) { throw new ArgumentException("The reference geometry does not contain a raster image.", nameof(parameters)); } if (reference.Raster.NumberOfBands != 1) { throw new ArgumentException("The reference geometry does not contain a single band.", nameof(parameters)); } AreMatchingRasters = RasterAlgorithms.IsMatching(source.Raster, reference.Raster); Reference = reference; }
/// <summary> /// Computes the specified spectral value. /// </summary> /// <param name="rowIndex">The zero-based row index of the value.</param> /// <param name="columnIndex">The zero-based column index of the value.</param> /// <param name="bandIndex">The zero-based band index of the value.</param> /// <returns>The spectral value at the specified index.</returns> protected override UInt32 Compute(Int32 rowIndex, Int32 columnIndex, Int32 bandIndex) { if (_multipliers[bandIndex] == 0) { return(RasterAlgorithms.RadiometricResolutionMax(Source.Raster.RadiometricResolution) / 2 + 1); } return(RasterAlgorithms.Restrict(_multipliers[bandIndex] * Source.Raster.GetValue(rowIndex, columnIndex, bandIndex), Source.Raster.RadiometricResolution)); }
/// <summary> /// Prepares the result of the operation. /// </summary> /// <returns>The resulting object.</returns> protected override ISpectralGeometry PrepareResult() { for (Int32 bandIndex = 0; bandIndex < Source.Raster.NumberOfBands; bandIndex++) { _lowerThresholdValues[bandIndex] = RasterAlgorithms.ComputeHistogramBalance(Source.Raster[bandIndex].HistogramValues); } return(base.PrepareResult()); }
/// <summary> /// Computes the specified spectral value. /// </summary> /// <param name="rowIndex">The zero-based row index of the value.</param> /// <param name="columnIndex">The zero-based column index of the value.</param> /// <returns>The array containing the spectral values for each band at the specified index.</returns> public virtual UInt32[] Compute(Double rowIndex, Double columnIndex) { Double[] resultFloat = ComputeFloat(rowIndex, columnIndex); UInt32[] result = new UInt32[_raster.NumberOfBands]; for (Int32 bandIndex = 0; bandIndex < _raster.NumberOfBands; bandIndex++) { result[bandIndex] = RasterAlgorithms.Restrict(resultFloat[bandIndex], _raster.RadiometricResolution); } return(result); }
/// <summary> /// Computes the result of the operation. /// </summary> protected override void ComputeResult() { if (RasterAlgorithms.IsMatching(Source.Raster, _validationGeometry.Raster)) { MatchByIndices(); } else if (_validationGeometry.Raster.IsMapped && Source.Raster.IsMapped) { MatchByLocation(); } }
/// <summary> /// Initializes a new instance of the <see cref="KMeansClustering"/> class. /// </summary> /// <param name="source">The source.</param> /// <param name="target">The target.</param> /// <param name="parameters">The parameters.</param> /// <exception cref="System.ArgumentNullException"> /// The source is null. /// or /// The method is null. /// or /// The method requires parameters which are not specified. /// </exception> /// <exception cref="System.ArgumentException"> /// The parameters do not contain a required parameter value. /// or /// The type of a parameter does not match the type specified by the method. /// or /// The value of a parameter is not within the expected range. /// or /// The specified source and result are the same objects, but the method does not support in-place operations. /// or /// The source geometry does not contain raster data. /// or /// The raster format of the source is not supported by the method. /// </exception> public KMeansClustering(ISpectralGeometry source, ISpectralGeometry target, IDictionary<OperationParameter, Object> parameters) : base(source, target, SpectralOperationMethods.KMeansClustering, parameters) { _numberOfClusters = Convert.ToInt32(ResolveParameter(SpectralOperationParameters.NumberOfClusters)); _maximumIterations = Convert.ToInt32(ResolveParameter(CommonOperationParameters.NumberOfIterations)); if (_numberOfClusters == 0) _numberOfClusters = (Int32)(Math.Sqrt(Source.Raster.NumberOfRows * Source.Raster.NumberOfColumns) * Source.Raster.RadiometricResolution / 8); if (_maximumIterations == 0) _maximumIterations = _numberOfClusters; _maximumDifference = RasterAlgorithms.RadiometricResolutionMax(Source.Raster) / Source.Raster.NumberOfRows * Source.Raster.NumberOfColumns; }
/// <summary> /// Computes the parameters of the specified band. /// </summary> /// <param name="bandIndex">The band index.</param> private void ComputeParameters(Int32 bandIndex) { // source: http://en.wikipedia.org/wiki/Histogram_equalization IReadOnlyList <Int32> histogram = Source.Raster.HistogramValues[bandIndex]; _cumulativeDistributionValues[bandIndex] = new Double[histogram.Count]; // setting values _cumulativeDistributionValues[bandIndex][0] = Convert.ToDouble(histogram[0]) / (Source.Raster.NumberOfRows * Source.Raster.NumberOfColumns); for (Int32 i = 1; i < histogram.Count; i++) { _cumulativeDistributionValues[bandIndex][i] = _cumulativeDistributionValues[bandIndex][i - 1] + Convert.ToDouble(histogram[i]) / (Source.Raster.NumberOfRows * Source.Raster.NumberOfColumns); } // setting minimum Int32 minIndex = 0; for (Int32 i = 0; i < histogram.Count; i++) { if (histogram[i] != 0) { minIndex = i; break; } } _cumulativeDistributionMinimums[bandIndex] = _cumulativeDistributionValues[bandIndex][minIndex]; // setting maximum Int32 maxIndex = histogram.Count - 1; for (Int32 i = histogram.Count - 1; i >= 0; i--) { if (histogram[i] != 0) { maxIndex = i; break; } } _cumulativeDistributionMaximums[bandIndex] = _cumulativeDistributionValues[bandIndex][maxIndex]; // exponent _radiometricResolutionExponents[bandIndex] = Calculator.Pow(2, Source.Raster.RadiometricResolution); // radiometric value limit _radiometricValueLimits[bandIndex] = RasterAlgorithms.RadiometricResolutionMax(Source.Raster.RadiometricResolution); }
/// <summary> /// Computes the specified spectral value. /// </summary> /// <param name="rowIndex">The zero-based row index of the value.</param> /// <param name="columnIndex">The zero-based column index of the value.</param> /// <param name="bandIndex">The zero-based band index of the value.</param> /// <returns>The spectral value at the specified index.</returns> protected override UInt32 Compute(Int32 rowIndex, Int32 columnIndex, Int32 bandIndex) { Double[] filteredValues = new Double[_filter.Radius * _filter.Radius]; Int32 rowBase = rowIndex - _filter.Radius / 2; Int32 columnBase = columnIndex - _filter.Radius / 2; Int32 index = 0; for (Int32 k = 0; k < _filter.Radius; k++) { for (Int32 l = 0; l < _filter.Radius; l++) { filteredValues[index] += _filter.Kernel[k, l] * Source.Raster.GetNearestValue(rowBase + k, columnBase + l, bandIndex); index++; } } Array.Sort(filteredValues); return(RasterAlgorithms.Restrict(filteredValues[_filter.Radius * _filter.Radius / 2], Source.Raster.RadiometricResolution)); }
/// <summary> /// Computes the specified spectral value. /// </summary> /// <param name="rowIndex">The zero-based row index of the value.</param> /// <param name="columnIndex">The zero-based column index of the value.</param> /// <param name="bandIndex">The zero-based band index of the value.</param> /// <returns>The spectral value at the specified index.</returns> protected override UInt32 Compute(Int32 rowIndex, Int32 columnIndex, Int32 bandIndex) { if (_filters.Count == 0) { return(Source.Raster.GetValue(rowIndex, columnIndex, bandIndex)); } if (_filters.Count == 1) { Double filteredValue = 0; for (Int32 filterRowIndex = -_filters[0].Radius; filterRowIndex <= _filters[0].Radius; filterRowIndex++) { for (Int32 filterColumnIndex = -_filters[0].Radius; filterColumnIndex <= _filters[0].Radius; filterColumnIndex++) { filteredValue += Source.Raster.GetNearestValue(rowIndex + filterRowIndex, columnIndex + filterColumnIndex, bandIndex) * _filters[0].Kernel[filterRowIndex + _filters[0].Radius, filterColumnIndex + _filters[0].Radius]; } } return(RasterAlgorithms.Restrict(filteredValue / _filters[0].Factor + _filters[0].Offset, Source.Raster.RadiometricResolution)); } Double[] filteredValues = new Double[_filters.Count]; for (Int32 filterIndex = 0; filterIndex < _filters.Count; filterIndex++) { for (Int32 filterRowIndex = -_filters[filterIndex].Radius; filterRowIndex <= _filters[filterIndex].Radius; filterRowIndex++) { for (Int32 filterColumnIndex = -_filters[filterIndex].Radius; filterColumnIndex <= _filters[filterIndex].Radius; filterColumnIndex++) { filteredValues[filterIndex] += Source.Raster.GetNearestValue(rowIndex + filterRowIndex, columnIndex + filterColumnIndex, bandIndex) * _filters[filterIndex].Kernel[filterRowIndex + _filters[filterIndex].Radius, filterColumnIndex + _filters[filterIndex].Radius]; } } filteredValues[filterIndex] = filteredValues[filterIndex] / _filters[filterIndex].Factor + _filters[filterIndex].Offset; } return(RasterAlgorithms.Restrict(CombineValues(filteredValues), Source.Raster.RadiometricResolution)); }
/// <summary> /// Computes the specified spectral value. /// </summary> /// <param name="rowIndex">The zero-based row index of the value.</param> /// <param name="columnIndex">The zero-based column index of the value.</param> /// <param name="bandIndex">The zero-based band index of the value.</param> /// <returns> /// The spectral value at the specified index. /// </returns> protected override UInt32 Compute(Int32 rowIndex, Int32 columnIndex, Int32 bandIndex) { Int32 rowCenter = (_structuringElement.NumberOfRows - 1) / 2; Int32 columnCenter = (_structuringElement.NumberOfColumns - 1) / 2; Int32 firstRowIndex = rowIndex - rowCenter; Int32 firstColumnIndex = columnIndex - columnCenter; Double result = 0; for (Int32 row = 0; row < _structuringElement.NumberOfRows; row++) { for (Int32 column = 0; column < _structuringElement.NumberOfColumns; column++) { Double value = Source.Raster.GetNearestValue(firstRowIndex + row, firstColumnIndex + column, bandIndex) + _structuringElement[row, column]; if (value > result) { result = value; } } } return(RasterAlgorithms.Restrict(result, Source.Raster.RadiometricResolution)); }
/// <summary> /// Initializes a new instance of the <see cref="ClassificationMapValidation" /> class. /// </summary> /// <param name="source">The source.</param> /// <param name="parameters">The parameters.</param> /// <exception cref="System.ArgumentNullException">The source is null.</exception> /// <exception cref="System.ArgumentException"> /// The source is invalid. /// or /// The parameters do not contain a required parameter value. /// or /// The type of a parameter does not match the type specified by the method. /// or /// A parameter value does not satisfy the conditions of the parameter. /// </exception> public ClassificationMapValidation(ISpectralGeometry source, IDictionary <OperationParameter, Object> parameters) : base(source, null, SpectralOperationMethods.ClassificationMapValidation, parameters) { _validationGeometry = ResolveParameter <ISpectralGeometry>(SpectralOperationParameters.ClassificationValidationGeometry); _isValidationMatching = RasterAlgorithms.IsMatching(Source.Raster, _validationGeometry.Raster); }
/// <summary> /// Asserts the results for the specified band. /// </summary> /// <param name="source">The source raster.</param> /// <param name="sourceBandIndex">The band index of the source raster.</param> /// <param name="result">The resulting raster.</param> /// <param name="resultBandIndex">The band index of the resulting raster.</param> private void AssertResultForBand(IRaster source, Int32 sourceBandIndex, IRaster result, Int32 resultBandIndex) { Assert.AreEqual(source.HistogramValues[sourceBandIndex].Sum(), result.HistogramValues[resultBandIndex].Sum()); Assert.Greater(result.HistogramValues[resultBandIndex][0], 0); for (Int32 rowIndex = 0; rowIndex < result.NumberOfRows; rowIndex++) { for (Int32 columnIndex = 0; columnIndex < result.NumberOfColumns; columnIndex++) { Assert.GreaterOrEqual(result.GetValue(rowIndex, columnIndex, resultBandIndex), 0); Assert.LessOrEqual(result.GetValue(rowIndex, columnIndex, resultBandIndex), RasterAlgorithms.RadiometricResolutionMax(source.RadiometricResolution)); } } }
/// <summary> /// Computes the specified spectral value. /// </summary> /// <param name="rowIndex">The zero-based row index of the value.</param> /// <param name="columnIndex">The zero-based column index of the value.</param> /// <param name="bandIndex">The zero-based band index of the value.</param> /// <returns>The spectral value at the specified index.</returns> protected override UInt32 Compute(Int32 rowIndex, Int32 columnIndex, Int32 bandIndex) { // determining which four tiles are the closest to the actual pixel // upper left tile's tile-row index in the array of tiles Int32 upperLeftTileRowIndex = (_numberOfPixelRowsOfNormalTile % 2 == 0) ? (rowIndex + _numberOfPixelRowsOfNormalTile / 2 - 1) / _numberOfPixelRowsOfNormalTile - 1 : (rowIndex + _numberOfPixelRowsOfNormalTile / 2) / _numberOfPixelRowsOfNormalTile - 1; // upper left tile's tile-column index in the array of tiles Int32 upperLeftTileColumnIndex = (_numberOfPixelColumnsOfNormalTile % 2 == 0) ? (columnIndex + _numberOfPixelColumnsOfNormalTile / 2 - 1) / _numberOfPixelColumnsOfNormalTile - 1 : (columnIndex + _numberOfPixelColumnsOfNormalTile / 2) / _numberOfPixelColumnsOfNormalTile - 1; Int32 upperRightTileRowIndex = upperLeftTileRowIndex; // upper right tile's tile-row index in the array of tiles Int32 upperRightTileColumnIndex = upperLeftTileColumnIndex + 1; // upper right tile's tile-column index in the array of tiles Int32 lowerLeftTileRowIndex = upperLeftTileRowIndex + 1; // lower left tile's tile-row index in the array of tiles Int32 lowerLeftTileColumnIndex = upperLeftTileColumnIndex; // lower left tile's tile-column index in the array of tiles Int32 lowerRightTileRowIndex = upperLeftTileRowIndex + 1; // lower right tile's tile-row index in the array of tiles Int32 lowerRightTileColumnIndex = upperLeftTileColumnIndex + 1; // lower right tile's tile-column index in the array of tiles // the four values to be bilinearly interpolated, computed using the four used tiles' transformation formula // for the corresponding tile's (not adaptive!) histogram equalization Double upperLeftValue = 0; Double upperRightValue = 0; Double lowerLeftValue = 0; Double lowerRightValue = 0; if (!(upperLeftTileRowIndex == -1 || upperLeftTileColumnIndex == -1)) { upperLeftValue = PixelValueTransformation(Source.Raster.GetValue(rowIndex, columnIndex, bandIndex), bandIndex, _allTilesParameters[upperLeftTileRowIndex, upperLeftTileColumnIndex]); } if (!(upperRightTileRowIndex == -1 || upperRightTileColumnIndex == _tileNumberHorizontally)) { upperRightValue = PixelValueTransformation(Source.Raster.GetValue(rowIndex, columnIndex, bandIndex), bandIndex, _allTilesParameters[upperRightTileRowIndex, upperRightTileColumnIndex]); } if (!(lowerLeftTileRowIndex == _tileNumberVertically || lowerLeftTileColumnIndex == -1)) { lowerLeftValue = PixelValueTransformation(Source.Raster.GetValue(rowIndex, columnIndex, bandIndex), bandIndex, _allTilesParameters[lowerLeftTileRowIndex, lowerLeftTileColumnIndex]); } if (!(lowerRightTileRowIndex == _tileNumberVertically || lowerRightTileColumnIndex == _tileNumberHorizontally)) { lowerRightValue = PixelValueTransformation(Source.Raster.GetValue(rowIndex, columnIndex, bandIndex), bandIndex, _allTilesParameters[lowerRightTileRowIndex, lowerRightTileColumnIndex]); } // the weights of the upper tiles and the left tiles Double upperWeight = ((lowerLeftTileRowIndex * _numberOfPixelRowsOfNormalTile + _numberOfPixelRowsOfNormalTile / 2) - rowIndex) / (Double)((lowerLeftTileRowIndex * _numberOfPixelRowsOfNormalTile + _numberOfPixelRowsOfNormalTile / 2) - (upperLeftTileRowIndex * _numberOfPixelRowsOfNormalTile + _numberOfPixelRowsOfNormalTile / 2)); Double leftWeight = ((upperRightTileColumnIndex * _numberOfPixelColumnsOfNormalTile + _numberOfPixelColumnsOfNormalTile / 2) - columnIndex) / (Double)((upperRightTileColumnIndex * _numberOfPixelColumnsOfNormalTile + _numberOfPixelColumnsOfNormalTile / 2) - (upperLeftTileColumnIndex * _numberOfPixelColumnsOfNormalTile + _numberOfPixelColumnsOfNormalTile / 2)); Double value; if (upperLeftTileRowIndex == -1) { if (upperLeftTileColumnIndex == -1) { value = lowerRightValue; } else if (upperLeftTileColumnIndex >= 0 && upperLeftTileColumnIndex <= (_tileNumberHorizontally - 2)) { value = LinearInterpolation(lowerLeftValue, lowerRightValue, leftWeight); } else { value = lowerLeftValue; } } else if (upperLeftTileRowIndex >= 0 && upperLeftTileRowIndex <= (_tileNumberVertically - 2)) { if (upperLeftTileColumnIndex == -1) { value = LinearInterpolation(upperRightValue, lowerRightValue, upperWeight); } else if (upperLeftTileColumnIndex >= 0 && upperLeftTileColumnIndex <= (_tileNumberHorizontally - 2)) { value = BilinearInterpolation(upperLeftValue, lowerLeftValue, upperRightValue, lowerRightValue, upperWeight, leftWeight); } else { value = LinearInterpolation(upperLeftValue, lowerLeftValue, upperWeight); } } else { if (upperLeftTileColumnIndex == -1) { value = upperRightValue; } else if (upperLeftTileColumnIndex >= 0 && upperLeftTileColumnIndex <= (_tileNumberHorizontally - 2)) { value = LinearInterpolation(upperLeftValue, upperRightValue, leftWeight); } else { value = upperLeftValue; } } return(RasterAlgorithms.Restrict(value, Source.Raster.RadiometricResolution)); }
/// <summary> /// Computes the specified spectral value. /// </summary> /// <param name="rowIndex">The zero-based row index of the value.</param> /// <param name="columnIndex">The zero-based column index of the value.</param> /// <param name="bandIndex">The zero-based band index of the value.</param> /// <returns>The spectral value at the specified index.</returns> public virtual UInt32 Compute(Double rowIndex, Double columnIndex, Int32 bandIndex) { return(RasterAlgorithms.Restrict(ComputeFloat(rowIndex, columnIndex, bandIndex), _raster.RadiometricResolution)); }
/// <summary> /// Computes the specified spectral value. /// </summary> /// <param name="rowIndex">The zero-based row index of the value.</param> /// <param name="columnIndex">The zero-based column index of the value.</param> /// <param name="bandIndex">The zero-based band index of the value.</param> /// <returns>The spectral value at the specified index.</returns> protected override UInt32 Compute(Int32 rowIndex, Int32 columnIndex, Int32 bandIndex) { return(RasterAlgorithms.Restrict(Source.Raster.GetValue(rowIndex, columnIndex, bandIndex) * _factor[bandIndex] + _offset[bandIndex], Source.Raster.RadiometricResolution)); }
/// <summary> /// Computes the specified spectral value. /// </summary> /// <param name="rowIndex">The zero-based row index of the value.</param> /// <param name="columnIndex">The zero-based column index of the value.</param> /// <param name="bandIndex">The zero-based band index of the value.</param> /// <returns>The spectral value at the specified index.</returns> protected override UInt32 Compute(Int32 rowIndex, Int32 columnIndex, Int32 bandIndex) { return(RasterAlgorithms.Restrict(Math.Log(Source.Raster.GetFloatValue(rowIndex, columnIndex, bandIndex)), Source.Raster.RadiometricResolution)); }
/// <summary> /// Prepares the result of the operation. /// </summary> /// <returns>The resulting object.</returns> protected override ISpectralGeometry PrepareResult() { _peek = RasterAlgorithms.RadiometricResolutionMax(Source.Raster.RadiometricResolution); return(base.PrepareResult()); }