Beispiel #1
0
        private static ZsImage CopyImageArea(ZsImage imageArgb, Area2D imageSrcArea)
        {
            var pixels        = Enumerable.Repeat(0.0, imageSrcArea.Bound.Width * imageSrcArea.Bound.Height * 4).ToArray();
            var resultImage   = new ZsImage(pixels, imageSrcArea.Bound.Width, imageSrcArea.Bound.Height, 4);
            var imageArgbArea = Area2D.Create(0, 0, imageSrcArea.Bound.Width, imageSrcArea.Bound.Height);

            resultImage.CopyFromImage(imageArgbArea, imageArgb, imageSrcArea);
            return(resultImage);
        }
Beispiel #2
0
        static void Main(string[] args)
        {
            const string basePath = "..\\..\\..\\..\\images";

            ZsImage srcImage  = GetArgbImage(basePath, "t009.jpg");
            ZsImage destImage = srcImage.Clone();

            var srcMarkup  = GetArea2D(basePath, "m009.png");
            var destMarkup = srcMarkup.Translate(-300, -30);

            destImage.CopyFromImage(destMarkup, destImage, srcMarkup);
            destImage.FromArgbToBitmap()
            .SaveTo("..\\..\\..\\target.png", ImageFormat.Png);

            // Prepage setting for the PM algorithm
            const byte patchSize = 5;
            var        settings  = new PatchMatchSettings {
                PatchSize = patchSize
            };

            // Init an nnf
            var nnf = new Nnf(destImage.Width, destImage.Height, srcImage.Width, srcImage.Height, patchSize);

            srcImage.FromArgbToRgb(new[] { 1.0, 1.0, 1.0 })
            .FromRgbToLab();

            destImage.FromArgbToRgb(new[] { 1.0, 1.0, 1.0 })
            .FromRgbToLab();

            destImage
            .Clone()
            .FromLabToRgb()
            .FromRgbToBitmap()
            .SaveTo($"..\\..\\..\\dest.png", ImageFormat.Png);

            var patchMatchNnfBuilder = new PatchMatchNnfBuilder();

            patchMatchNnfBuilder.RunRandomNnfInitIteration(nnf, destImage, srcImage, settings);

            for (int j = 0; j < 3; j++)
            {
                patchMatchNnfBuilder.RunBuildNnfIteration(nnf, destImage, srcImage, NeighboursCheckDirection.Forward, settings);
                Console.WriteLine($"\tIteration {j * 2}");
                patchMatchNnfBuilder.RunBuildNnfIteration(nnf, destImage, srcImage, NeighboursCheckDirection.Backward, settings);
                Console.WriteLine($"\tIteration {j * 2 + 1}");
            }

            nnf.ToRgbImage()
            .FromRgbToBitmap()
            .SaveTo($"..\\..\\..\\nnf.png", ImageFormat.Png);

            nnf.RestoreImage(srcImage, 3, patchSize)
            .FromLabToRgb()
            .FromRgbToBitmap()
            .SaveTo($"..\\..\\..\\restored.png", ImageFormat.Png);
        }
Beispiel #3
0
        private static ZsImage AlignImage(ZsImage wrongSizedImageArgb, ZsImage correctSizedImageArgb)
        {
            var correctArea    = Area2D.Create(0, 0, correctSizedImageArgb.Width, correctSizedImageArgb.Height);
            var wrongArea      = Area2D.Create(0, 0, wrongSizedImageArgb.Width, wrongSizedImageArgb.Height);
            var srcArea        = wrongArea.Intersect(correctArea);
            var pixels         = Enumerable.Repeat(0.0, correctSizedImageArgb.Width * correctSizedImageArgb.Height * 4).ToArray();
            var correctedImage = new ZsImage(pixels, correctSizedImageArgb.Width, correctSizedImageArgb.Height, 4);

            return(correctedImage.CopyFromImage(correctArea, wrongSizedImageArgb, srcArea));
        }
Beispiel #4
0
        public ZsImage Inpaint(ZsImage imageArgb, ZsImage markupArgb, InpaintSettings settings, IEnumerable <ZsImage> donorsArgb = null)
        {
            #region validate the inputs

            if (imageArgb == null)
            {
                throw new ArgumentNullException(nameof(imageArgb));
            }

            if (imageArgb.NumberOfComponents != 4)
            {
                throw new BadImageFormatException($"{nameof(imageArgb)} is expected to be in ARGB format");
            }

            if (markupArgb == null)
            {
                throw new ArgumentNullException(nameof(markupArgb));
            }

            if (markupArgb.NumberOfComponents != 4)
            {
                throw new BadImageFormatException($"{nameof(markupArgb)} is expected to be in ARGB format");
            }

            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            if (donorsArgb == null)
            {
                donorsArgb = new ZsImage[0];
            }
            else if (donorsArgb.Any(donorArgb => donorArgb.NumberOfComponents != 4))
            {
                throw new BadImageFormatException($"{nameof(donorsArgb)} are expected to be in ARGB format");
            }
            #endregion

            // Prepare input data
            var     originalImageArea = Area2D.Create(0, 0, imageArgb.Width, imageArgb.Height);
            ZsImage imageToPorcess;
            Pyramid imagePyramid;

            var levelsAmount = _levelDetector.CalculateLevelsAmount(imageArgb, markupArgb, settings.PatchSize);

            // Get the area of the image that can be scaled down required amount of times (levels)
            var areaToProcess = GetImageAreaToProcess(imageArgb, markupArgb, levelsAmount);

            if (!areaToProcess.IsSameAs(originalImageArea))
            {
                // We need to crop the original image, markup and donors
                // since the area to process differs from the image area
                imageToPorcess = CopyImageArea(imageArgb, areaToProcess);
                var markup = CopyImageArea(markupArgb, areaToProcess);
                var donors = donorsArgb.Select(donorImage => CopyImageArea(donorImage, areaToProcess));

                imagePyramid = BuildPyramid(imageToPorcess, markup, donors, levelsAmount, settings.PatchSize);
            }
            else
            {
                imageToPorcess = imageArgb.Clone();
                imagePyramid   = BuildPyramid(imageToPorcess, markupArgb, donorsArgb, levelsAmount, settings.PatchSize);
            }

            imageToPorcess = InternalInpaint(imagePyramid, settings);

            // paste result in the original bitmap where it was extracted from
            var imageArea = Area2D.Create(0, 0, imageToPorcess.Width, imageToPorcess.Height);
            imageToPorcess.FromLabToRgb()
            .FromRgbToArgb(imageArea);

            imageArgb.CopyFromImage(areaToProcess, imageToPorcess, imageArea);

            return(imageArgb);
        }
