Esempio n. 1
0
        public void GaussianBlur(double sigma = 1.0, bool normalize = false, int?kernelSize = null)
        {
            var _kernel = new ConvolutionKernel();

            _kernel.MakeGaussianKernel(sigma, kernelSize);
            if (normalize)
            {
                _kernel.Normalize();
            }
            Convolution(_kernel, EdgeHandling.Extend);
        }
Esempio n. 2
0
        public void Convolution(ConvolutionKernel kernel, EdgeHandling edgeHandling)
        {
            unsafe
            {
                var                  _workingBitmap             = new Bitmap(Image);
                var                  _rect                      = new Rectangle(0, 0, Image.Width, Image.Height);
                BitmapData           _originalBitmapData        = Image.LockBits(_rect, ImageLockMode.ReadWrite, Image.PixelFormat);
                var                  _workingBitmapData         = _workingBitmap.LockBits(_rect, ImageLockMode.ReadWrite, Image.PixelFormat);
                int                  _bytesPerPixel             = Bitmap.GetPixelFormatSize(Image.PixelFormat) / 8;
                int                  _heightInPixels            = _originalBitmapData.Height;
                int                  _widthInBytes              = _originalBitmapData.Width * _bytesPerPixel;
                int                  _offset                    = kernel.Offset;
                int                  _imageOffset               = 0; //edge position
                byte *               _firstPixelPointerOriginal = (byte *)_originalBitmapData.Scan0;
                byte *               _firstPixelPointerWorking  = (byte *)_workingBitmapData.Scan0;
                byte *[]             _rowsOriginal              = new byte *[_heightInPixels];
                Func <int, int, int> _clamping                  = null;
                switch (edgeHandling)
                {
                case EdgeHandling.Extend:
                    _clamping = ClampExtend;
                    break;

                case EdgeHandling.Wrap:
                    _clamping = ClampWrap;
                    break;

                case EdgeHandling.Mirror:
                    _clamping = ClampMirror;
                    break;

                case EdgeHandling.Crop:
                default:
                    _imageOffset = kernel.Offset;
                    _clamping    = ClampCrop;
                    break;
                }
                for (int i = 0; i < _heightInPixels; i++)
                {
                    _rowsOriginal[i] = _firstPixelPointerOriginal + (i * _originalBitmapData.Stride);
                }
                //BGR format
                for (int y = _imageOffset; y < _heightInPixels - _imageOffset; y++)
                {
                    for (int x = _imageOffset * _bytesPerPixel; x < _widthInBytes - _imageOffset * _bytesPerPixel; x = x + _bytesPerPixel)
                    {
                        double _r = 0.0;
                        double _g = 0.0;
                        double _b = 0.0;
                        byte * _workingScanLine = _firstPixelPointerWorking + (y * _workingBitmapData.Stride);
                        for (int ky = -_offset; ky <= _offset; ky++)
                        {
                            int _yOffset = _clamping(y + ky, _heightInPixels - 1);
                            //
                            byte *_originalScanLine = _rowsOriginal[_yOffset];
                            for (int kx = -_offset; kx <= _offset; kx++)
                            {
                                double _k       = kernel[kx, ky];
                                int    _xOffset = _clamping(x + kx * _bytesPerPixel, _widthInBytes - 3);
                                _b += _originalScanLine[_xOffset] * _k;
                                _g += _originalScanLine[_xOffset + 1] * _k;
                                _r += _originalScanLine[_xOffset + 2] * _k;
                            }
                        }
                        _workingScanLine[x]     = Clamp(_b / kernel.NormalizationFactor + kernel.Bias);
                        _workingScanLine[x + 1] = Clamp(_g / kernel.NormalizationFactor + kernel.Bias);
                        _workingScanLine[x + 2] = Clamp(_r / kernel.NormalizationFactor + kernel.Bias);
                    }
                }
                _workingBitmap.UnlockBits(_workingBitmapData);
                Image.UnlockBits(_originalBitmapData);
                Image = _workingBitmap;
                //originalBitmap = _workingBitmap.Clone(_rect, originalBitmap.PixelFormat);
                //_workingBitmap.Save(@"C:\Users\rokr\Desktop\aaa_no.bmp");
            }
        }