Esempio n. 1
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        public unsafe void Apply(BitmapData bmData)
        {
            byte *p = (byte *)bmData.Scan0.ToPointer();
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;
            float z = 1 - s;

            Parallel.For(0, height, y =>
            {
                YUV nYUV, iYUV; RGB rgb;
                int nR, nG, nB, iR, iG, iB;
                int x, ystride, k, luma;

                ystride = y * stride;

                for (x = 0; x < width; x++)
                {
                    k = ystride + x * 4;

                    iR = p[k + 2]; iG = p[k + 1]; iB = p[k];

                    luma = RGB.HDTV(iR, iG, iB);
                    nYUV = YUV.FromRGB(luma, luma, luma);
                    iYUV = YUV.FromRGB(color.R, color.G, color.B);
                    rgb  = AddColor(nYUV, iYUV).ToRGB;
                    nR   = rgb.Red; nG = rgb.Green; nB = rgb.Blue;

                    p[k + 2] = Maths.Byte(nR * s + iR * z);
                    p[k + 1] = Maths.Byte(nG * s + iG * z);
                    p[k]     = Maths.Byte(nB * s + iB * z);
                }
            }
                         );

            return;
        }
Esempio n. 2
0
        /// <summary>
        /// Process frame.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        /// <param name="bmSrc">Bitmap data</param>
        private unsafe double ProcessFrameWithFilter(BitmapData bmData, BitmapData bmSrc)
        {
            byte *dst = (byte *)bmData.Scan0.ToPointer();
            byte *src = (byte *)bmSrc.Scan0.ToPointer();
            int   width = bmData.Width, height = bmData.Height;

            double variance = 0.0;

            for (int x = 0; x < width; x++)
            {
                int y, k;

                for (y = 0; y < height; y++, dst += 4, src += 4)
                {
                    for (k = 0; k < 3; k++)
                    {
                        var difference = Math.Abs(dst[k] - src[k]);
                        dst[k] = Maths.Byte(difference);
                    }

                    var summary = RGB.Average(dst[2], dst[1], dst[0]);

                    if (summary > Threshold)
                    {
                        variance++;
                    }
                }
            }
            ;

            return(variance / (width * height));
        }
Esempio n. 3
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        private unsafe void ApplyRGB(BitmapData bmData)
        {
            byte *p = (byte *)bmData.Scan0.ToPointer();
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;
            float length = values.Length - 1;

            Parallel.For(0, height, y =>
            {
                int x, ystride, k;
                RGB rgb;

                ystride = y * stride;

                for (x = 0; x < width; x++)
                {
                    k   = ystride + x * 4;
                    rgb = new RGB(p[k + 2], p[k + 1], p[k]);

                    rgb.Red   = Maths.Byte(values[rgb.Red] * length);
                    rgb.Green = Maths.Byte(values[rgb.Green] * length);
                    rgb.Blue  = Maths.Byte(values[rgb.Blue] * length);

                    p[k + 2] = rgb.Red; p[k + 1] = rgb.Green; p[k] = rgb.Blue;
                }
            }
                         );

            return;
        }
Esempio n. 4
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        public unsafe void Apply(BitmapData bmData)
        {
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;
            int   widthToProcess  = Math.Min(width, texture.GetLength(1));
            int   heightToProcess = Math.Min(height, texture.GetLength(0));
            float z = 1.0f - this.depth;
            byte *p = (byte *)bmData.Scan0.ToPointer();

            Parallel.For(0, heightToProcess, y =>
            {
                int x, ystride, k;
                byte red, green, blue;
                float t;

                ystride = y * stride;

                for (x = 0; x < widthToProcess; x++)
                {
                    k   = ystride + x * 4;
                    red = p[k + 2]; green = p[k + 1]; blue = p[k];
                    t   = texture[y, x];

                    p[k + 2] = Maths.Byte((z * red) + (this.depth * red) * t);
                    p[k + 1] = Maths.Byte((z * green) + (this.depth * green) * t);
                    p[k]     = Maths.Byte((z * blue) + (this.depth * blue) * t);
                }
            }
                         );

            return;
        }
Esempio n. 5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="red"></param>
        /// <param name="green"></param>
        /// <param name="blue"></param>
        /// <param name="table"></param>
        /// <returns></returns>
        private Color GetColor(int red, int green, int blue, float[] table)
        {
            byte r = Maths.Byte(table[red]);
            byte g = Maths.Byte(table[green]);
            byte b = Maths.Byte(table[blue]);

            return(Color.FromArgb(r, g, b));
        }
