/// <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> /// Gets the number of categories the raster contains. /// </summary> /// <returns>The number of categories the raster contains.</returns> protected virtual Int32 GetNumberOfCategories(IRaster raster) { Int32 numberOfCategories = 0; for (Int32 rowIndex = 0; rowIndex < raster.NumberOfRows; rowIndex++) { for (Int32 columnIndex = 0; columnIndex < raster.NumberOfColumns; columnIndex++) { if (raster.GetValue(rowIndex, columnIndex, 0) > numberOfCategories) { numberOfCategories = (Int32)raster.GetValue(rowIndex, columnIndex, 0); } } } return(numberOfCategories + 1); }
/// <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> /// <param name="filterRadius">The radius of the filter.</param> private void AssertResultForBand(IRaster source, Int32 sourceBandIndex, IRaster result, Int32 resultBandIndex, Int32 filterRadius) { for (Int32 rowIndex = 0; rowIndex < result.NumberOfRows; rowIndex++) { for (Int32 columnIndex = 0; columnIndex < result.NumberOfColumns; columnIndex++) { Double filteredValue = 0; switch (result.Format) { case RasterFormat.Integer: for (Int32 filterRowIndex = -filterRadius; filterRowIndex <= filterRadius; filterRowIndex++) { for (Int32 filterColumnIndex = -filterRadius; filterColumnIndex <= filterRadius; filterColumnIndex++) { filteredValue += source.GetNearestValue(rowIndex + filterRowIndex, columnIndex + filterColumnIndex, sourceBandIndex); } } filteredValue /= Calculator.Square(2 * filterRadius + 1); Assert.AreEqual(Convert.ToUInt32(filteredValue), result.GetValue(rowIndex, columnIndex, resultBandIndex)); break; case RasterFormat.Floating: for (Int32 filterRowIndex = -filterRadius; filterRowIndex <= filterRadius; filterRowIndex++) { for (Int32 filterColumnIndex = -filterRadius; filterColumnIndex <= filterRadius; filterColumnIndex++) { filteredValue += source.GetNearestFloatValue(rowIndex + filterRowIndex, columnIndex + filterColumnIndex, sourceBandIndex); } } filteredValue /= Calculator.Square(2 * filterRadius + 1); Assert.AreEqual(filteredValue, result.GetFloatValue(rowIndex, columnIndex, resultBandIndex)); break; } } } }
/// <summary> /// Creates a raster image. /// </summary> /// <param name="other">The other raster image.</param> /// <returns>The produced raster image matching <paramref name="other"/>.</returns> /// <exception cref="System.ArgumentNullException">The other raster is null.</exception> public IRaster CreateRaster(IRaster other) { if (other == null) { throw new ArgumentNullException("other", "The other raster is null."); } IRaster raster = CreateRaster(other.Format, other.NumberOfBands, other.NumberOfRows, other.NumberOfColumns, other.RadiometricResolution, other.Mapper); switch (raster.Format) { case RasterFormat.Integer: for (Int32 bandIndex = 0; bandIndex < raster.NumberOfBands; bandIndex++) { for (Int32 rowIndex = 0; rowIndex < raster.NumberOfRows; rowIndex++) { for (Int32 columnIndex = 0; columnIndex < raster.NumberOfColumns; columnIndex++) { raster.SetValue(rowIndex, columnIndex, bandIndex, raster.GetValue(rowIndex, columnIndex, bandIndex)); } } } break; case RasterFormat.Floating: for (Int32 bandIndex = 0; bandIndex < raster.NumberOfBands; bandIndex++) { for (Int32 rowIndex = 0; rowIndex < raster.NumberOfRows; rowIndex++) { for (Int32 columnIndex = 0; columnIndex < raster.NumberOfColumns; columnIndex++) { raster.SetFloatValue(rowIndex, columnIndex, bandIndex, raster.GetFloatValue(rowIndex, columnIndex, bandIndex)); } } } break; } return(raster); }
/// <summary> /// Computes the histogram of the specified raster. /// </summary> /// <param name="raster">The raster.</param> /// <returns>The histogram of the raster.</returns> private Int32[][] ComputeHistogram(IRaster raster) { if (_histogramValues == null) { _histogramValues = new Int32[raster.NumberOfBands][]; for (Int32 bandIndex = 0; bandIndex < raster.NumberOfBands; bandIndex++) { _histogramValues[bandIndex] = new Int32[1UL << raster.RadiometricResolution]; for (Int32 rowIndex = 0; rowIndex < raster.NumberOfRows; rowIndex++) { for (Int32 columnIndex = 0; columnIndex < raster.NumberOfColumns; columnIndex++) { _histogramValues[bandIndex][raster.GetValue(rowIndex, columnIndex, bandIndex)]++; } } } } return(_histogramValues); }
/// <summary> /// Writes the raster of the geometry into a strip. /// </summary> /// <param name="raster">The raster.</param> /// <param name="compression">The compression.</param> /// <param name="format">The sample format.</param> private void WriteRasterContentToStrip(IRaster raster, TiffCompression compression, TiffSampleFormat format) { _baseStream.Seek(_currentImageStartPosition, SeekOrigin.Begin); // mark the starting position of the strip UInt32 numberOfBytes = (UInt32)(Math.Ceiling(raster.RadiometricResolution / 8.0) * raster.NumberOfBands * raster.NumberOfRows * raster.NumberOfColumns); UInt32 numberOfBytesLeft = numberOfBytes; if (numberOfBytes % 2 != 0) // correct the number of bytes { numberOfBytes++; } Byte[] bytes = new Byte[numberOfBytes < NumberOfWritableBytes ? numberOfBytes : NumberOfWritableBytes]; Int32 byteIndex = 0; Int32 bitIndex = 8; for (Int32 rowIndex = 0; rowIndex < raster.NumberOfRows; rowIndex++) { for (Int32 columnIndex = 0; columnIndex < raster.NumberOfColumns; columnIndex++) { // write the values for each band into the buffer for (Int32 bandIndex = 0; bandIndex < raster.NumberOfBands; bandIndex++) { switch (format) { case TiffSampleFormat.Undefined: case TiffSampleFormat.UnsignedInteger: WriteUnsignedIntergerValue(raster.GetValue(rowIndex, columnIndex, bandIndex), raster.RadiometricResolution, bytes, ref byteIndex, ref bitIndex); break; case TiffSampleFormat.SignedInteger: case TiffSampleFormat.Floating: WriteFloatValue(raster.GetFloatValue(rowIndex, columnIndex, bandIndex), raster.RadiometricResolution, bytes, ref byteIndex, ref bitIndex); break; } if (byteIndex == bytes.Length) { // write the buffer to the file _baseStream.Write(bytes, 0, byteIndex); byteIndex = 0; numberOfBytesLeft -= (UInt32)byteIndex; // the final array of bytes should not be the number of bytes left if (numberOfBytes > NumberOfWritableBytes && numberOfBytesLeft > 0 && numberOfBytesLeft < NumberOfWritableBytes) { bytes = new Byte[numberOfBytesLeft % 2 == 0 ? numberOfBytesLeft : numberOfBytesLeft + 1]; } } } } } // if any values are left if (numberOfBytesLeft > 0) { _baseStream.Write(bytes, 0, byteIndex); } }
public void ClassifiedImageChangeDetectionExecuteTest() { // loss Dictionary <OperationParameter, Object> parameters = new Dictionary <OperationParameter, Object>(); parameters.Add(SpectralOperationParameters.ClassificationReferenceGeometry, _reference); parameters.Add(SpectralOperationParameters.LossDetection, true); ClassifiedImageChangeDetection detection = new ClassifiedImageChangeDetection(_source, parameters); detection.Execute(); IRaster result = detection.Result.Raster; for (Int32 rowIndex = 0; rowIndex < 3; rowIndex++) { for (Int32 columnIndex = 0; columnIndex < 3; columnIndex++) { if ((rowIndex == 0 && columnIndex == 0) || (rowIndex == 2 && columnIndex == 2)) { Assert.AreEqual(0, result.GetValue(rowIndex, columnIndex, 2)); } else { Assert.AreEqual(2, result.GetValue(rowIndex, columnIndex, 2)); } } } // difference with loss parameters = new Dictionary <OperationParameter, Object>(); parameters.Add(SpectralOperationParameters.ClassificationReferenceGeometry, _reference); parameters.Add(SpectralOperationParameters.DifferentialChangeDetection, true); parameters.Add(SpectralOperationParameters.LossDetection, true); detection = new ClassifiedImageChangeDetection(_source, parameters); detection.Execute(); result = detection.Result.Raster; // band 1 for (Int32 rowIndex = 0; rowIndex < result.NumberOfRows; rowIndex++) { for (Int32 columnIndex = 0; columnIndex < result.NumberOfColumns; columnIndex++) { if ((rowIndex == 1 && columnIndex == 0) || (rowIndex == 0 && columnIndex == 1)) { Assert.AreEqual(2, result.GetValue(rowIndex, columnIndex, 1)); } else { Assert.AreEqual(0, result.GetValue(rowIndex, columnIndex, 1)); } } } // band 2 Assert.AreEqual(0, result.GetValue(0, 1, 2)); Assert.AreEqual(0, result.GetValue(1, 0, 2)); Assert.AreEqual(0, result.GetValue(2, 1, 2)); Assert.AreEqual(0, result.GetValue(1, 2, 2)); Assert.AreEqual(0, result.GetValue(0, 0, 2)); Assert.AreEqual(0, result.GetValue(0, 2, 2)); Assert.AreEqual(0, result.GetValue(1, 1, 2)); Assert.AreEqual(0, result.GetValue(2, 0, 2)); Assert.AreEqual(0, result.GetValue(2, 2, 2)); // band 3 for (Int32 rowIndex = 0; rowIndex < result.NumberOfRows; rowIndex++) { for (Int32 columnIndex = 0; columnIndex < result.NumberOfColumns; columnIndex++) { if ((rowIndex == 2 && columnIndex == 1) || (rowIndex == 1 && columnIndex == 2)) { Assert.AreEqual(2, result.GetValue(rowIndex, columnIndex, 3)); } else { Assert.AreEqual(0, result.GetValue(rowIndex, columnIndex, 3)); } } } // specified category index parameters = new Dictionary <OperationParameter, Object>(); parameters.Add(SpectralOperationParameters.ClassificationReferenceGeometry, _reference); parameters.Add(SpectralOperationParameters.DifferentialChangeDetection, true); parameters.Add(SpectralOperationParameters.LossDetection, true); parameters.Add(SpectralOperationParameters.ChangeDetectionCategoryIndex, 3); detection = new ClassifiedImageChangeDetection(_source, parameters); detection.Execute(); result = detection.Result.Raster; Assert.AreEqual(1, result.NumberOfBands); for (Int32 i = 0; i < 3; i++) { for (Int32 j = 0; j < 3; j++) { if ((i == 2 && j == 1) || (i == 1 && j == 2)) { Assert.AreEqual(2, result.GetValue(i, j, 0)); } else { Assert.AreEqual(0, result.GetValue(i, j, 0)); } } } // specified category indices parameters = new Dictionary <OperationParameter, Object>(); parameters.Add(SpectralOperationParameters.ClassificationReferenceGeometry, _reference); parameters.Add(SpectralOperationParameters.DifferentialChangeDetection, true); parameters.Add(SpectralOperationParameters.LossDetection, true); parameters.Add(SpectralOperationParameters.ChangeDetectionCategoryIndices, new[] { 3, 1 }); detection = new ClassifiedImageChangeDetection(_source, parameters); detection.Execute(); result = detection.Result.Raster; Assert.AreEqual(2, result.NumberOfBands); //Category 3 -> Band 0: for (Int32 rowIndex = 0; rowIndex < result.NumberOfRows; rowIndex++) { for (Int32 columnIndex = 0; columnIndex < result.NumberOfColumns; columnIndex++) { if ((rowIndex == 2 && columnIndex == 1) || (rowIndex == 1 && columnIndex == 2)) { Assert.AreEqual(2, result.GetValue(rowIndex, columnIndex, 0)); } else { Assert.AreEqual(0, result.GetValue(rowIndex, columnIndex, 0)); } } } //Category 1 -> Band 1: for (Int32 rowIndex = 0; rowIndex < result.NumberOfRows; rowIndex++) { for (Int32 columnIndex = 0; columnIndex < result.NumberOfColumns; columnIndex++) { if ((rowIndex == 1 && columnIndex == 0) || (rowIndex == 0 && columnIndex == 1)) { Assert.AreEqual(2, result.GetValue(rowIndex, columnIndex, 1)); } else { Assert.AreEqual(0, result.GetValue(rowIndex, columnIndex, 1)); } } } // source and reference match parameters = new Dictionary <OperationParameter, Object>(); parameters.Add(SpectralOperationParameters.ClassificationReferenceGeometry, _source); parameters.Add(SpectralOperationParameters.DifferentialChangeDetection, true); detection = new ClassifiedImageChangeDetection(_source, parameters); detection.Execute(); result = detection.Result.Raster; Assert.AreEqual(3, result.NumberOfRows); Assert.AreEqual(3, result.NumberOfColumns); Assert.AreEqual(4, result.NumberOfBands); for (Int32 bandIndex = 0; bandIndex < result.NumberOfBands; bandIndex++) { for (Int32 rowIndex = 0; rowIndex < result.NumberOfRows; rowIndex++) { for (Int32 columnIndex = 0; columnIndex < result.NumberOfColumns; columnIndex++) { Assert.AreEqual(0, result.GetValue(rowIndex, columnIndex, bandIndex)); } } } }
/// <summary> /// Returns the spectral value at a specified index. /// </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 ApplyGetValue(Int32 rowIndex, Int32 columnIndex, Int32 bandIndex) { return(_source.GetValue(_rowIndex + rowIndex, _columnIndex + columnIndex, bandIndex)); }
/// <summary> /// Gets a spectral value at a specified row and column index. /// </summary> /// <param name="rowIndex">The zero-based column index of the value.</param> /// <param name="columnIndex">The zero-based row index of the value.</param> /// <returns>The spectral value located at the specified row and column index.</returns> /// <exception cref="System.NotSupportedException">The raster is not readable.</exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// The row index is less than 0. /// or /// The row index is equal to or greater than the number of rows. /// or /// The column index is less than 0. /// or /// the column index is equal to or greater than the number of columns. /// </exception> public UInt32 GetValue(Int32 rowIndex, Int32 columnIndex) { return(_raster.GetValue(rowIndex, columnIndex, _bandIndex)); }