Пример #1
0
        public static Bitmap Step2(Bitmap bmp)
        {
            int[][]     mat    = ImageConvert.Bitmap2Mat(bmp);
            ConvKernel  kernel = ConvKernel.GetKMeanKernal(3);
            Convolution conv   = new Convolution();

            conv.Calculate(mat, kernel, out mat);
            Bitmap result = ImageConvert.Mat2Bitmap(mat);

            return(result);
        }
Пример #2
0
        /// <summary>
        /// foamliu, 2009/02/01, 用两个核进行卷积.
        /// 主要用于边缘算子.
        ///
        /// </summary>
        /// <param name="input"></param>
        /// <param name="kernel"></param>
        /// <param name="output"></param>
        public void CalculateEdge(int[][] input, ConvKernel kx, ConvKernel ky, out int[][] output, ConvNorm norm)
        {
            int width  = input.Length;
            int height = input[0].Length;

            output = Util.BuildMatInt(width, height);

            int m = kx.M;
            int n = kx.N;

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    double Gx = 0;
                    double Gy = 0;
                    for (int j = -n; j <= n; j++)
                    {
                        for (int i = -m; i <= m; i++)
                        {
                            Gx += Util.GetPixel(input, x - i, y - j) * kx.Filter(i, j);
                            Gy += Util.GetPixel(input, x - i, y - j) * ky.Filter(i, j);
                        }
                    }

                    if (norm == ConvNorm.Norm_1)
                    {
                        // 1-范数 (1-norm)
                        output[x][y] = System.Convert.ToInt32(Math.Abs(Gx) + Math.Abs(Gy));
                        //  foamliu, 2009/02/03, 用 2-norm 更准确, 但是我看不出差别,
                        //  而且1-范数较快.
                    }
                    else if (norm == ConvNorm.Norm_2)
                    {
                        // 2-范数 (2-norm)
                        output[x][y] = (int)(Math.Sqrt(Gx * Gx + Gy * Gy));
                    }

                    // foamliu, 2009/02/03, 这两个梯度可以用于求方向 theta:
                    // theta = arctan(Gy/Gx).
                    // 当 theta = 0 时是一条垂直边界, 左侧更暗.

                    // 梯度大的地方更亮.
                }
            }
        }
Пример #3
0
        /// <summary>
        /// foamliu, 2009/01/29, k × k (k = 2n + 1) 均值核.
        ///
        /// </summary>
        /// <param name="k"></param>
        /// <returns></returns>
        public static ConvKernel GetKMeanKernal(int k)
        {
            int n = (k - 1) / 2;

            double[][] filter = Util.BuildMat(k, k);

            for (int i = 0; i <= 2 * n; i++)
            {
                for (int j = 0; j <= 2 * n; j++)
                {
                    filter[i][j] = 1.0 / (k * k);
                }
            }

            ConvKernel conv = new ConvKernel(n, n, filter);

            return(conv);
        }
Пример #4
0
        public void Calculate(int[][] input, ConvKernel kernel, out int[][] output)
        {
            int width  = input.Length;
            int height = input[0].Length;

            output = new int[width][];

            for (int i = 0; i < width; i++)
            {
                output[i] = new int[height];
            }

            if (kernel == null)
            {
                return;
            }

            int m = kernel.M;
            int n = kernel.N;

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    double sum = 0;
                    for (int j = -n; j <= n; j++)
                    {
                        for (int i = -m; i <= m; i++)
                        {
                            sum += Util.GetPixel(input, x - i, y - j) * kernel.Filter(i, j);
                        }
                    }
                    //output[x][y] = (int)Math.Abs(sum);
                    //  foamliu, 2009/02/03, 这里不应取绝对值, 这么做使得在做图像锐化时犯了
                    //  <<数字图像处理 "Digital Image Processing Using MATLAB">> 图3.16 (b) 一样的错误.
                    //  正确的做法是保持负值, 用正规化处理.
                    output[x][y] = System.Convert.ToInt32(sum);
                }
            }
        }