예제 #1
0
        public static Bitmap ApplySodel(Bitmap srcImage)
        {
            var xkernel = xSobel;
            var ykernel = ySobel;

            ImageUtils image  = new ImageUtils();
            var        buffer = image.BitmapToBytes(srcImage);
            var        width  = image.Width;
            var        height = image.Height;
            var        bytes  = image.Bytes;
            var        result = new byte[bytes];

            directions = new double[bytes / 4];
            resultBuf  = new byte[bytes / 4];
            xGradients = new double[bytes / 4];
            yGradients = new double[bytes / 4];

            var rgb = 0.0;

            for (int i = 0; i < buffer.Length; i += 4)
            {
                rgb           = buffer[i] * .3f;
                rgb          += buffer[i + 1] * .6f;
                rgb          += buffer[i + 2] * .1f;
                buffer[i]     = (byte)rgb;
                buffer[i + 1] = buffer[i];
                buffer[i + 2] = buffer[i];
                buffer[i + 3] = 255;
            }
            var x       = 0.0;
            var y       = 0.0;
            var results = 0.0;

            var filterOffset = 1;
            var calcOffset   = 0;
            var byteOffset   = 0;

            for (var offsetY = filterOffset; offsetY < height - filterOffset; ++offsetY)
            {
                for (var offsetX = filterOffset; offsetX < width - filterOffset; ++offsetX)
                {
                    x       = y = 0;
                    results = 0.0;

                    byteOffset = offsetY * 4 * width + offsetX * 4;

                    for (var filterY = -filterOffset; filterY <= filterOffset; filterY++)
                    {
                        for (var filterX = -filterOffset; filterX <= filterOffset; filterX++)
                        {
                            calcOffset = byteOffset + filterX * 4 + filterY * 4 * width;
                            x         += (double)(buffer[calcOffset]) * xkernel[filterY + filterOffset, filterX + filterOffset];
                            y         += (double)(buffer[calcOffset]) * ykernel[filterY + filterOffset, filterX + filterOffset];
                        }
                    }
                    xGradients[byteOffset / 4] = x;
                    yGradients[byteOffset / 4] = y;
                    results += Math.Sqrt((x * x) + (y * y));

                    if (results > 255)
                    {
                        results = 255;
                    }
                    else if (results < 0)
                    {
                        results = 0;
                    }

                    if (x != 0)
                    {
                        var dirNotNorm = 57.29 * 1.0 / Math.Tan(y / x);
                        if (Math.Tan(y / x) == 0)
                        {
                            directions[byteOffset / 4] = 0;
                        }
                        else
                        {
                            directions[byteOffset / 4] = NormalizeDirection(dirNotNorm);
                        }
                    }
                    else
                    {
                        directions[byteOffset / 4] = 0;
                    }

                    resultBuf[byteOffset / 4] = (byte)results;

                    result[byteOffset]     = (byte)(results);
                    result[byteOffset + 1] = (byte)(results);
                    result[byteOffset + 2] = (byte)(results);
                    result[byteOffset + 3] = 255;
                }
            }
            return(image.BytesToBitmap(result));
        }