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)); }
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); }
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); }