Beispiel #5
0
        //      [Benchmark]
        public static void Remove()
        {
            const int toRemove = 100;

            //using (var imageBitmap = new Bitmap(@"..\..\..\images\Valve_original.png"))
            using (var imageBitmap = new Bitmap(@"..\..\..\images\t001.png"))
                //using (var protectBitmap = new Bitmap(@"..\..\..\images\p009.png"))
                using (var removeBitmap = new Bitmap(@"..\..\..\images\m001.png"))
                //using (var imageBitmap = new Bitmap(@"..\..\..\images\sc1.png"))
                {
                    var imageArea   = Area2D.Create(0, 0, imageBitmap.Width, imageBitmap.Height);
                    var protectArea = Area2D.Empty;// protectBitmap.ToArea();
                    var removeArea  = removeBitmap.ToArea();

                    // TODO: Sobel in one go
                    var filterX = new double[]
                    {
                        +1, 0, -1,
                        +2, 0, -2,
                        +1, 0, -1
                    };

                    var filterY = new double[]
                    {
                        +1, +2, +1,
                        0, 0, 0,
                        -1, -2, -1
                    };

                    var image1 = imageBitmap
                                 .ToRgbImage();

                    var energyMap = imageBitmap
                                    .ToRgbImage()
                                    .FromRgbToGray();

                    var image2 = energyMap.Clone();

                    // Apply Sobol operator
                    energyMap.Filter(imageArea, filterX, 3, 3);
                    image2.Filter(imageArea, filterY, 3, 3);
                    energyMap.MergeImage(image2);

                    // adjust energy
                    energyMap.NormalizeWeights(energyMap.Height, energyMap.Height * 2, imageArea);
                    //energyMap.NormalizeWeights(0, 1, imageArea);
                    //energyMap.NormalizeWeights(1, 3, imageArea);

                    energyMap.SetComponentsValues(protectArea, new[] { 1.0 }, 0);
                    energyMap.SetComponentsValues(removeArea, new[] { 0.0 }, 0);

                    // build energy map
                    energyMap.ConvertToEnergyMap(imageArea);
                    //energyMap.NormalizeEnergyMap(imageArea);

                    int[] xes = new int[energyMap.Height];

                    // TODO: while not removed
                    // TODO: Add component to the energy map or image with the markup
                    // TODO: Convert the markup to Area and check whether it was reduced if it is not 3 times in a row - stop.
                    for (int i = 0; i < toRemove; i++)
                    {
                        // find min energy sequence
                        FillMinSequence(xes, energyMap, imageArea);
                        // remove max col / row from photo &energy map
                        Update(energyMap.PixelsData, xes, imageArea, image1.Width, image1.Height, 1);

                        //RemoveSequence(xes, energyMap);
                        RemoveSequence(xes, image1);

                        imageArea = Area2D.Create(imageArea.Bound.X, imageArea.Bound.Y, imageArea.Bound.Width - 1, imageArea.Bound.Height);
                    }

                    // TODO: restor with the protection
                    // TODO: restor without the protection

                    if (true)
                    {
                        var newWidth = image1.Width - toRemove;
                        var pixels   = Enumerable.Repeat(0.0, newWidth * image1.Height * image1.NumberOfComponents).ToArray();
                        var image3   = new ZsImage(pixels, newWidth, image1.Height, image1.NumberOfComponents);
                        var destArea = Area2D.Create(0, 0, image3.Width, image3.Height);
                        var srcArea  = Area2D.Create(0, 0, image1.Width, image1.Height);

                        image3
                        .CopyFromImage(destArea, image1, srcArea)
                        .FromRgbToBitmap()
                        .SaveTo("..\\..\\out2.png", ImageFormat.Png)
                        .ShowFile();

                        //energyMap.FromGrayToRgb()
                        //    .FromRgbToBitmap()
                        //    .SaveTo("..\\..\\out1.png", ImageFormat.Png)
                        //    .ShowFile();
                    }
                }
        }