private void PreProcess(IImageReader <T2> reader, ImageFormat imageFormat, int amount, int?outputSize) { Ensure.ArgumentNotNull(reader, nameof(reader)); if (amount > 1) { // count labels of images for the defined amount for each axis IList <PositionAxisContainerModel <ulong> > labels = new List <PositionAxisContainerModel <ulong> >(); IDictionary <AxisType, int[]> newMap = new Dictionary <AxisType, int[]>(); IAxisPositionMapper mapper = reader.Mapper; if (mapper == null) { throw new UnexpectedNullException("The image reader does not contain a mapper."); } foreach (AxisType axisType in (AxisType[])Enum.GetValues(typeof(AxisType))) { int length = mapper.GetLength(axisType); newMap[axisType] = new int[Math.Min(amount, length)]; for (int i = 0; i < newMap[axisType].Length; i++) { // set initial mapped positions newMap[axisType][i] = mapper.GetMappedPosition(axisType, i); var labelCount = reader.GetLabelCount(axisType, i); labels.Add(new PositionAxisContainerModel <ulong>(i, axisType, labelCount)); } } // calculate new mapped positions based on the labels foreach (AxisType axisType in (AxisType[])Enum.GetValues(typeof(AxisType))) { var candidates = labels .Where(e => e.AxisType == axisType) .Where(e => e.Entity > 1) .OrderBy(e => e.Position); var startPosition = candidates.FirstOrDefault(); var endPosition = candidates.LastOrDefault(); if (startPosition != null && endPosition != null) { if (startPosition == endPosition) { newMap[axisType] = new int[1]; newMap[axisType][0] = mapper.GetMappedPosition(axisType, startPosition.Position); } else { // calculate mappedPosition between startPosition and endPosition int mappedStartPosition = mapper.GetMappedPosition(axisType, startPosition.Position); int mappedEndPosition = mapper.GetMappedPosition(axisType, endPosition.Position); int length = mappedEndPosition - mappedStartPosition; if (length >= newMap[axisType].Length) { for (int i = 0; i < newMap[axisType].Length; i++) { newMap[axisType][i] = mappedStartPosition + mapper.CalculateMappedPosition(amount, length, i); } } } } } // set a new mapper with the new map reader.Mapper = new AxisPositionMapper(newMap); } }
private void PreProcess(IImageReader <T2> reader, ImageFormat imageFormat, uint amount, uint?desiredSize) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (amount > 1) { // calculate hashes of images for the defined amount for each axis IList <PositionAxisContainerModel <string> > hashes = new List <PositionAxisContainerModel <string> >(); IDictionary <AxisType, uint[]> newMap = new Dictionary <AxisType, uint[]>(); IAxisPositionMapper mapper = reader.Mapper; if (mapper == null) { throw new UnexpectedNullException("The image reader does not contain a mapper."); } foreach (AxisType axisType in (AxisType[])Enum.GetValues(typeof(AxisType))) { newMap[axisType] = new uint[amount]; for (uint i = 0; i < amount; i++) { // set initial mapped positions newMap[axisType][i] = mapper.GetMappedPosition(axisType, i); using (var bitmap = reader.ExtractPosition(axisType, i, desiredSize)) { if (bitmap != null) { string hash = Cryptography.CalculateSHA1Hash(bitmap.ToByteArray(imageFormat)); hashes.Add(new PositionAxisContainerModel <string>(i, axisType, hash)); } } } } // calculate new mapped positions based on the hashes foreach (AxisType axisType in (AxisType[])Enum.GetValues(typeof(AxisType))) { var axisHashes = hashes.Where(e => e.AxisType == axisType); // find the most likely hash representing an empty image string emptyHash = axisHashes.GroupBy(e => e.Entity) .Where(e => e.Count() > 1).OrderBy(e => e.Count()).Select(e => e.Key).FirstOrDefault(); if (emptyHash != null) { var nonEmptyHashes = axisHashes.Where(e => e.Entity != emptyHash).OrderBy(e => e.Position); var startPosition = nonEmptyHashes.FirstOrDefault(); var endPosition = nonEmptyHashes.LastOrDefault(); if (startPosition != null && endPosition != null) { if (startPosition == endPosition) { // set the same mappedPosition for all positions for (int i = 0; i < amount; i++) { newMap[axisType][i] = mapper.GetMappedPosition(axisType, startPosition.Position); } } else { // calculate mappedPosition between startPosition and endPosition uint mappedStartPosition = mapper.GetMappedPosition(axisType, startPosition.Position); uint mappedEndPosition = mapper.GetMappedPosition(axisType, endPosition.Position); uint length = mappedEndPosition - mappedStartPosition; for (uint i = 0; i < amount; i++) { newMap[axisType][i] = mappedStartPosition + mapper.CalculateMappedPosition(amount, length, i); } } } } } // TODO: distribute equally (newMap) to avoid re-use of the same image excessively compared to others /* * Request: * - Extract x images and each image at least once. * Special case: * - Less than x images can be extracted. * Preferred behaviour: * - Prioritize images in the middle for re-use. */ // set a new mapper with the new map reader.Mapper = new AxisPositionMapper(newMap); } }