public static async Task <InpaintingResult> InpaintImage([ActivityTrigger] NnfInputData input) { var container = BlobHelper.OpenBlobContainer(input.Container); var imageBlob = container.GetBlockBlobReference(input.Image); var image = (await BlobHelper.ConvertBlobToArgbImage(imageBlob)) .FromArgbToRgb(new[] { 0.0, 0.0, 0.0 }) .FromRgbToLab(); var inpaintAreaState = BlobHelper.ReadFromBlob <Area2DState>(input.InpaintAreaName, container); var inpaintArea = Area2D.RestoreFrom(inpaintAreaState); var nnfState = BlobHelper.ReadFromBlob <NnfState>(input.NnfName, container); var nnf = new Nnf(nnfState); nnf.Normalize(); // after we have the NNF - we calculate the values of the pixels in the inpainted area var inpaintResult = Inpaint(image, inpaintArea, nnf, input.K, input.Settings); await BlobHelper.SaveImageLabToBlob(image, container, input.Image); // TODO: remove it later it is for debug purpose. await BlobHelper.SaveImageLabToBlob(image, container, $"{input.LevelIndex}_{input.IterationIndex}.png"); return(inpaintResult); }
/// <summary> /// Normalizes the specified NNF. /// </summary> /// <param name="nnf">The NNF.</param> /// <exception cref="ArgumentNullException">nnf</exception> public static void Normalize(this Nnf nnf) { if (nnf == null) { throw new ArgumentNullException(nameof(nnf)); } var destArea = Area2D.Create(0, 0, nnf.DstWidth, nnf.DstHeight); nnf.Normalize(destArea); }
static void Main(string[] args) { const string basePath = "..\\..\\..\\..\\images"; const int patchSize = 5; var srcImageName = "t009.jpg"; // Prepare images var srcImage = GetLabImage(basePath, srcImageName); var destImage = GetLabImage(basePath, srcImageName); var ignoreArea = GetArea2D(basePath, "m009.png"); var destArea = ignoreArea.Dilation(patchSize * 2 + 1); // Init an nnf var nnf = new Nnf(destImage.Width, destImage.Height, srcImage.Width, srcImage.Height, patchSize); // Create a mapping of the areas on the dest and source areas. var imageArea = Area2D.Create(0, 0, srcImage.Width, srcImage.Height); var map = new Area2DMapBuilder() .InitNewMap(imageArea, imageArea) .SetIgnoredSourcedArea(ignoreArea) .Build(); // Prepage setting for the PM algorithm var settings = new PatchMatchSettings { PatchSize = patchSize }; var calculator = ImagePatchDistance.Cie76; var patchMatchNnfBuilder = new PatchMatchNnfBuilder(); // Create the nnf for the image(while ignoring some area) // with a couple of iterations. patchMatchNnfBuilder.RunRandomNnfInitIteration(nnf, destImage, srcImage, settings, calculator, map); patchMatchNnfBuilder.RunBuildNnfIteration(nnf, destImage, srcImage, NeighboursCheckDirection.Forward, settings, calculator, map); patchMatchNnfBuilder.RunBuildNnfIteration(nnf, destImage, srcImage, NeighboursCheckDirection.Backward, settings, calculator, map); // Create a mapping for the area that is a bit bigger // then ignored area. map = new Area2DMapBuilder() .InitNewMap(imageArea, imageArea) .ReduceDestArea(destArea) .SetIgnoredSourcedArea(ignoreArea) .Build(); patchMatchNnfBuilder.RunRandomNnfInitIteration(nnf, destImage, srcImage, settings, calculator, map); patchMatchNnfBuilder.RunBuildNnfIteration(nnf, destImage, srcImage, NeighboursCheckDirection.Forward, settings, calculator, map); patchMatchNnfBuilder.RunBuildNnfIteration(nnf, destImage, srcImage, NeighboursCheckDirection.Backward, settings, calculator, map); string fileName1 = @"..\..\..\nnf1_pure.png"; nnf .ToRgbImage() .FromRgbToBitmap() .SaveTo(fileName1, ImageFormat.Png); // Normalize the NNF in the ignored area. nnf.Normalize(ignoreArea); // Prepare results, save and show them string fileName2 = @"..\..\..\nnf2_normalized.png"; nnf .ToRgbImage() .FromRgbToBitmap() .SaveTo(fileName2, ImageFormat.Png) .ShowFile(); Console.WriteLine($"Nnf normalization is finished."); }