private async Task <Tuple <int, ushort[]> > LoadLayerProbabilisticAsync(ExportPredicitonDialog dialog, int width, int stride, int height, int[] selectedIndices, int constLayerIndex) { return(await Task.Run(() => { var layerData = new ushort[stride *height]; Parallel.ForEach(Partitioner.Create(0, height), range => { for (var y = range.Item1; y < range.Item2; ++y) { for (var x = 0; x < width; ++x) { double totalProbability = 0; foreach (int selectedIndex in selectedIndices) { var probability = _probabilities[y][x][selectedIndex]; if (probability >= dialog.DialogViewModel.MinAcceptanceProbability) { totalProbability += probability; } } totalProbability = Math.Min(totalProbability, 1); var dataIndex = y * stride + x; layerData[dataIndex] = (ushort)(totalProbability * ushort.MaxValue); } } }); return new Tuple <int, ushort[]>(constLayerIndex, layerData); })); }
private async void ExportPredictionsAsync() { var dialog = new ExportPredicitonDialog(PredictProbabilities, _mainWindowViewModel.Layers.ToList()); if (dialog.ShowDialog() == true) { var exportPath = dialog.DialogViewModel.ExportPath; var layers = dialog.DialogViewModel.ExportLandCoverLayers; var width = _classificationOverlay.PixelWidth; var stride = width; var height = _classificationOverlay.PixelHeight; var exportTasks = new List <Task>(); NotBlocking = false; var scaleToUnrealLandscape = dialog.DialogViewModel.ScaleToUnrealLandscape; var layerTasks = new List <Task <Tuple <int, ushort[]> > >(); // Create landcovertype layers for (var layerIndex = 0; layerIndex < layers.Count; ++layerIndex) { var layer = layers[layerIndex]; var types = layer.LandCoverTypes; var selectedIndices = layer.SelectedTypeIndices; var constLayerIndex = layerIndex; layerTasks.Add(dialog.DialogViewModel.ExportAsProbabilities ? LoadLayerProbabilisticAsync(dialog, width, stride, height, selectedIndices, constLayerIndex) : LoadLayerAsync(width, stride, height, types, constLayerIndex)); } // TODO what if does not exist? var heightMapLayer = dialog.DialogViewModel.ExportLayers.First(l => l.IsHeightmap).Layer; int exportWidth, exportHeight, imageWidth, imageHeight; CalculateHeightmapExportDimensions(scaleToUnrealLandscape, heightMapLayer, out exportWidth, out exportHeight, out imageWidth, out imageHeight); // Export layers foreach (var exportLayer in dialog.DialogViewModel.ExportLayers) { if (exportLayer.Export) { var layer = exportLayer.Layer; var upperLeftImage = layer.WorldToImage * PredictionUpperLeftWorld; var bottomRightImage = layer.WorldToImage * PredictionBottomRightWorld; var upperLeftX = (int)upperLeftImage[0]; var upperLeftY = (int)upperLeftImage[1]; var bottomLeftX = (int)bottomRightImage[0]; var bottomLeftY = (int)bottomRightImage[1]; int predictionWidth = bottomLeftX - upperLeftX; int predictionHeight = bottomLeftY - upperLeftY; var layerImage = layer.BandImage; // TODO possible loss of precision var cropped = layerImage.Crop(upperLeftX, upperLeftY, predictionWidth, predictionHeight); // var scaled = cropped.Scale(exportWidth, exportHeight); var resized = cropped.Resize(imageWidth, imageHeight); var formatChanged = resized.ConvertFormat(exportLayer.Format); BitmapFrame.Create(cropped).SaveAsPng(Path.Combine(exportPath, layer.Name + "_cropped.png")); // BitmapFrame.Create(scaled).SaveAsPng(Path.Combine(exportPath, layer.Name + "_scaled.png")); BitmapFrame.Create(resized).SaveAsPng(Path.Combine(exportPath, layer.Name + "_resized.png")); BitmapFrame.Create(formatChanged).SaveAsPng(Path.Combine(exportPath, layer.Name + ".png")); } } // Export prediction layers var layersData = await Task.WhenAll(layerTasks); var outputLayers = layersData.OrderBy(t => t.Item1).Select(t => t.Item2).ToList(); for (var layerIndex = 0; layerIndex < outputLayers.Count; ++layerIndex) { var layer = layers[layerIndex]; var data = outputLayers[layerIndex]; var bitmap = BitmapSource.Create(width, height, 96, 96, PixelFormats.Gray16, null, data, width * 2); // Save layer as Gray16 if (scaleToUnrealLandscape) { var scaled = bitmap.Scale(exportWidth, exportHeight); var resized = scaled.Resize(imageWidth, imageHeight); var formatChanged = resized.ConvertFormat(PixelFormats.Gray16); BitmapFrame.Create(formatChanged).SaveAsPng(Path.Combine(exportPath, layer.Name)); } else { BitmapFrame.Create(bitmap).SaveAsPng(Path.Combine(exportPath, layer.Name)); } } // Finish Task.WaitAll(exportTasks.ToArray()); NotBlocking = true; } }