public static ImageBuffer Convolution(this ImageBuffer buffer, double[,] xKernel, double[,] yKernel, double factor = 1, int bias = 0)
        {
            byte[] source = buffer.Bytes;

            ImageBuffer output = buffer.CloneFormat();

            byte[] target = output.Bytes;

            double blueX, greenX, redX, blueY, greenY, redY;
            double blueTotal, greenTotal, redTotal;

            int filterOffset = 1;
            int calcOffset   = 0;

            int byteOffset = 0;

            for (int offsetY = filterOffset; offsetY < buffer.Height - filterOffset; offsetY++)
            {
                for (int offsetX = filterOffset; offsetX < buffer.Width - filterOffset; offsetX++)
                {
                    blueX = greenX = redX = 0;
                    blueY = greenY = redY = 0;

                    blueTotal = greenTotal = redTotal = 0.0;

                    byteOffset = offsetY * buffer.Stride + offsetX * 4;

                    for (int filterY = -filterOffset; filterY <= filterOffset; filterY++)
                    {
                        for (int filterX = -filterOffset; filterX <= filterOffset; filterX++)
                        {
                            calcOffset = byteOffset + (filterX * 4) + (filterY * buffer.Stride);

                            blueX  += (double)(source[calcOffset + 0]) * xKernel[filterY + filterOffset, filterX + filterOffset];
                            greenX += (double)(source[calcOffset + 1]) * xKernel[filterY + filterOffset, filterX + filterOffset];
                            redX   += (double)(source[calcOffset + 2]) * xKernel[filterY + filterOffset, filterX + filterOffset];

                            blueY  += (double)(source[calcOffset + 0]) * yKernel[filterY + filterOffset, filterX + filterOffset];
                            greenY += (double)(source[calcOffset + 1]) * yKernel[filterY + filterOffset, filterX + filterOffset];
                            redY   += (double)(source[calcOffset + 2]) * yKernel[filterY + filterOffset, filterX + filterOffset];
                        }
                    }

                    blueTotal  = Math.Sqrt((blueX * blueX) + (blueY * blueY));
                    greenTotal = Math.Sqrt((greenX * greenX) + (greenY * greenY));
                    redTotal   = Math.Sqrt((redX * redX) + (redY * redY));

                    target[byteOffset + 0] = ByteConversion.Bounded(blueTotal);
                    target[byteOffset + 1] = ByteConversion.Bounded(greenTotal);
                    target[byteOffset + 2] = ByteConversion.Bounded(redTotal);
                    target[byteOffset + 3] = 255;
                }
            }
            return(output);
        }
        // See also: http://matlabtricks.com/post-5/3x3-convolution-kernels-with-online-demo#demo

        public static ImageBuffer Convolution(this ImageBuffer buffer, double[,] kernel, double factor = 1, int bias = 0)
        {
            byte[] source = buffer.Bytes;

            ImageBuffer output = buffer.Fill(Color.Black);

            byte[] target = output.Bytes;

            double blue, green, red;

            int width = kernel.GetLength(0);
            //int height = kernel.GetLength(1);  // ?? wordt (nog?) niet gebruikt (20150101 FH)

            int matrixOffset = (width - 1) / 2;

            int calcOffset, byteOffset;

            for (int offsetY = matrixOffset; offsetY < buffer.Height - matrixOffset; offsetY++)
            {
                for (int offsetX = matrixOffset; offsetX < buffer.Width - matrixOffset; offsetX++)
                {
                    blue  = 0;
                    green = 0;
                    red   = 0;

                    byteOffset = offsetY * buffer.Stride + offsetX * 4;

                    for (int filterY = -matrixOffset; filterY <= matrixOffset; filterY++)
                    {
                        for (int filterX = -matrixOffset; filterX <= matrixOffset; filterX++)
                        {
                            calcOffset = byteOffset + (filterX * 4) + (filterY * buffer.Stride);

                            blue  += (double)(source[calcOffset + 0]) * kernel[filterY + matrixOffset, filterX + matrixOffset];
                            green += (double)(source[calcOffset + 1]) * kernel[filterY + matrixOffset, filterX + matrixOffset];
                            red   += (double)(source[calcOffset + 2]) * kernel[filterY + matrixOffset, filterX + matrixOffset];
                        }
                    }

                    blue  = factor * blue + bias;
                    green = factor * green + bias;
                    red   = factor * red + bias;

                    target[byteOffset + 0] = ByteConversion.Bounded(blue);
                    target[byteOffset + 1] = ByteConversion.Bounded(green);
                    target[byteOffset + 2] = ByteConversion.Bounded(red);
                    target[byteOffset + 3] = 255;
                }
            }

            return(output);
        }
Esempio n. 3
0
        public static ImageBuffer PureRGB(this ImageBuffer buffer, byte level, Color color)
        {
            ImageBuffer output = buffer.CloneFormat();

            for (int k = 0; k < buffer.Bytes.Length; k += 4)
            {
                output.Bytes[k + 0] = ByteConversion.LevelSplit(buffer.Bytes[k + 0], level, color.B, 0);
                output.Bytes[k + 1] = ByteConversion.LevelSplit(buffer.Bytes[k + 1], level, color.G, 0);
                output.Bytes[k + 2] = ByteConversion.LevelSplit(buffer.Bytes[k + 2], level, color.R, 0);
                output.Bytes[k + 3] = 255;
            }
            return(output);
        }
        public static ImageBuffer SuperImpoze(this ImageBuffer image, ImageBuffer impoze)
        {
            ImageBuffer output = image.Clone();

            for (int k = 0; k < output.Bytes.Length; k += 4)
            {
                output.Bytes[k + 0] = ByteConversion.MinAtLevel(impoze.Bytes[k + 0], 1, output.Bytes[k + 0]);
                output.Bytes[k + 1] = ByteConversion.MinAtLevel(impoze.Bytes[k + 1], 1, output.Bytes[k + 1]);
                output.Bytes[k + 2] = ByteConversion.MinAtLevel(impoze.Bytes[k + 2], 1, output.Bytes[k + 2]);
                output.Bytes[k + 3] = 255;
            }
            return(output);
        }
        public static ImageBuffer Add(params ImageBuffer[] buffers)
        {
            ImageBuffer output = buffers[0].CloneFormat();

            for (int k = 0; k < output.Bytes.Length; k += 4)
            {
                for (int i = 0; i < buffers.Count(); i++)
                {
                    output.Bytes[k + 0] = ByteConversion.Max(output.Bytes[k + 0] + buffers[i].Bytes[k + 0]);
                    output.Bytes[k + 1] = ByteConversion.Max(output.Bytes[k + 1] + buffers[i].Bytes[k + 1]);
                    output.Bytes[k + 2] = ByteConversion.Max(output.Bytes[k + 2] + buffers[i].Bytes[k + 2]);
                    output.Bytes[k + 3] = 255;
                }
            }
            return(output);
        }
        public static void AverageOut(this byte[] buffer, int p1, int p2)
        {
            int d = Math.Abs(buffer[p1] - buffer[p2]);

            if (d < 15 && d > 0)
            {
                byte value = ByteConversion.Max((buffer[p1] + buffer[p2]) / 2);
                buffer[p1 + 0] = value; // blue
                buffer[p1 + 1] = value; // green
                buffer[p1 + 2] = value; // red
                buffer[p1 + 3] = 255;   // transparency

                buffer[p2 + 0] = value; // blue
                buffer[p2 + 1] = value; // green
                buffer[p2 + 2] = value; // red
                buffer[p2 + 3] = 255;   // transparency
            }
        }