Example #1
0
        public async Task UpscaleImage(Guid taskId, byte[] image, int width, int height, Action <ResultMessage> done, Action <ProgressMessage> progress)
        {
            TimeSpan timeSpanStart = TimeSpan.FromTicks(DateTime.Now.Ticks);

            // decompose
            progress(new ProgressMessage(taskId, UpscallingStatuses.Decompose, "in process"));
            ImageChannels channels = ImageChannel.ChannelDecompose(image, width, height);

            progress(new ProgressMessage(taskId, UpscallingStatuses.Decompose, "ready"));

            // calculate
            //Scaling all blocks
            ImageChannels upscaledChannels = await Task.Run(() => UpscaleRgbAsync(taskId, channels, ScaleModel, Scale, progress));

            //Scaled all blocks

            // resize alpha channel
            ImageChannel imageA = Scale == 1 ? upscaledChannels.Alpha : upscaledChannels.Alpha.Resize(Scale);

            if (imageA.Buffer.Length != upscaledChannels.Red.Buffer.Length)
            {
                throw new Exception("A channel image size must be same with R channel image size");
            }

            upscaledChannels.Alpha = imageA;

            // recompose
            progress(new ProgressMessage(taskId, UpscallingStatuses.Compose, "in process"));
            byte[] upscaledImage = ImageChannel.ChannelCompose(upscaledChannels);
            progress(new ProgressMessage(taskId, UpscallingStatuses.Compose, "ready"));

            TimeSpan elapsedTime = TimeSpan.FromTicks(DateTime.Now.Ticks) - timeSpanStart;

            done(new ResultMessage(taskId, upscaledImage, upscaledChannels.Red.Width, upscaledChannels.Red.Height, elapsedTime));
        }
Example #2
0
        public static ImageChannels ChannelDecompose(byte[] image, int width, int height)
        {
            ImageChannel imageR = new ImageChannel(width, height);
            ImageChannel imageG = new ImageChannel(width, height);
            ImageChannel imageB = new ImageChannel(width, height);
            ImageChannel imageA = new ImageChannel(width, height);

            for (int w = 0; w < width; w++)
            {
                for (int h = 0; h < height; h++)
                {
                    int index = w + (h * width);
                    imageR.Buffer[index] = image[(w * 4) + (h * width * 4)];
                    imageG.Buffer[index] = image[(w * 4) + (h * width * 4) + 1];
                    imageB.Buffer[index] = image[(w * 4) + (h * width * 4) + 2];
                    imageA.Buffer[index] = image[(w * 4) + (h * width * 4) + 3];
                }
            }

            return(new ImageChannels()
            {
                Alpha = imageA,
                Red = imageR,
                Green = imageG,
                Blue = imageB
            });
        }
Example #3
0
        private ImageChannel Denormalize(ImagePlane imagePlane)
        {
            ImageChannel image = new ImageChannel(imagePlane.Width, imagePlane.Height);

            for (int i = 0; i < imagePlane.Buffer.Length; i++)
            {
                double temp = Math.Round(imagePlane.Buffer[i] * 255, MidpointRounding.AwayFromZero);
                image.Buffer[i] = temp > 255? (byte)255: (byte)temp;
            }
            return(image);
        }
Example #4
0
        private ImagePlane Normalize(ImageChannel image)
        {
            int        width      = image.Width;
            int        height     = image.Height;
            ImagePlane imagePlane = new ImagePlane(width, height);

            if (imagePlane.Buffer.Length != image.Buffer.Length)
            {
                throw new Exception("Assertion error: length");
            }
            for (int i = 0; i < image.Buffer.Length; i++)
            {
                double temp = image.Buffer[i] / 255.0;
                imagePlane.Buffer[i] = temp;
            }
            return(imagePlane);
        }
Example #5
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);
        }
Example #6
0
        public ImageChannel Resize(double scale)
        {
            int          width        = Width;
            int          height       = Height;
            int          scaledWidth  = (int)Math.Round(width * scale, MidpointRounding.AwayFromZero);
            int          scaledHeight = (int)Math.Round(height * scale, MidpointRounding.AwayFromZero);
            ImageChannel scaledImage  = new ImageChannel(scaledWidth, scaledHeight);

            for (int w = 0; w < scaledWidth; w++)
            {
                for (int h = 0; h < scaledHeight; h++)
                {
                    int scaledIndex        = w + (h * scaledWidth);
                    int originalWidth      = (int)Math.Round((w + 1) / scale, MidpointRounding.AwayFromZero) - 1;
                    int originalHeight     = (int)Math.Round((h + 1) / scale, MidpointRounding.AwayFromZero) - 1;
                    int originalImageIndex = originalWidth + (originalHeight * width);
                    scaledImage.Buffer[scaledIndex] = Buffer[originalImageIndex];
                }
            }
            return(scaledImage);
        }
Example #7
0
        public ImageChannel Extrapolation(int px)
        {
            int          width             = Width;
            int          height            = Height;
            ImageChannel extrapolatedImage = new ImageChannel(width + (2 * px), height + (2 * px));

            for (int h = 0; h < height + (px * 2); h++)
            {
                for (int w = 0; w < width + (px * 2); w++)
                {
                    int index = w + h * (width + (px * 2));
                    if (w < px)
                    {
                        // Left outer area
                        if (h < px)
                        {
                            // Left upper area
                            extrapolatedImage.Buffer[index] = Buffer[ToIndex(0, 0, width)];
                        }
                        else if (px + height <= h)
                        {
                            // Left lower area
                            extrapolatedImage.Buffer[index] = Buffer[ToIndex(0, height - 1, width)];
                        }
                        else
                        {
                            // Left outer area
                            extrapolatedImage.Buffer[index] = Buffer[ToIndex(0, h - px, width)];
                        }
                    }
                    else if (px + width <= w)
                    {
                        // Right outer area
                        if (h < px)
                        {
                            // Right upper area
                            extrapolatedImage.Buffer[index] = Buffer[ToIndex(width - 1, 0, width)];
                        }
                        else if (px + height <= h)
                        {
                            // Right lower area
                            extrapolatedImage.Buffer[index] = Buffer[ToIndex(width - 1, height - 1, width)];
                        }
                        else
                        {
                            // Right outer area
                            extrapolatedImage.Buffer[index] = Buffer[ToIndex(width - 1, h - px, width)];
                        }
                    }
                    else if (h < px)
                    {
                        // Upper outer area
                        extrapolatedImage.Buffer[index] = Buffer[ToIndex(w - px, 0, width)];
                    }
                    else if (px + height <= h)
                    {
                        // Lower outer area
                        extrapolatedImage.Buffer[index] = Buffer[ToIndex(w - px, height - 1, width)];
                    }
                    else
                    {
                        // Inner area
                        extrapolatedImage.Buffer[index] = Buffer[ToIndex(w - px, h - px, width)];
                    }
                }
            }
            return(extrapolatedImage);
        }