Esempio n. 1
0
        private ImageChannels UpscaleRgbAsync(Guid taskId, ImageChannels channels, SRCNNModelLayer[] model, int scale, Action <ProgressMessage> progressCallback)
        {
            ImagePlane[] inputPlanes = channels.ToArray().Select((image) =>
            {
                ImageChannel imgResized = scale == 1 ? image : image.Resize(scale);

                // extrapolation for layer count (each convolution removes outer 1 pixel border)
                ImageChannel imgExtra = imgResized.Extrapolation(model.Length);

                return(Normalize(imgExtra));
            }).ToArray();

            // blocking
            ImageBlocks imageBlocks = ImagePlane.Blocking(inputPlanes);

            inputPlanes = null;

            // init W
            double[][] weights = GetWeights(model);

            var outputBlocks = imageBlocks.Blocks.AsParallel()
                               .SelectMany((block, index) => UpscaleBlocks(taskId, model, weights, progressCallback,
                                                                           index + 1, imageBlocks.Blocks.Count,
                                                                           block))
                               .ToList();


            // de-blocking
            ImagePlane[] outputPlanes = ImagePlane.Deblocking(outputBlocks.ToArray(), imageBlocks.BlocksWidth, imageBlocks.BlocksHeight);
            if (outputPlanes.Length != 3)
            {
                throw new Exception("Output planes must be 3: color channel R, G, B.");
            }

            ImageChannels outputChannels = new ImageChannels()
            {
                Red   = Denormalize(outputPlanes[0]),
                Green = Denormalize(outputPlanes[1]),
                Blue  = Denormalize(outputPlanes[2]),
                Alpha = channels.Alpha
            };

            return(outputChannels);
        }
Esempio n. 2
0
        public static ImageBlocks Blocking(ImagePlane[] initialPlanes)
        {
            int widthInput  = initialPlanes[0].Width;
            int heightInput = initialPlanes[0].Height;

            int blocksWidth  = (int)Math.Ceiling((double)(widthInput - Overlap) / (BlockSize - Overlap));
            int blocksHeight = (int)Math.Ceiling((double)(heightInput - Overlap) / (BlockSize - Overlap));
            int blocks       = blocksWidth * blocksHeight;

            ImageBlocks inputBlocks = new ImageBlocks() // [ [ block0_R, block0_G, block0_B ], [ block1_R, ...] ... ]
            {
                BlocksWidth  = blocksWidth,
                BlocksHeight = blocksHeight
            };

            for (int b = 0; b < blocks; b++)
            {
                int blockWidthIndex  = b % blocksWidth;
                int blockHeightIndex = (int)Math.Floor((double)(b / blocksWidth));

                int blockWidth;
                int blockHeight;
                if (blockWidthIndex == blocksWidth - 1)
                {
                    blockWidth = widthInput - ((BlockSize - Overlap) * blockWidthIndex); // right end block
                }
                else
                {
                    blockWidth = BlockSize;
                }
                if (blockHeightIndex == blocksHeight - 1)
                {
                    blockHeight = heightInput - ((BlockSize - Overlap) * blockHeightIndex); // bottom end block
                }
                else
                {
                    blockHeight = BlockSize;
                }

                ImagePlane[] channels = new ImagePlane[initialPlanes.Length];
                for (int i = 0; i < channels.Length; i++)
                {
                    channels[i] = new ImagePlane(blockWidth, blockHeight);
                }

                for (int w = 0; w < blockWidth; w++)
                {
                    for (int h = 0; h < blockHeight; h++)
                    {
                        for (int n = 0; n < initialPlanes.Length; n++)
                        {
                            int        targetIndexW = blockWidthIndex * (BlockSize - Overlap) + w;
                            int        targetIndexH = blockHeightIndex * (BlockSize - Overlap) + h;
                            ImagePlane channel      = initialPlanes[n];
                            double     channelValue = channel.GetValue(targetIndexW, targetIndexH);
                            channels[n].SetValue(w, h, channelValue);
                        }
                    }
                }
                inputBlocks.Blocks.Add(channels);
            }
            return(inputBlocks);
        }