示例#1
0
        private ImagePlane[] Convolution(ImagePlane[] inputPlanes, double[] W, int nOutputPlane, double[] bias)
        {
            int width  = inputPlanes[0].Width;
            int height = inputPlanes[0].Height;

            ImagePlane[] outputPlanes = new ImagePlane[nOutputPlane];
            for (int o = 0; o < nOutputPlane; o++)
            {
                outputPlanes[o] = new ImagePlane(width - 2, height - 2);
            }
            double[] sumValues  = new double[nOutputPlane];
            double[] biasValues = new double[nOutputPlane];
            bias.CopyTo(biasValues, 0);
            for (int w = 1; w < width - 1; w++)
            {
                for (int h = 1; h < height - 1; h++)
                {
                    biasValues.CopyTo(sumValues, 0); // leaky ReLU bias
                    for (int i = 0; i < inputPlanes.Length; i++)
                    {
                        double i00 = inputPlanes[i].GetValue(w - 1, h - 1);
                        double i10 = inputPlanes[i].GetValue(w, h - 1);
                        double i20 = inputPlanes[i].GetValue(w + 1, h - 1);
                        double i01 = inputPlanes[i].GetValue(w - 1, h);
                        double i11 = inputPlanes[i].GetValue(w, h);
                        double i21 = inputPlanes[i].GetValue(w + 1, h);
                        double i02 = inputPlanes[i].GetValue(w - 1, h + 1);
                        double i12 = inputPlanes[i].GetValue(w, h + 1);
                        double i22 = inputPlanes[i].GetValue(w + 1, h + 1);

                        for (int o = 0; o < nOutputPlane; o++)
                        {
                            int    weightIndex = (o * inputPlanes.Length * 9) + (i * 9);
                            double value       = sumValues[o];
                            value       += i00 * W[weightIndex++];
                            value       += i10 * W[weightIndex++];
                            value       += i20 * W[weightIndex++];
                            value       += i01 * W[weightIndex++];
                            value       += i11 * W[weightIndex++];
                            value       += i21 * W[weightIndex++];
                            value       += i02 * W[weightIndex++];
                            value       += i12 * W[weightIndex++];
                            value       += i22 * W[weightIndex++];
                            sumValues[o] = value;
                        }
                    }
                    for (int o = 0; o < nOutputPlane; o++)
                    {
                        double v = sumValues[o];
                        if (v < 0)
                        {
                            v *= 0.1;
                        }
                        outputPlanes[o].SetValue(w - 1, h - 1, v);
                    }
                }
            }
            return(outputPlanes);
        }
示例#2
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);
        }
示例#3
0
        public static ImagePlane[] Deblocking(ImagePlane[][] outputBlocks, int blocksWidth, int blocksHeight)
        {
            int blockSize = outputBlocks[0][0].Width;
            int width     = 0;

            for (int b = 0; b < blocksWidth; b++)
            {
                width += outputBlocks[b][0].Width;
            }
            int height = 0;

            for (int b = 0; b < blocksWidth * blocksHeight; b += blocksWidth)
            {
                height += outputBlocks[b][0].Height;
            }
            //console.log("result image width:" + width + " height:" + height);
            List <ImagePlane> outputPlanes = new List <ImagePlane>(); // [ planeR, planeG, planeB ]

            for (int b = 0; b < outputBlocks.Length; b++)
            {
                ImagePlane[] block            = outputBlocks[b];
                int          blockWidthIndex  = b % blocksWidth;
                int          blockHeightIndex = (int)Math.Floor((double)b / blocksWidth);

                for (int n = 0; n < block.Length; n++)
                {
                    if (outputPlanes.Count < n + 1)
                    {
                        outputPlanes.Add(new ImagePlane(width, height));
                    }
                    else if (outputPlanes[n] == null)
                    {
                        outputPlanes[n] = new ImagePlane(width, height);
                    }
                    ImagePlane channelBlock = block[n];
                    for (int w = 0; w < channelBlock.Width; w++)
                    {
                        for (int h = 0; h < channelBlock.Height; h++)
                        {
                            int    targetIndexW = blockWidthIndex * blockSize + w;
                            int    targetIndexH = blockHeightIndex * blockSize + h;
                            int    targetIndex  = targetIndexH * width + targetIndexW;
                            double channelValue = channelBlock.GetValue(w, h);
                            outputPlanes[n].Buffer[targetIndex] = channelValue;
                        }
                    }
                }
            }
            return(outputPlanes.ToArray());
        }
示例#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);
        }
示例#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);
        }
示例#6
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);
        }