Esempio n. 6
0
        /// <summary>
        /// Converts an RGB structure to a color image.
        /// </summary>
        /// <param name="array">RGBA structure array</param>
        /// <param name="bmData">Bitmap data</param>
        public unsafe static void FromRGB(this float[][,] array, BitmapData bmData)
        {
            // matrices
            float[,] x = array[0];
            float[,] y = array[1];
            float[,] z = array[2];

            // params
            int   width = x.GetLength(1), height = x.GetLength(0);
            int   stride = bmData.Stride;
            byte *p      = (byte *)bmData.Scan0.ToPointer();

            // alpha
            bool alpha = array.Length == 4;

            if (alpha)
            {
                float[,] a = array[3];

                Parallel.For(0, height, j =>
                {
                    int i, k, jstride = j * stride;

                    for (i = 0; i < width; i++)
                    {
                        // shift:
                        k = jstride + i * 4;

                        // recording model:
                        p[k + 0] = Maths.Byte(x[j, i] * 255.0f);
                        p[k + 1] = Maths.Byte(y[j, i] * 255.0f);
                        p[k + 2] = Maths.Byte(z[j, i] * 255.0f);
                        p[k + 3] = Maths.Byte(a[j, i] * 255.0f);
                    }
                });
            }
            else
            {
                Parallel.For(0, height, j =>
                {
                    int i, k, jstride = j * stride;

                    for (i = 0; i < width; i++)
                    {
                        // shift:
                        k = jstride + i * 4;

                        // recording model:
                        p[k + 0] = Maths.Byte(x[j, i] * 255.0f);
                        p[k + 1] = Maths.Byte(y[j, i] * 255.0f);
                        p[k + 2] = Maths.Byte(z[j, i] * 255.0f);
                        p[k + 3] = (byte)255;
                    }
                });
            }

            return;
        }
Esempio n. 7
0
        /// <summary>
        /// Corrects color saturation.
        /// </summary>
        /// <param name="red">Red </param>
        /// <param name="green">Green</param>
        /// <param name="blue">Blue</param>
        /// <param name="s">Saturation</param>
        /// <returns>RGB structure</returns>
        public static sRGB Saturation(float red, float green, float blue, float s)
        {
            float max = Maths.Max(red, green, blue);

            // Result color:
            return(new sRGB(
                       Maths.Byte(blue + (blue - max) * s),
                       Maths.Byte(green + (green - max) * s),
                       Maths.Byte(red + (red - max) * s)));
        }
Esempio n. 8
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        public unsafe void Apply(BitmapData bmData)
        {
            byte *p = (byte *)bmData.Scan0.ToPointer();
            int   y, x, width = bmData.Width, height = bmData.Height;

            for (y = 0; y < height; y++)
            {
                for (x = 0; x < width; x++, p += 4)
                {
                    p[0] = p[1] = p[2] = Maths.Byte(cr * p[2] + cg * p[1] + cb * p[0]);
                }
            }
            return;
        }
Esempio n. 9
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        /// <param name="bmMax">Bitmap data</param>
        /// <param name="bmMin">Bitmap data</param>
        private unsafe void ApplyRGB(BitmapData bmData, BitmapData bmMax, BitmapData bmMin)
        {
            byte *p = (byte *)bmData.Scan0.ToPointer();
            byte *pMax = (byte *)bmMax.Scan0.ToPointer();
            byte *pMin = (byte *)bmMin.Scan0.ToPointer();
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;

            float required = 1.0f - this.contrast;

            Parallel.For(0, height, j =>
            {
                int i, k, k1, k2, q, v, jstride = j * stride;
                float mag, max, min;
                float num1, num2, num3;

                for (i = 0; i < width; i++)
                {
                    k = jstride + i * 4; k1 = k + 1; k2 = k + 2;

                    // Local function:
                    for (q = 0; q < 3; q++)
                    {
                        v = k + q;

                        mag = p[v] / 255.0f;
                        max = pMax[v] / 255.0f;
                        min = pMin[v] / 255.0f;

                        num1 = max - min;

                        if (num1 < required)
                        {
                            num2 = min + (required - num1) * min / (num1 - 1f);
                            min  = Maths.Float(num2);
                            max  = Maths.Float(num2 + required);
                        }

                        num1 = max - min;
                        num3 = mag - min;

                        if (num1 > 0)
                        {
                            p[v] = Maths.Byte(255 * num3 / num1);
                        }
                    }
                    // end local function.
                }
            }
                         );
        }
