示例#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));
        }
示例#2
0
        public byte[] ChannelDecompose(ImageChannels channels)
        {
            int width  = channels.Red.Width;
            int height = channels.Red.Height;

            byte[] image = new byte[width * height * 4];
            for (int i = 0; i < width * height; i++)
            {
                image[i * 4]     = channels.Red.Buffer[i];
                image[i * 4 + 1] = channels.Green.Buffer[i];
                image[i * 4 + 2] = channels.Blue.Buffer[i];
                image[i * 4 + 3] = channels.Alpha.Buffer[i];
            }
            return(image);
        }
示例#3
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);
        }