Esempio n. 10
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        public unsafe void Apply(BitmapData bmData)
        {
            byte *p = (byte *)bmData.Scan0.ToPointer();
            int   y, x, width = bmData.Width, height = bmData.Height;
            int   stride = bmData.Stride;

            for (y = 0; y < height; y++)
            {
                for (x = 0; x < width; x++, p += 4)
                {
                    p[2] = Maths.Byte(p[2] + generator.Next(-amount, amount));
                    p[1] = Maths.Byte(p[1] + generator.Next(-amount, amount));
                    p[0] = Maths.Byte(p[0] + generator.Next(-amount, amount));
                }
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        /// <param name="bmSrc">Bitmap data</param>
        public unsafe void Apply(BitmapData bmData, BitmapData bmSrc)
        {
            byte *p = (byte *)bmData.Scan0.ToPointer();
            byte *pSrc = (byte *)bmSrc.Scan0.ToPointer();
            int   y, x, width = bmData.Width, height = bmData.Height;

            for (x = 0; x < width; x++)
            {
                for (y = 0; y < height; y++, p += 4, pSrc += 4)
                {
                    p[2] = Maths.Byte(a * p[2] + b * pSrc[2]);
                    p[1] = Maths.Byte(a * p[1] + b * pSrc[1]);
                    p[0] = Maths.Byte(a * p[0] + b * pSrc[0]);
                }
            }
            return;
        }
Esempio n. 12
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        public unsafe void Apply(BitmapData bmData)
        {
            byte *p = (byte *)bmData.Scan0.ToPointer();
            int   width = bmData.Width, height = bmData.Height;
            int   stride = bmData.Stride;

            // filter color
            float rf = color.R / 255.0f;
            float gf = color.G / 255.0f;
            float bf = color.B / 255.0f;

            // do job
            Parallel.For(0, height, y =>
            {
                // bitmap color
                float lm;
                float rb;
                float gb;
                float bb;

                int x, ystride, k;

                ystride = y * stride;

                for (x = 0; x < width; x++)
                {
                    k = ystride + x * 4;

                    // luma
                    lm = RGB.Average(p[k + 2], p[k + 1], p[k]) / 255.0f;

                    // blending
                    rb = this.blendf(lm, rf) * 255.0f;
                    gb = this.blendf(lm, gf) * 255.0f;
                    bb = this.blendf(lm, bf) * 255.0f;

                    // recording
                    p[k + 2] = Maths.Byte(rb * s + p[k + 2] * (1.0f - s));
                    p[k + 1] = Maths.Byte(gb * s + p[k + 1] * (1.0f - s));
                    p[k]     = Maths.Byte(bb * s + p[k] * (1.0f - s));
                }
            });

            return;
        }
Esempio n. 13
0
        /// <summary>
        /// Converts a matrix of channel values to a monochrome Bitmap.
        /// </summary>
        /// <param name="m">Matrix</param>
        /// <param name="bmData">Bitmap data</param>
        public unsafe static void FromGrayscale(this float[,] m, BitmapData bmData)
        {
            int   width = m.GetLength(1), height = m.GetLength(0);
            int   stride = bmData.Stride;
            byte *p      = (byte *)bmData.Scan0.ToPointer();

            Parallel.For(0, height, j =>
            {
                int i, k, jstride = j * stride;

                for (i = 0; i < width; i++)
                {
                    k        = jstride + i * 4;
                    p[k + 2] = p[k + 1] = p[k] = Maths.Byte(m[j, i] * 255.0f);
                    p[k + 3] = 255;
                }
            });

            return;
        }
Esempio n. 14
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        public unsafe void Apply(BitmapData bmData)
        {
            int[] H = Statistics.Histogram(bmData);
            byte *p = (byte *)bmData.Scan0.ToPointer();
            int   y, x, width = bmData.Width, height = bmData.Height;

            float[] table  = Statistics.Equalize(H);
            float   length = table.Length - 1;

            for (y = 0; y < height; y++)
            {
                for (x = 0; x < width; x++, p += 4)
                {
                    p[2] = Maths.Byte(table[p[2]] * length);
                    p[1] = Maths.Byte(table[p[1]] * length);
                    p[0] = Maths.Byte(table[p[0]] * length);
                }
            }
            return;
        }
Esempio n. 15
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        public unsafe void Apply(BitmapData bmData)
        {
            // rebuild?
            if (rebuild == true)
            {
                this.Rebuild(); this.rebuild = false;
            }

            byte *p = (byte *)bmData.Scan0.ToPointer();
            int   y, x, height = bmData.Height, width = bmData.Width;
            float length = values.Length - 1;

            for (y = 0; y < height; y++)
            {
                for (x = 0; x < width; x++, p += 4)
                {
                    p[3] = Maths.Byte(values[p[3]] * length);
                }
            }
            return;
        }
Esempio n. 16
0
        /// <summary>
        /// Returns a matrix whose values belong to the interval [0, 255].
        /// </summary>
        /// <param name="m">Matrix</param>
        /// <returns>Matrix</returns>
        public static float[][] ToByte(this float[][] m)
        {
            int r0 = m.GetLength(0), r1;

            float[][] H = new float[r0][];
            float[]   v;
            int       i, j;

            for (i = 0; i < r0; i++)
            {
                v  = m[i];
                r1 = v.GetLength(0);

                for (j = 0; j < r1; j++)
                {
                    H[i][j] = Maths.Byte(v[j]);
                }
            }

            return(H);
        }
Esempio n. 17
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        /// <param name="bmSrc">Bitmap data</param>
        private unsafe void ApplyRGB(BitmapData bmData, BitmapData bmSrc)
        {
            byte *p = (byte *)bmData.Scan0.ToPointer(), pSrc = (byte *)bmSrc.Scan0.ToPointer();
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;
            float length = values.GetLength(0) - 1;

            Parallel.For(0, height, j =>
            {
                int i, k, k1, k2, jstride = j * stride;

                for (i = 0; i < width; i++)
                {
                    k = jstride + i * 4; k1 = k + 1; k2 = k + 2;

                    p[k2] = Maths.Byte(this.values[p[k2], pSrc[k2]] * length);
                    p[k1] = Maths.Byte(this.values[p[k1], pSrc[k1]] * length);
                    p[k]  = Maths.Byte(this.values[p[k], pSrc[k]] * length);
                }
            }
                         );
        }
Esempio n. 18
0
        /// <summary>
        /// Converts ushort matrix into Bitmap.
        /// </summary>
        /// <param name="depth">Matrix</param>
        /// <returns>Bitmap</returns>
        public unsafe static Bitmap ToBitmap(this ushort[,] depth)
        {
            var width     = depth.GetLength(1);
            var height    = depth.GetLength(0);
            var rectangle = new Rectangle(0, 0, width, height);
            var bitmap    = new Bitmap(width, height);
            var bmData    = bitmap.LockBits(rectangle, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            var dst       = (byte *)bmData.Scan0.ToPointer();
            var stride    = bmData.Stride;

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    var k = x * 3 + y * stride;
                    dst[k + 0] = dst[k + 1] = dst[k + 2] = Maths.Byte((float)depth[y, x] / byte.MaxValue);
                }
            }

            bitmap.Unlock(bmData);
            return(bitmap);
        }
Esempio n. 19
0
        /// <summary>
        /// Converts a matrix of channel values to a monochrome Bitmap.
        /// </summary>
        /// <param name="m">Matrix</param>
        /// <returns>Bitmap</returns>
        public unsafe static Bitmap FromGrayscale(this float[,] m)
        {
            int        width = m.GetLength(1), height = m.GetLength(0);
            Bitmap     bitmap = new Bitmap(width, height);
            BitmapData bmData = BitmapFormat.Lock32bpp(bitmap);
            int        stride = bmData.Stride;
            byte *     p      = (byte *)bmData.Scan0.ToPointer();

            Parallel.For(0, height, j =>
            {
                int i, k, jstride = j * stride;

                for (i = 0; i < width; i++)
                {
                    k        = jstride + i * 4;
                    p[k + 2] = p[k + 1] = p[k] = Maths.Byte(m[j, i] * 255.0f);
                    p[k + 3] = 255;
                }
            });

            BitmapFormat.Unlock(bitmap, bmData);
            return(bitmap);
        }
Esempio n. 20
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        /// <param name="bmSrc">Bitmap data</param>
        private unsafe void ApplyGrayscale(BitmapData bmData, BitmapData bmSrc)
        {
            byte *p = (byte *)bmData.Scan0.ToPointer(), pSrc = (byte *)bmSrc.Scan0.ToPointer();
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;
            float length = values.GetLength(0) - 1;

            Parallel.For(0, height, j =>
            {
                int i, k, lumax, lumay, jstride = j * stride;

                for (i = 0; i < width; i++)
                {
                    k = jstride + i * 4;

                    lumax = RGB.Average(p[k + 2], p[k + 1], p[k]);
                    lumay = RGB.Average(pSrc[k + 2], pSrc[k + 1], pSrc[k]);

                    p[k + 2] = p[k + 1] = p[k] = Maths.Byte(this.values[lumax, lumay] * length);
                }
            });

            return;
        }
Esempio n. 21
0
        /// <summary>
        /// Flat-field filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        /// <param name="bmSrc">Bitmap data</param>
        private unsafe void flatfield(BitmapData bmData, BitmapData bmSrc)
        {
            byte *p = (byte *)bmData.Scan0.ToPointer();
            byte *pSrc = (byte *)bmSrc.Scan0.ToPointer();
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;

            this.globalmeans(bmSrc); // calculating medians.

            Parallel.For(0, height, y =>
            {
                int x, ystride, k;

                ystride = y * stride;

                for (x = 0; x < width; x++)
                {
                    k = ystride + x * 4;

                    if (pSrc[k + 2] != 0)
                    {
                        p[k + 2] = Maths.Byte(p[k + 2] * mR / pSrc[k + 2]);
                    }
                    if (pSrc[k + 1] != 0)
                    {
                        p[k + 1] = Maths.Byte(p[k + 1] * mR / pSrc[k + 1]);
                    }
                    if (pSrc[k] != 0)
                    {
                        p[k] = Maths.Byte(p[k] * mR / pSrc[k]);
                    }
                }
            }
                         );

            return;
        }
Esempio n. 22
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        private unsafe void ApplyGrayscale(BitmapData bmData)
        {
            byte *p = (byte *)bmData.Scan0.ToPointer();
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;
            float length = values.Length - 1;

            Parallel.For(0, height, y =>
            {
                int x, ystride, k;
                int luma;

                ystride = y * stride;

                for (x = 0; x < width; x++)
                {
                    k        = ystride + x * 4;
                    luma     = RGB.Average(p[k + 2], p[k + 1], p[k]);
                    p[k + 2] = p[k + 1] = p[k] = Maths.Byte(values[luma] * length);
                }
            }
                         );

            return;
        }
Esempio n. 23
0
        /// <summary>
        /// Converts an YCbCr structure to a color image.
        /// </summary>
        /// <param name="array">YCbCr structure array</param>
        /// <returns>Bitmap</returns>
        public unsafe static Bitmap FromYCbCr(this float[][,] array)
        {
            // matrices
            float[,] x = array[0];
            float[,] y = array[1];
            float[,] z = array[2];

            // params
            int        width = x.GetLength(1), height = x.GetLength(0);
            Bitmap     bitmap = new Bitmap(width, height);
            BitmapData bmData = BitmapFormat.Lock32bpp(bitmap);
            int        stride = bmData.Stride;
            byte *     p      = (byte *)bmData.Scan0.ToPointer();

            // alpha
            bool alpha = array.Length == 4;

            if (alpha)
            {
                float[,] a = array[3];

                Parallel.For(0, height, j =>
                {
                    RGB rgb;

                    int i, k, jstride = j * stride;

                    for (i = 0; i < width; i++)
                    {
                        // shift:
                        k = jstride + i * 4;

                        rgb = new YCbCr(x[j, i], y[j, i], z[j, i]).ToRGB;

                        // recording model:
                        p[k + 0] = rgb.Blue;
                        p[k + 1] = rgb.Green;
                        p[k + 2] = rgb.Red;
                        p[k + 3] = Maths.Byte(a[j, i] * 255.0f);
                    }
                });
            }
            else
            {
                Parallel.For(0, height, j =>
                {
                    RGB rgb;

                    int i, k, jstride = j * stride;

                    for (i = 0; i < width; i++)
                    {
                        // shift:
                        k = jstride + i * 4;

                        rgb = new YCbCr(x[j, i], y[j, i], z[j, i]).ToRGB;

                        // recording model:
                        p[k + 0] = rgb.Blue;
                        p[k + 1] = rgb.Green;
                        p[k + 2] = rgb.Red;
                        p[k + 3] = (byte)255;
                    }
                });
            }

            BitmapFormat.Unlock(bitmap, bmData);
            return(bitmap);
        }
Esempio n. 24
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        /// <param name="bmSrc">Bitmap data</param>
        private unsafe void ApplyHorizontal(BitmapData bmData, BitmapData bmSrc)
        {
            #region Data
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;
            byte *src = (byte *)bmSrc.Scan0.ToPointer();
            byte *dst = (byte *)bmData.Scan0.ToPointer();
            int   h   = rw >= width ? width - 1 : rw;
            int   v   = h >> 1;
            int   dl  = width - v;
            #endregion

            Parallel.For(0, height, y =>
            {
                float r = 0;
                float g = 0;
                float b = 0;
                int p, q, w, x;
                int yy = y * stride;

                for (p = yy, x = 0; x < h; x++, p += 4)
                {
                    r += src[p + 2];
                    g += src[p + 1];
                    b += src[p + 0];
                }

                for (p = yy, x = 0; x < v; x++, p += 4)
                {
                    dst[p + 2] = Maths.Byte(r / h);
                    dst[p + 1] = Maths.Byte(g / h);
                    dst[p + 0] = Maths.Byte(b / h);
                }

                for (
                    x = v,
                    p = yy + (x - v) * 4,
                    q = yy + (x + 0) * 4,
                    w = yy + (x + v) * 4;

                    x < dl;

                    x++,
                    p += 4,
                    q += 4,
                    w += 4)
                {
                    r = r - src[p + 2] + src[w + 2];
                    g = g - src[p + 1] + src[w + 1];
                    b = b - src[p + 0] + src[w + 0];

                    dst[q + 2] = Maths.Byte(r / h);
                    dst[q + 1] = Maths.Byte(g / h);
                    dst[q + 0] = Maths.Byte(b / h);
                }

                for (
                    x = dl,
                    p = (x - v) * 4 + yy,
                    q = (x + 0) * 4 + yy;

                    x < width;

                    x++,
                    p += 4,
                    q += 4)
                {
                    r = r - src[p + 2] + src[q + 2];
                    g = g - src[p + 1] + src[q + 1];
                    b = b - src[p + 0] + src[q + 0];

                    dst[q + 2] = Maths.Byte(r / h);
                    dst[q + 1] = Maths.Byte(g / h);
                    dst[q + 0] = Maths.Byte(b / h);
                }
            });
        }
Esempio n. 25
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        /// <param name="bmSrc">Bitmap data</param>
        private unsafe void ApplyVertical(BitmapData bmData, BitmapData bmSrc)
        {
            #region Data
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;
            byte *src = (byte *)bmSrc.Scan0.ToPointer();
            byte *dst = (byte *)bmData.Scan0.ToPointer();
            int   h   = rh >= height ? height - 1 : rh;
            int   v   = h >> 1;
            int   dl  = height - v;
            #endregion

            Parallel.For(0, width, x =>
            {
                float r = 0;
                float g = 0;
                float b = 0;
                int p, w, q, y;
                int xx = x * 4;

                for (p = xx, y = 0; y < h; y++, p += stride)
                {
                    r += src[p + 2];
                    g += src[p + 1];
                    b += src[p + 0];
                }

                for (p = xx, y = 0; y < v; y++, p += stride)
                {
                    dst[p + 2] = Maths.Byte(r / h);
                    dst[p + 1] = Maths.Byte(g / h);
                    dst[p + 0] = Maths.Byte(b / h);
                }

                for (
                    y = v,
                    p = xx + (y - v) * stride,
                    q = xx + (y + 0) * stride,
                    w = xx + (y + v) * stride;

                    y < dl;

                    y++,
                    p += stride,
                    q += stride,
                    w += stride)
                {
                    r = r - src[p + 2] + src[w + 2];
                    g = g - src[p + 1] + src[w + 1];
                    b = b - src[p + 0] + dst[w + 0];

                    dst[q + 2] = Maths.Byte(r / h);
                    dst[q + 1] = Maths.Byte(g / h);
                    dst[q + 0] = Maths.Byte(b / h);
                }

                for (
                    y = dl,
                    p = xx + (y - v) * stride,
                    q = xx + (y + 0) * stride;

                    y < height;

                    y++,
                    p += stride,
                    q += stride)
                {
                    r = r - src[p + 2] + src[q + 2];
                    g = g - src[p + 1] + src[q + 1];
                    b = b - src[p + 0] + src[q + 0];

                    dst[q + 2] = Maths.Byte(r / h);
                    dst[q + 1] = Maths.Byte(g / h);
                    dst[q + 0] = Maths.Byte(b / h);
                }
            });

            return;
        }
Esempio n. 26
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="rError"></param>
        /// <param name="gError"></param>
        /// <param name="bError"></param>
        /// <param name="ptr"></param>
        protected unsafe void Diffuse(int rError, int gError, int bError, byte *ptr)
        {
            float edR;  // error diffusion
            float edG;  // error diffusion
            float edB;  // error diffusion

            // do error diffusion to right-standing neighbors
            float[] row = matrix[0];
            int     jI, jP, i, k, jC, n;
            int     length = matrix.Length;


            for (jI = 1, jP = 4, jC = 0, k = row.Length; jC < k; jI++, jC++, jP += 4)
            {
                if (x + jI >= width)
                {
                    break;
                }

                edR         = ptr[jP + 2] + (rError * row[jC]) / summary;
                ptr[jP + 2] = Maths.Byte(edR);

                edG         = ptr[jP + 1] + (gError * row[jC]) / summary;
                ptr[jP + 1] = Maths.Byte(edG);

                edB         = ptr[jP + 0] + (bError * row[jC]) / summary;
                ptr[jP + 0] = Maths.Byte(edB);
            }

            // do error diffusion to bottom neigbors
            for (i = 1, n = length; i < n; i++)
            {
                if (y + i >= height)
                {
                    break;
                }

                // move pointer to next image line
                ptr += stride;

                // get coefficients of the row
                row = matrix[i];

                // process the row
                for (jC = 0, k = row.Length, jI = -(k >> 1), jP = -(k >> 1) * 4; jC < k; jI++, jC++, jP += 4)
                {
                    if (x + jI >= width)
                    {
                        break;
                    }
                    if (x + jI < 0)
                    {
                        continue;
                    }

                    edR         = ptr[jP + 2] + (rError * row[jC]) / summary;
                    ptr[jP + 2] = Maths.Byte(edR);

                    edG         = ptr[jP + 1] + (gError * row[jC]) / summary;
                    ptr[jP + 1] = Maths.Byte(edG);

                    edB         = ptr[jP + 0] + (bError * row[jC]) / summary;
                    ptr[jP + 0] = Maths.Byte(edB);
                }
            }
        }
Esempio n. 27
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        public unsafe void Apply(BitmapData bmData)
        {
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;
            byte *p = (byte *)bmData.Scan0.ToPointer();

            // channel subtraction
            if (Channel == RGBA.Red)
            {
                Parallel.For(0, height, y =>
                {
                    int x, ystride, k;
                    ystride = y * stride;

                    for (x = 0; x < width; x++)
                    {
                        k        = ystride + x * 4;
                        var luma = RGB.PAL(p[k + 2], p[k + 1], p[k]);
                        var diff = p[k + 2] - luma;

                        p[k] = p[k + 1] = p[k + 2] = Maths.Byte(127.5f + diff);
                    }
                });
            }
            else if (Channel == RGBA.Green)
            {
                Parallel.For(0, height, y =>
                {
                    int x, ystride, k;
                    ystride = y * stride;

                    for (x = 0; x < width; x++)
                    {
                        k        = ystride + x * 4;
                        var luma = RGB.PAL(p[k + 2], p[k + 1], p[k]);
                        var diff = p[k + 1] - luma;

                        p[k] = p[k + 1] = p[k + 2] = Maths.Byte(127.5f + diff);
                    }
                });
            }
            else
            {
                Parallel.For(0, height, y =>
                {
                    int x, ystride, k;
                    ystride = y * stride;

                    for (x = 0; x < width; x++)
                    {
                        k        = ystride + x * 4;
                        var luma = RGB.PAL(p[k + 2], p[k + 1], p[k]);
                        var diff = p[k] - luma;

                        p[k] = p[k + 1] = p[k + 2] = Maths.Byte(127.5f + diff);
                    }
                });
            }

            // histogram processing
            int[] hist = Statistics.Histogram(bmData);
            int   n    = hist.Length;
            int   z    = n / 2;

            int[] lef = new int[z];
            int[] rig = new int[z];

            for (int i = 0; i < z; i++)
            {
                lef[i] = hist[i];
                rig[i] = hist[i + z];
            }

            _       = Statistics.Max(lef, out int index1);
            _       = Statistics.Max(rig, out int index2);
            index2 += z;

            int count = index2 - index1;

            int[] center = new int[count];

            for (int i = 0; i < count; i++)
            {
                center[i] = hist[i + index1];
            }

            _          = Statistics.Min(center, out int threshold);
            threshold += index1;

            // creating mask
            Parallel.For(0, height, y =>
            {
                int x, ystride, k;
                ystride = y * stride;

                for (x = 0; x < width; x++)
                {
                    k = ystride + x * 4;

                    p[k] = p[k + 1] = p[k + 2] = (p[k] >= threshold) ? (byte)0 : (byte)255;
                }
            });

            return;
        }
Esempio n. 28
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        /// <param name="bmSrc">Bitmap data</param>
        public unsafe void Apply(BitmapData bmData, BitmapData bmSrc)
        {
            #region Data
            if (this.l0 != this.l1 && this.bilateral == true)
            {
                throw new Exception("Matrix must be squared");
            }

            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;
            byte *src = (byte *)bmSrc.Scan0.ToPointer();
            byte *dst = (byte *)bmData.Scan0.ToPointer();
            #endregion

            if (!this.bilateral)
            {
                Parallel.For(0, height, y =>
                {
                    float red, green, blue, div, k;
                    int x, i, j, ir, jr, yr, xr;
                    int ystride, v;
                    byte *p;

                    yr      = y - radius0;
                    ystride = y * stride;

                    for (x = 0; x < width; x++)
                    {
                        xr = x - radius1;
                        v  = ystride + x * 4;

                        red = green = blue = div = 0;

                        #region Convolution filtering
                        for (i = 0; i < l0; i++)
                        {
                            ir = yr + i;
                            if (ir < 0)
                            {
                                continue;
                            }
                            if (ir >= height)
                            {
                                break;
                            }

                            for (j = 0; j < l1; j++)
                            {
                                jr = xr + j;

                                if (jr < 0)
                                {
                                    continue;
                                }
                                if (jr >= width)
                                {
                                    break;
                                }

                                k = kernel[i][j];

                                if (k != 0)
                                {
                                    p    = &src[ir * stride + jr * 4];
                                    div += k;
                                    red += k * p[2]; green += k * p[1]; blue += k * p[0];
                                }
                            }
                        }
                        #endregion

                        #region Divider and offset
                        if (div != 0)
                        {
                            red   /= div;
                            green /= div;
                            blue  /= div;
                        }
                        if (offset != 0)
                        {
                            red   += offset;
                            green += offset;
                            blue  += offset;
                        }
                        #endregion

                        #region Recording pixel
                        dst[v + 2] = Maths.Byte(red);
                        dst[v + 1] = Maths.Byte(green);
                        dst[v]     = Maths.Byte(blue);
                        #endregion
                    }
                });
            }
            else
            {
                Parallel.For(0, height, y =>
                {
                    float red1, green1, blue1, div1, k1;
                    float red2, green2, blue2, div2, k2;
                    int x, i, j, ir, jr, yr, xr;
                    int ystride, v;
                    byte *p;

                    yr      = y - radius0;
                    ystride = y * stride;

                    for (x = 0; x < width; x++)
                    {
                        xr = x - radius1;
                        v  = ystride + x * 4;

                        red1 = green1 = blue1 = div1 = 0;
                        red2 = green2 = blue2 = div2 = 0;

                        #region Convolution filtering
                        for (i = 0; i < l0; i++)
                        {
                            ir = yr + i;
                            if (ir < 0)
                            {
                                continue;
                            }
                            if (ir >= height)
                            {
                                break;
                            }

                            for (j = 0; j < l1; j++)
                            {
                                jr = xr + j;

                                if (jr < 0)
                                {
                                    continue;
                                }
                                if (jr >= width)
                                {
                                    break;
                                }

                                k1 = kernel[i][j]; k2 = kernel[j][i];

                                p = &src[ir * stride + jr * 4];

                                div1 += k1; div2 += k2;
                                red1 += k1 * p[2]; green1 += k1 * p[1]; blue1 += k1 * p[0];
                                red2 += k2 * p[2]; green2 += k2 * p[1]; blue2 += k2 * p[0];
                            }
                        }
                        #endregion

                        #region Divider and offset
                        if (div1 != 0)
                        {
                            red1   /= div1;
                            green1 /= div1;
                            blue1  /= div1;
                        }
                        if (div2 != 0)
                        {
                            red2   /= div2;
                            green2 /= div2;
                            blue2  /= div2;
                        }
                        if (offset != 0)
                        {
                            red1   += offset;
                            green1 += offset;
                            blue1  += offset;

                            red2   += offset;
                            green2 += offset;
                            blue2  += offset;
                        }
                        #endregion

                        #region Recording pixel
                        dst[v + 2] = Maths.Byte(G(red1, red2));
                        dst[v + 1] = Maths.Byte(G(green1, green2));
                        dst[v]     = Maths.Byte(G(blue1, blue2));
                        #endregion
                    }
                });
            }

            return;
        }
Esempio n. 29
0
        /// <summary>
        /// Apply filter.
        /// </summary>
        /// <param name="bmData">Bitmap data</param>
        /// <param name="bmSrc">Bitmap data</param>
        public unsafe void Apply(BitmapData bmData, BitmapData bmSrc)
        {
            #region Data
            int   width = bmData.Width, height = bmData.Height, stride = bmData.Stride;
            byte *src = (byte *)bmSrc.Scan0.ToPointer();
            byte *dst = (byte *)bmData.Scan0.ToPointer();
            #endregion

            Parallel.For(0, height, y =>
            {
                int[] H   = new int[256];
                int[] cdf = new int[256];
                int n     = l0 * l1;
                int brightness;
                float dn = 255.0f / n;

                int x, i, j, ir, jr, yr, xr, irstride;
                int ystride, v;
                byte *p;

                yr      = y - rw;
                ystride = y * stride;

                for (x = 0; x < width; x++)
                {
                    xr = x - rh;
                    v  = ystride + x * 4;

                    #region Convolution filtering
                    for (i = 0; i < l0; i++)
                    {
                        ir = yr + i;
                        if (ir < 0)
                        {
                            continue;
                        }
                        if (ir >= height)
                        {
                            break;
                        }
                        irstride = ir * stride;

                        for (j = 0; j < l1; j++)
                        {
                            jr = xr + j;

                            if (jr < 0)
                            {
                                continue;
                            }
                            if (jr >= width)
                            {
                                break;
                            }

                            p          = &src[irstride + jr * 4];
                            brightness = (p[2] + p[1] + p[0]) / 3;
                            H[brightness]++;
                        }
                    }
                    #endregion

                    #region Density function
                    cdf[0] = H[0];

                    for (i = 1; i < 256; i++)
                    {
                        cdf[i] = H[i] + cdf[i - 1];
                    }
                    #endregion

                    #region Recording pixel
                    dst[v + 2] = Maths.Byte(cdf[src[v + 2]] * dn);
                    dst[v + 1] = Maths.Byte(cdf[src[v + 1]] * dn);
                    dst[v]     = Maths.Byte(cdf[src[v]] * dn);
                    #endregion

                    #region Clear data
                    Array.Clear(H, 0, 256);
                    Array.Clear(cdf, 0, 256);
                    #endregion
                }
            }
                         );

            return;
        }
Esempio n. 30
0
        /// <summary>
        /// Local laplacian filter.
        /// </summary>
        /// <param name="input">Input data</param>
        /// <param name="radius">Radius</param>
        /// <param name="sigma">Sigma</param>
        /// <param name="factor">Factor</param>
        /// <param name="n">Number of steps</param>
        /// <param name="levels">Levels</param>
        /// <returns>Output data</returns>
        internal static void llfilter(float[] input, int radius, float sigma, float factor, int n, int levels)
        {
            // exception
            if (factor == 0)
            {
                return;
            }

            // data
            int   height = input.GetLength(0);
            int   y, level, length = 256;
            float step = 1.0f / n;
            float min = 0.0f, max = 1.0f;

            // pyramids
            int n_levels = (int)Math.Min((Math.Log(height) / Math.Log(2)), levels);
            LaplacianPyramidTransform lpt = new LaplacianPyramidTransform(n_levels, radius);
            GaussianPyramidTransform  gpt = new GaussianPyramidTransform(n_levels, radius);

            float[][] input_gaussian_pyr = gpt.Forward(input);
            float[][] output_laplace_pyr = lpt.Forward(input_gaussian_pyr);
            float[][] temp_laplace_pyr;
            float[]   I_temp, I_gaus, I_outp;
            float[]   T;

            // do job
            for (float i = min; i <= max; i += step)
            {
                height = input.GetLength(0);
                I_temp = new float[height];
                T      = Rem(sigma, factor, i, length);

                // remapping function
                for (y = 0; y < height; y++)
                {
                    I_temp[y] = T[Maths.Byte(input[y] * (length - 1))];
                }

                temp_laplace_pyr = lpt.Forward(I_temp);
                T = Rec(i, step, length);

                // pyramid reconstruction
                for (level = 0; level < n_levels; level++)
                {
                    I_gaus = input_gaussian_pyr[level];
                    I_temp = temp_laplace_pyr[level];
                    I_outp = output_laplace_pyr[level];
                    height = I_outp.GetLength(0);

                    for (y = 0; y < height; y++)
                    {
                        I_outp[y] += T[Maths.Byte(I_gaus[y] * (length - 1))] * I_temp[y];
                    }

                    output_laplace_pyr[level] = I_outp;
                }
            }

            // backward transform
            I_outp = lpt.Backward(output_laplace_pyr);
            height = input.GetLength(0);

            for (y = 0; y < height; y++)
            {
                input[y] = I_outp[y];
            }

            return;
        }