Exemplo n.º 1
0
            // One byte images only
            private byte[] PerformConvolution(byte[] inImage, Box size, ConvolutionKernel kernel)
            {
                byte[] outImage        = new byte[inImage.Length];
                int    kernelHeight    = kernel.Kernel.GetLength(0);
                int    kernelWidth     = kernel.Kernel.GetLength(1);
                int    kernelCenterRow = kernelWidth / 2;
                int    kernelCenterCol = kernelHeight / 2;

                int accumulator;

                for (int imageRow = 0; imageRow < size.Height; ++imageRow)
                {
                    for (int imageCol = 200; imageCol < size.Width - 200; ++imageCol)
                    {
                        byte outValue = 0;
                        accumulator = 0;
                        for (int kernelRow = 0; kernelRow < kernelHeight; ++kernelRow)
                        {
                            for (int kernelCol = 0; kernelCol < kernelWidth; ++kernelCol)
                            {
                                accumulator += kernel.Kernel[kernelRow, kernelCol] * GetPixelAt(inImage, size, imageRow + (kernelRow - kernelCenterRow), imageCol + (kernelCol - kernelCenterCol), 0);
                            }
                        }
                        outValue = (byte)((float)accumulator * kernel.Multiplier);
                        outImage[imageRow * size.Width + imageCol] = outValue;
                    }
                }
                return(outImage);
            }
        public MNISTConvolutionNN(Variable features, DeviceDescriptor device, int outputDesmintations = 10, string classifierName = "classifierOutput")
        {
            // Set local private variables
            this.device   = device;
            this.features = features;

            // Create and connect a convolution neutral network for MNIST
            // 1. Convolution layer I
            // Kernel size = 3 x 3, Input size = 28 x 28 x 1, Output size = 12 x 12 x 30
            ConvolutionKernel kernel1 = new ConvolutionKernel()
            {
                width               = 3,
                height              = 3,
                input_channel       = 1,
                output_map_channel  = 30,
                vStride             = 2,
                hStride             = 2,
                poolingWindowWidth  = 3,
                poolingWindowHeight = 3,
            };

            Function convolutionPooling1 = ConvolutionWithMaxPooling(inputLayer: features, kernel: kernel1);

            // 2. Convolution layer II
            // Kernel size = 3 x 3, Input size = 12 x 12 x 30, Output size =  8 x 8 x 10
            ConvolutionKernel kernel2 = new ConvolutionKernel()
            {
                width               = 3,
                height              = 3,
                input_channel       = kernel1.output_map_channel,
                output_map_channel  = 10,
                vStride             = 1,
                hStride             = 1,
                poolingWindowWidth  = 3,
                poolingWindowHeight = 3,
            };

            Function convolutionPooling2 = ConvolutionWithMaxPooling(inputLayer: convolutionPooling1, kernel: kernel2);

            // 3. Reshape layer
            Function reshaped = Flatten(convolutionPooling2);
            // int planeDimension = ((Variable)convolutionPooling2).Shape.Dimensions.Aggregate((d1, d2) => d1 * d2);
            // Function reshaped = Reshape(convolutionPooling2, new int[] { planeDimension });

            // 4. Fully connected layer I
            Function fullyConnectedI = Sigmoid(FullyConnectedLinearLayer(reshaped, 240, "outputl1"), "SigmoidI");

            // 5. Fully connected layer II
            Function fullyConnectedII = Sigmoid(FullyConnectedLinearLayer(fullyConnectedI, 100, "outputl2"), "SigmoidII");

            // 6. Fully connected layer III
            Function fullyConnectedIII = FullyConnectedLinearLayer(fullyConnectedII, outputDesmintations, "outputl3");

            // 7. Softmax layer
            Function softmaxLayer = Softmax(fullyConnectedIII, classifierName);

            cnn_function = softmaxLayer;
        }
Exemplo n.º 3
0
        public void HorizontalEdgeBi(Bitmap image)
        {
            int[,] matrix =
            {
                { -1, 0, 1 }
            };
            Bitmap destination = DuplicateBitmap(image);
            var    convolveOp  = new ConvolveOp();
            var    kernel      = new ConvolutionKernel
            {
                Size   = 3,
                Matrix = matrix
            };

            destination = convolveOp.Convolve(image, kernel);
        }
Exemplo n.º 4
0
        public new void VerticalEdgeDetector(Bitmap source)
        {
            int[,] matrix =
            {
                { -1, 0, 1 }
            };
            Bitmap destination = DuplicateBitmap(source);
            var    convolveOp  = new ConvolveOp();
            var    kernel      = new ConvolutionKernel
            {
                Size   = 3,
                Matrix = matrix
            };

            destination = convolveOp.Convolve(source, kernel);
        }
Exemplo n.º 5
0
        public void FullEdgeDetector(Bitmap source)
        {
            int[,] verticalMatrix =
            {
                { -1, 0, 1 },
                { -2, 0, 2 },
                { -1, 0, 1 }
            };
            int[,] horizontalMatrix =
            {
                { -1, -2, -1 },
                {  0,  0,  0 },
                {  1,  2,  1 }
            };

            Bitmap i1 = CreateBlankBitmap(source);
            Bitmap i2 = CreateBlankBitmap(source);

            var convolveOp = new ConvolveOp();
            var kernel     = new ConvolutionKernel
            {
                Size   = 3,
                Matrix = verticalMatrix
            };

            i1 = convolveOp.Convolve(source, kernel);

            kernel        = new ConvolutionKernel();
            kernel.Size   = 3;
            kernel.Matrix = horizontalMatrix;
            i2            = convolveOp.Convolve(source, kernel);

            int w = source.Width;
            int h = source.Height;

            for (int x = 0; x < w; x++)
            {
                for (int y = 0; y < h; y++)
                {
                    float sum = 0.0f;
                    sum += GetBrightness(i1, x, y);
                    sum += GetBrightness(i2, x, y);
                    SetBrightness(source, x, y, Math.Min(1.0f, sum));
                }
            }
        }
        private Function ConvolutionWithMaxPooling(Variable inputLayer, ConvolutionKernel kernel)
        {
            double convWScale = 0.26;

            // Configure a convolution layer
            Parameter conv_para = new Parameter(
                shape: new int[] { kernel.width, kernel.height, kernel.input_channel, kernel.output_map_channel },
                dataType: DataType.Float, initializer: GlorotUniformInitializer(convWScale, -1, 2), device: device);
            Function convolution = LeakyReLU(operand: Convolution(convolutionMap: conv_para, operand: inputLayer, strides: new int[] { 1, 1, kernel.input_channel }), alpha: 0.3f);

            Function pooling = Pooling(operand: convolution, poolingType: PoolingType.Max,
                                       poolingWindowShape: new int[] { kernel.poolingWindowWidth, kernel.poolingWindowHeight },
                                       strides: new int[] { kernel.hStride, kernel.vStride },
                                       autoPadding: new bool[] { true });

            return(pooling);
        }
Exemplo n.º 7
0
        public void VerticalEdgeBitmap(Bitmap image)
        {
            Bitmap imageCopy = DuplicateBitmap(image);

            int[,] data =
            {
                { -1, 0, 1 },
                { -1, 0, 1 },
                { -1, 0, 1 },
                { -1, 0, 1 }
            };
            ConvolveOp convolveOp = new ConvolveOp();
            var        kernel     = new ConvolutionKernel();

            kernel.Size   = 3;
            kernel.Matrix = data;
            imageCopy     = convolveOp.Convolve(image, kernel);
        }
Exemplo n.º 8
0
        public void HorizontalEdgeDetector(Bitmap source)
        {
            Bitmap destination = DuplicateBitmap(source);

            int[,] matrix =
            {
                { -1, -2, -1 },
                {  0,  0,  0 },
                {  1,  2,  1 }
            };
            var convolveOp = new ConvolveOp();
            var kernel     = new ConvolutionKernel
            {
                Size   = 3,
                Matrix = matrix
            };

            destination = convolveOp.Convolve(source, kernel);
        }
Exemplo n.º 9
0
        public void VerticalEdgeDetector(Bitmap source)
        {
            Bitmap destination = DuplicateBitmap(source);

            int[,] datset1 =
            {
                { -1, 0, 1 },
                { -2, 0, 2 },
                { -1, 0, 1 }
            };

            var convolveOp = new ConvolveOp();
            var kernel     = new ConvolutionKernel
            {
                Size   = 3,
                Matrix = datset1
            };

            destination = convolveOp.Convolve(source, kernel);
        }
Exemplo n.º 10
0
        public GestureOverlay()
        {
            InitializeComponent();

            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.UserPaint, true);

            var outlineDivisor = 5700;
            var outlineBias = -1000;

            BlurFilter = new ConvolutionKernel(
                outlineDivisor, outlineBias,
                0, 0, 0, 1000, 0, 0, 0,
                0, 0, 1000, 2000, 1000, 0, 0,
                0, 1000, 2000, 4000, 2000, 1000, 0,
                1000, 2000, 4000, -44000, 4000, 2000, 1000,
                0, 1000, 2000, 4000, 2000, 1000, 0,
                0, 0, 1000, 2000, 1000, 0, 0,
                0, 0, 0, 1000, 0, 0, 0
            );
        }
Exemplo n.º 11
0
 public void ApplyConvolution(ConvolutionKernel k)
 {
     ApplyConvolution(this, k);
 }
Exemplo n.º 12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="x"></param>
        /// <param name="bw"></param>
        /// <param name="bwSel"></param>
        /// <param name="adjust"></param>
        /// <param name="kernel"></param>
        /// <param name="weights"></param>
        /// <param name="width"></param>
        /// <param name="widthSel"></param>
        /// <param name="n"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="cut"></param>
        /// <remarks>Adapted from the R-project (www.r-project.org), Version 2.72, file density.R</remarks>
        public static ProbabilityDensityResult ProbabilityDensity(
            this IReadOnlyList <double> x,
            double bw,
            string bwSel,
            double adjust,
            ConvolutionKernel kernel,
            IReadOnlyList <double> weights,
            double width,
            string widthSel,
            int n,
            double from,
            double to,
            double cut // default: 3
            )
        {
            double wsum;

            if (null == weights)
            {
                weights = VectorMath.GetConstantVector(1.0 / x.Count, x.Count);
                wsum    = 1;
            }
            else
            {
                wsum = weights.Sum();
            }

            double totMass = 1;

            int n_user = n;

            n = Math.Max(n, 512);
            if (n > 512)
            {
                n = BinaryMath.NextPowerOfTwoGreaterOrEqualThan(n);
            }

            if (bw.IsNaN() && !(width.IsNaN() && null == widthSel))
            {
                if (!width.IsNaN())
                {
                    // S has width equal to the length of the support of the kernel
                    // except for the gaussian where it is 4 * sd.
                    // R has bw a multiple of the sd.
                    double fac = 1;
                    switch (kernel)
                    {
                    case ConvolutionKernel.Gaussian:
                        fac = 4;
                        break;

                    case ConvolutionKernel.Rectangular:
                        fac = 2 * Math.Sqrt(3);
                        break;

                    case ConvolutionKernel.Triangular:
                        fac = 2 * Math.Sqrt(6);
                        break;

                    case ConvolutionKernel.Epanechnikov:
                        fac = 2 * Math.Sqrt(5);
                        break;

                    case ConvolutionKernel.Biweight:
                        fac = 2 * Math.Sqrt(7);
                        break;

                    case ConvolutionKernel.Cosine:
                        fac = 2 / Math.Sqrt(1 / 3 - 2 / (Math.PI * Math.PI));
                        break;

                    case ConvolutionKernel.Optcosine:
                        fac = 2 / Math.Sqrt(1 - 8 / (Math.PI * Math.PI));
                        break;

                    default:
                        throw new ArgumentException("Unknown convolution kernel");
                    }
                    bw = width / fac;
                }
                else
                {
                    bwSel = widthSel;
                }
            }

            if (null != bwSel)
            {
                if (x.Count < 2)
                {
                    throw new ArgumentException("need at least 2 points to select a bandwidth automatically");
                }
                switch (bwSel.ToLowerInvariant())
                {
                case "nrd0":
                    //nrd0 = bw.nrd0(x),
                    break;

                case "nrd":
                    //nrd = bw.nrd(x),
                    break;

                case "ucv":
                    //ucv = bw.ucv(x),
                    break;

                case "bcv":
                    //bcv = bw.bcv(x),
                    break;

                case "sj":
                    //sj = , "sj-ste" = bw.SJ(x, method="ste"),
                    break;

                case "sj-dpi":
                    //"sj-dpi" = bw.SJ(x, method="dpi"),
                    break;

                default:
                    throw new ArgumentException("Unknown bandwith selection rule: " + bwSel.ToString());
                }
            }

            if (!RMath.IsFinite(bw))
            {
                throw new ArithmeticException("Bandwidth is not finite");
            }

            bw = adjust * bw;

            if (!(bw > 0))
            {
                throw new ArithmeticException("Bandwith is not positive");
            }

            if (from.IsNaN())
            {
                from = x.Min() - cut * bw;
            }
            if (to.IsNaN())
            {
                to = x.Max() + cut * bw;
            }

            if (!RMath.IsFinite(from))
            {
                throw new ArithmeticException("non-finite 'from'");
            }
            if (!to.IsFinite())
            {
                throw new ArithmeticException("non-finite 'to'");
            }
            double lo = from - 4 * bw;
            double up = to + 4 * bw;

            var y = new DoubleVector(2 * n);

            MassDistribution(x, weights, lo, up, y, n);
            y.Multiply(totMass);

            var kords = new DoubleVector(2 * n);

            kords.FillWithLinearSequenceGivenByStartAndEnd(0, 2 * (up - lo));

            for (int i = n + 1, j = n - 1; j >= 0; i++, j--)
            {
                kords[i] = -kords[j];
            }

            switch (kernel)
            {
            case ConvolutionKernel.Gaussian:
                kords.Map(new Probability.NormalDistribution(0, bw).PDF);
                break;

            case ConvolutionKernel.Rectangular:
                double a = bw * Math.Sqrt(3);
                kords.Map(delegate(double xx)
                          { return(Math.Abs(xx) < a ? 0.5 / a : 0); });
                break;

            case ConvolutionKernel.Triangular:
                a = bw * Math.Sqrt(6);
                kords.Map(delegate(double xx)
                          { return(Math.Abs(xx) < a ? (1 - Math.Abs(xx) / a) / a : 0); });
                break;

            case ConvolutionKernel.Epanechnikov:
                a = bw * Math.Sqrt(5);
                kords.Map(delegate(double xx)
                          { return(Math.Abs(xx) < a ? 0.75 * (1 - RMath.Pow2(Math.Abs(xx) / a)) / a : 0); });
                break;

            case ConvolutionKernel.Biweight:
                a = bw * Math.Sqrt(7);
                kords.Map(delegate(double xx)
                          { return(Math.Abs(xx) < a ? 15.0 / 16.0 * RMath.Pow2(1 - RMath.Pow2(Math.Abs(xx) / a)) / a : 0); });
                break;

            case ConvolutionKernel.Cosine:
                a = bw / Math.Sqrt(1.0 / 3 - 2 / RMath.Pow2(Math.PI));
                kords.Map(delegate(double xx)
                          { return(Math.Abs(xx) < a ? (1 + Math.Cos(Math.PI * xx / a)) / (2 * a) : 0); });
                break;

            case ConvolutionKernel.Optcosine:
                a = bw / Math.Sqrt(1 - 8 / RMath.Pow2(Math.PI));
                kords.Map(delegate(double xx)
                          { return(Math.Abs(xx) < a ? Math.PI / 4 * Math.Cos(Math.PI * xx / (2 * a)) / a : 0); });
                break;

            default:
                throw new ArgumentException("Unknown convolution kernel");
            }

            var result = new DoubleVector(2 * n);

            Fourier.FastHartleyTransform.CyclicRealConvolution(y.GetInternalData(), kords.GetInternalData(), result.GetInternalData(), 2 * n, null);
            y.Multiply(1.0 / (2 * n));
            VectorMath.MaxOf(y, 0, y);
            var xords = VectorMath.CreateEquidistantSequenceByStartEndLength(lo, up, n);
            var xu    = VectorMath.CreateEquidistantSequenceByStartEndLength(from, to, n_user);

            double[] res2 = new double[xu.Length];
            Interpolation.LinearInterpolation.Interpolate(xords, result, n, xu, xu.Length, 0, out res2);

            return(new ProbabilityDensityResult()
            {
                X = xu, Y = VectorMath.ToROVector(res2), Bandwidth = bw
            });
        }
Exemplo n.º 13
0
            static FrameManager()
            {
                _instance = new FrameManager();
                _sensor   = KinectSensor.GetDefault();
                _frameResolutions[SourceType.COLOR]        = Box.S_1920_1080;
                _frameResolutions[SourceType.GREEN_SCREEN] = Box.S_1920_1080;
                _frameResolutions[SourceType.DEPTH]        = Box.S_512_424;
                _frameResolutions[SourceType.INFRARED]     = Box.S_512_424;
                _frameResolutions[SourceType.BODY_INDEX]   = Box.S_512_424;
                _frameResolutions[SourceType.BACKGROUND]   = _frameResolutions[SourceType.GREEN_SCREEN];

                foreach (SourceType thisSourceType in _frameResolutions.Keys)
                {
                    _displayableBuffers[thisSourceType] = new byte[_frameResolutions[thisSourceType].Area * (_outputPixelFormat.BitsPerPixel / 8)];
                }

                _bodyIndexToColorMap.Add(0, 0xFF0000FF); // BLUE
                _bodyIndexToColorMap.Add(1, 0x00FF00FF); // GREEN
                _bodyIndexToColorMap.Add(2, 0x0000FFFF); // RED
                _bodyIndexToColorMap.Add(3, 0x00FFFFFF); // YELLOW
                _bodyIndexToColorMap.Add(4, 0xFF00FFFF); // PURPLE
                _bodyIndexToColorMap.Add(5, 0xFFFFFFFF); // WHITE

                foreach (int bodyIndex in _bodyIndexToColorMap.Keys)
                {
                    _colorToBodyIndexMap.Add(_bodyIndexToColorMap[bodyIndex], bodyIndex);
                }

                _instance.InitializeBackgroundImage();

                _rawDepthPixels     = new UInt16[_frameResolutions[SourceType.DEPTH].Area];
                _rawInfraredPixels  = new UInt16[_frameResolutions[SourceType.INFRARED].Area];
                _rawBodyIndexPixels = new byte[_frameResolutions[SourceType.BODY_INDEX].Area];
                _cameraSpacePoints  = new CameraSpacePoint[Box.S_1920_1080.Area];

                _boxBlur_3_by_3 = new ConvolutionKernel(1.0f / 9f, new int[, ] {
                    { 1, 1, 1 },
                    { 1, 1, 1 },
                    { 1, 1, 1 },
                });

                _boxBlur_5_by_5 = new ConvolutionKernel(1.0f / 25f, new int[, ] {
                    { 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1 },
                });

                _boxBlur_7_by_7 = new ConvolutionKernel(1.0f / 49f, new int[, ] {
                    { 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1 },
                });

                _boxBlur_9_by_9 = new ConvolutionKernel(1.0f / 81f, new int[, ] {
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 }
                });

                _identity_3_by_3 = new ConvolutionKernel(1, new int[, ] {
                    { 1, 0, 0 },
                    { 0, 1, 0 },
                    { 0, 0, 1 }
                });

                _gaussianBlur_5_by_5 = new ConvolutionKernel(1.0f / 256.0f, new int[, ] {
                    { 1, 4, 6, 4, 1 },
                    { 4, 16, 24, 16, 4 },
                    { 6, 24, 36, 24, 6 },
                    { 4, 16, 24, 16, 4 },
                    { 1, 4, 6, 4, 1 },
                });

                _gaussianBlur_3_by_3 = new ConvolutionKernel(1.0f / 16.0f, new int[, ] {
                    { 1, 2, 1 },
                    { 2, 4, 2 },
                    { 1, 2, 1 }
                });

                _edgeDetection = new ConvolutionKernel(1.0f, new int[, ] {
                    { -1, -1, -1 },
                    { -1, 8, -1 },
                    { -1, -1, -1 }
                });

                /*
                 * _experimental = new ConvolutionKernel(1, new float[,] {
                 *  { 0.00401f,   0.005895f,    0.007763f,    0.009157f,    0.009675f,    0.009157f,    0.007763f,    0.005895f,    0.00401f},
                 *  { 0.005895f,  0.008667f,    0.011412f,    0.013461f,    0.014223f,    0.013461f,    0.011412f,    0.008667f,    0.005895f},
                 *  { 0.007763f,  0.011412f,    0.015028f,    0.017726f,    0.018729f,    0.017726f,    0.015028f,    0.011412f,    0.007763f},
                 *  { 0.009157f,  0.013461f,    0.017726f,    0.020909f,    0.022092f,    0.020909f,    0.017726f,    0.013461f,    0.009157f},
                 *  { 0.009675f,  0.014223f,    0.018729f,    0.022092f,    0.023342f,    0.022092f,    0.018729f,    0.014223f,    0.009675f},
                 *  { 0.009157f,  0.013461f,    0.017726f,    0.020909f,    0.022092f,    0.020909f,    0.017726f,    0.013461f,    0.009157f},
                 *  { 0.007763f,  0.011412f,    0.015028f,    0.017726f,    0.018729f,    0.017726f,    0.015028f,    0.011412f,    0.007763f},
                 *  { 0.005895f,  0.008667f,    0.011412f,    0.013461f,    0.014223f,    0.013461f,    0.011412f,    0.008667f,    0.005895f},
                 *  { 0.00401f,   0.005895f,    0.007763f,    0.009157f,    0.009675f,    0.009157f,    0.007763f,    0.005895f,    0.00401f}
                 * });
                 *
                 * _experimental2 = new ConvolutionKernel(1, new float[,] {
                 *  { 0.000518f, 0.021715f, 0.00051f},
                 *  { 0.021715f, 0.91107f , 0.021715f},
                 *  { 0.000518f, 0.021715f, 0.000518f }
                 * });
                 */
            }
Exemplo n.º 14
0
		/// <summary>
		///
		/// </summary>
		/// <param name="x"></param>
		/// <param name="bw"></param>
		/// <param name="bwSel"></param>
		/// <param name="adjust"></param>
		/// <param name="kernel"></param>
		/// <param name="weights"></param>
		/// <param name="width"></param>
		/// <param name="widthSel"></param>
		/// <param name="n"></param>
		/// <param name="from"></param>
		/// <param name="to"></param>
		/// <param name="cut"></param>
		/// <remarks>Adapted from the R-project (www.r-project.org), Version 2.72, file density.R</remarks>
		public static ProbabilityDensityResult ProbabilityDensity(
			this IROVector x,
			double bw,
			string bwSel,
			double adjust,
			ConvolutionKernel kernel,
			IROVector weights,
			double width,
			string widthSel,
			int n,
			double from,
			double to,
			double cut // default: 3
			)
		{
			double wsum;
			if (null == weights)
			{
				weights = VectorMath.GetConstantVector(1.0 / x.Length, x.Length);
				wsum = 1;
			}
			else
			{
				wsum = weights.Sum();
			}

			double totMass = 1;

			int n_user = n;
			n = Math.Max(n, 512);
			if (n > 512)
				n = BinaryMath.NextPowerOfTwoGreaterOrEqualThan(n);

			if (bw.IsNaN() && !(width.IsNaN() && null == widthSel))
			{
				if (!width.IsNaN())
				{
					// S has width equal to the length of the support of the kernel
					// except for the gaussian where it is 4 * sd.
					// R has bw a multiple of the sd.
					double fac = 1;
					switch (kernel)
					{
						case ConvolutionKernel.Gaussian:
							fac = 4;
							break;

						case ConvolutionKernel.Rectangular:
							fac = 2 * Math.Sqrt(3);
							break;

						case ConvolutionKernel.Triangular:
							fac = 2 * Math.Sqrt(6);
							break;

						case ConvolutionKernel.Epanechnikov:
							fac = 2 * Math.Sqrt(5);
							break;

						case ConvolutionKernel.Biweight:
							fac = 2 * Math.Sqrt(7);
							break;

						case ConvolutionKernel.Cosine:
							fac = 2 / Math.Sqrt(1 / 3 - 2 / (Math.PI * Math.PI));
							break;

						case ConvolutionKernel.Optcosine:
							fac = 2 / Math.Sqrt(1 - 8 / (Math.PI * Math.PI));
							break;

						default:
							throw new ArgumentException("Unknown convolution kernel");
					}
					bw = width / fac;
				}
				else
				{
					bwSel = widthSel;
				}
			}

			if (null != bwSel)
			{
				if (x.Length < 2)
					throw new ArgumentException("need at least 2 points to select a bandwidth automatically");
				switch (bwSel.ToLowerInvariant())
				{
					case "nrd0":
						//nrd0 = bw.nrd0(x),
						break;

					case "nrd":
						//nrd = bw.nrd(x),
						break;

					case "ucv":
						//ucv = bw.ucv(x),
						break;

					case "bcv":
						//bcv = bw.bcv(x),
						break;

					case "sj":
						//sj = , "sj-ste" = bw.SJ(x, method="ste"),
						break;

					case "sj-dpi":
						//"sj-dpi" = bw.SJ(x, method="dpi"),
						break;

					default:
						throw new ArgumentException("Unknown bandwith selection rule: " + bwSel.ToString());
				}
			}

			if (!RMath.IsFinite(bw))
				throw new ArithmeticException("Bandwidth is not finite");

			bw = adjust * bw;

			if (!(bw > 0))
				throw new ArithmeticException("Bandwith is not positive");

			if (from.IsNaN())
				from = x.GetMinimum() - cut * bw;
			if (to.IsNaN())
				to = x.GetMaximum() + cut * bw;

			if (!RMath.IsFinite(from))
				throw new ArithmeticException("non-finite 'from'");
			if (!to.IsFinite())
				throw new ArithmeticException("non-finite 'to'");
			double lo = from - 4 * bw;
			double up = to + 4 * bw;

			var y = new DoubleVector(2 * n);
			MassDistribution(x, weights, lo, up, y, n);
			y.Multiply(totMass);

			var kords = new DoubleVector(2 * n);
			kords.FillWithLinearSequenceGivenByStartEnd(0, 2 * (up - lo));

			for (int i = n + 1, j = n - 1; j >= 0; i++, j--)
				kords[i] = -kords[j];

			switch (kernel)
			{
				case ConvolutionKernel.Gaussian:
					kords.Apply(new Probability.NormalDistribution(0, bw).PDF);
					break;

				case ConvolutionKernel.Rectangular:
					double a = bw * Math.Sqrt(3);
					kords.Apply(delegate(double xx) { return Math.Abs(xx) < a ? 0.5 / a : 0; });
					break;

				case ConvolutionKernel.Triangular:
					a = bw * Math.Sqrt(6);
					kords.Apply(delegate(double xx) { return Math.Abs(xx) < a ? (1 - Math.Abs(xx) / a) / a : 0; });
					break;

				case ConvolutionKernel.Epanechnikov:
					a = bw * Math.Sqrt(5);
					kords.Apply(delegate(double xx) { return Math.Abs(xx) < a ? 0.75 * (1 - RMath.Pow2(Math.Abs(xx) / a)) / a : 0; });
					break;

				case ConvolutionKernel.Biweight:
					a = bw * Math.Sqrt(7);
					kords.Apply(delegate(double xx) { return Math.Abs(xx) < a ? 15.0 / 16.0 * RMath.Pow2(1 - RMath.Pow2(Math.Abs(xx) / a)) / a : 0; });
					break;

				case ConvolutionKernel.Cosine:
					a = bw / Math.Sqrt(1.0 / 3 - 2 / RMath.Pow2(Math.PI));
					kords.Apply(delegate(double xx) { return Math.Abs(xx) < a ? (1 + Math.Cos(Math.PI * xx / a)) / (2 * a) : 0; });
					break;

				case ConvolutionKernel.Optcosine:
					a = bw / Math.Sqrt(1 - 8 / RMath.Pow2(Math.PI));
					kords.Apply(delegate(double xx) { return Math.Abs(xx) < a ? Math.PI / 4 * Math.Cos(Math.PI * xx / (2 * a)) / a : 0; });
					break;

				default:
					throw new ArgumentException("Unknown convolution kernel");
			}

			var result = new DoubleVector(2 * n);
			Fourier.FastHartleyTransform.CyclicRealConvolution(y.GetInternalData(), kords.GetInternalData(), result.GetInternalData(), 2 * n, null);
			y.Multiply(1.0 / (2 * n));
			VectorMath.Max(y, 0, y);
			var xords = VectorMath.CreateEquidistantSequenceByStartEndLength(lo, up, n);
			var xu = VectorMath.CreateEquidistantSequenceByStartEndLength(from, to, n_user);

			double[] res2 = new double[xu.Length];
			Interpolation.LinearInterpolation.Interpolate(xords, result, n, xu, xu.Length, 0, out res2);

			return new ProbabilityDensityResult() { X = xu, Y = VectorMath.ToROVector(res2), Bandwidth = bw };
		}
Exemplo n.º 15
0
        public static unsafe void ApplyConvolution(ImageChannel <TPixel> img, ConvolutionKernel k)
        {
            if (img.Width < 2 || img.Height < 2)
            {
                return;
            }

            int widthTypeScaled = img.Width * img.Step;

            int kernelHeight = k.Width;
            int kernelWidth  = k.Height;
            int scale        = k.Scale;

            int[,] kernel = k.Kernel;
            int extend = Math.Max(kernelWidth, kernelHeight) / 2;
            ImageChannel <TPixel> maskImage = new ImageChannel <TPixel>(img.Width + extend * 2, img.Height + extend * 2);

            FillImage(maskImage, (TPixel)0); //这里效率不高。原本只需要填充四周扩大的部分即可
            CopyChannel(img, maskImage, new System.Drawing.Point(0, 0), new System.Drawing.Rectangle(0, 0, img.Width, img.Height), new System.Drawing.Point(extend, extend));

            int step     = img.Step;
            int maskStep = maskImage.Step;

            int     width     = img.Width;
            int     height    = img.Height;
            TPixel *start     = (TPixel *)img.StartIntPtr;
            TPixel *maskStart = (TPixel *)maskImage.StartIntPtr;

            // 复制边界像素
            TPixel *dstStart        = maskStart + extend;
            int     maskWidth       = img.Width + extend * 2;
            int     maskHeight      = img.Height + extend * 2;
            TPixel *dstContentStart = maskStart + extend + maskWidth * extend;

            // 复制上方的像素
            for (int y = 0; y < extend; y++)
            {
                TPixel *lineStart = dstStart + y * maskWidth;
                TPixel *lineEnd   = lineStart + width;
                TPixel *copyStart = dstContentStart;
                while (lineStart != lineEnd)
                {
                    *lineStart = *copyStart;
                    lineStart++;
                    copyStart++;
                }
            }

            // 复制下方的像素
            for (int y = height + extend; y < maskHeight; y++)
            {
                TPixel *lineStart = dstStart + y * maskWidth;
                TPixel *lineEnd   = lineStart + width;
                TPixel *copyStart = dstContentStart + height * maskWidth - maskWidth;
                while (lineStart != lineEnd)
                {
                    *lineStart = *copyStart;
                    lineStart++;
                    copyStart++;
                }
            }

            // 复制左右两侧的像素
            TPixel *dstLine = maskStart + maskWidth * extend;
            TPixel  p       = default(TPixel);

            for (int y = extend; y < height + extend; y++)
            {
                p = dstLine[extend];
                for (int x = 0; x < extend; x++)
                {
                    dstLine[x] = p;
                }

                p = dstLine[extend + width - 1];
                for (int x = width + extend; x < maskWidth; x++)
                {
                    dstLine[x] = p;
                }
                dstLine += maskWidth;
            }

            // 复制四个角落的像素

            // 左上
            p = dstContentStart[0];
            for (int y = 0; y < extend; y++)
            {
                for (int x = 0; x < extend; x++)
                {
                    maskStart[y * maskWidth + x] = p;
                }
            }

            // 右上
            p = dstContentStart[width - 1];
            for (int y = 0; y < extend; y++)
            {
                for (int x = width + extend; x < maskWidth; x++)
                {
                    maskStart[y * maskWidth + x] = p;
                }
            }

            // 左下
            p = dstContentStart[(height - 1) * maskWidth];
            for (int y = height + extend; y < maskHeight; y++)
            {
                for (int x = 0; x < extend; x++)
                {
                    maskStart[y * maskWidth + x] = p;
                }
            }

            // 右下
            p = dstContentStart[(height - 1) * maskWidth + width - 1];
            for (int y = height + extend; y < maskHeight; y++)
            {
                for (int x = width + extend; x < maskWidth; x++)
                {
                    maskStart[y * maskWidth + x] = p;
                }
            }

            if (scale == 1)
            {
                for (int h = 0; h < height; h++)
                {
                    for (int w = 0; w < width; w++)
                    {
                        TValue val = 0;
                        for (int kw = 0; kw < kernelWidth; kw++)
                        {
                            for (int kh = 0; kh < kernelHeight; kh++)
                            {
                                val += maskStart[(h + kh) * maskWidth + (w + kw)] * kernel[kh, kw];
                            }
                        }
                        start[h * widthTypeScaled + w] = (TPixel)val;
                    }
                }
            }
            else
            {
                double factor = 1.0 / scale;
                for (int h = 0; h < height; h++)
                {
                    for (int w = 0; w < width; w++)
                    {
                        TValue val = 0;
                        for (int kw = 0; kw < kernelWidth; kw++)
                        {
                            for (int kh = 0; kh < kernelHeight; kh++)
                            {
                                val += maskStart[(h + kh) * maskWidth + (w + kw)] * kernel[kh, kw];
                            }
                        }
                        start[h * widthTypeScaled + w] = (TPixel)(val * factor);
                    }
                }
            }
            maskImage.Dispose();
        }
Exemplo n.º 16
0
 public ConvolutionProcessor(GraphicsInterface gi, int width, int height, ConvolutionKernel whichKernel)
     :base(gi, width, height, Convolution_Frag)
 {
     curker = (int)whichKernel;
 }
Exemplo n.º 17
0
        public unsafe void ApplyConvolution(ConvolutionKernel k)
        {
            int kernelHeight = k.Width;
            int kernelWidth  = k.Height;
            int scale        = k.Scale;

            int[,] kernel = k.Kernel;
            int    extend    = Math.Max(kernelWidth, kernelHeight) / 2;
            TImage maskImage = new TImage(Width + extend * 2, Height + extend * 2);

            maskImage.Fill(0);//这里效率不高。原本只需要填充四周扩大的部分即可

            maskImage.Copy(this, new System.Drawing.Point(0, 0), new System.Drawing.Rectangle(0, 0, this.Width, this.Height), new System.Drawing.Point(extend, extend));

            int     width  = this.Width;
            int     height = this.Height;
            TPixel *start  = (TPixel *)this.StartIntPtr;

            // 复制边界像素
            TPixel *dstStart     = maskImage.Start + extend;
            int     extendWidth  = this.Width + extend * 2;
            int     extendHeight = this.Height + extend * 2;

            // 复制上方的像素
            for (int y = 0; y < extend; y++)
            {
                TPixel *dstP     = dstStart + y * extendWidth;
                TPixel *srcStart = start;
                TPixel *srcEnd   = srcStart + width;

                while (srcStart != srcEnd)
                {
                    *dstP = *srcStart;
                    srcStart++;
                    dstP++;
                }
            }

            // 复制下方的像素
            for (int y = height + extend; y < extendHeight; y++)
            {
                TPixel *dstP     = dstStart + y * extendWidth;
                TPixel *srcStart = start + (height - 1) * width;
                TPixel *srcEnd   = srcStart + width;

                while (srcStart != srcEnd)
                {
                    *dstP = *srcStart;
                    srcStart++;
                    dstP++;
                }
            }

            // 复制左右两侧的像素
            TPixel *dstLine = maskImage.Start + extendWidth * extend;
            TPixel *srcLine = start;
            TPixel  p       = default(TPixel);

            for (int y = extend; y < height + extend; y++)
            {
                for (int x = 0; x < extend; x++)
                {
                    p          = srcLine[0];
                    dstLine[x] = p;
                }

                p = srcLine[width - 1];
                for (int x = width + extend; x < extendWidth; x++)
                {
                    dstLine[x] = p;
                }
                dstLine += extendWidth;
                srcLine += width;
            }

            // 复制四个角落的像素

            // 左上
            p = start[0];
            for (int y = 0; y < extend; y++)
            {
                for (int x = 0; x < extend; x++)
                {
                    maskImage[y, x] = p;
                }
            }

            // 右上
            p = start[width - 1];
            for (int y = 0; y < extend; y++)
            {
                for (int x = width + extend; x < extendWidth; x++)
                {
                    maskImage[y, x] = p;
                }
            }

            // 左下
            p = start[(height - 1) * width];
            for (int y = height + extend; y < extendHeight; y++)
            {
                for (int x = 0; x < extend; x++)
                {
                    maskImage[y, x] = p;
                }
            }

            // 右下
            p = start[height * width - 1];
            for (int y = height + extend; y < extendHeight; y++)
            {
                for (int x = width + extend; x < extendWidth; x++)
                {
                    maskImage[y, x] = p;
                }
            }

            if (scale == 1)
            {
                for (int h = 0; h < height; h++)
                {
                    for (int w = 0; w < width; w++)
                    {
                        int val = 0;
                        for (int kw = 0; kw < kernelWidth; kw++)
                        {
                            for (int kh = 0; kh < kernelHeight; kh++)
                            {
                                val += maskImage[h + kh, w + kw] * kernel[kh, kw];
                            }
                        }
                        start[h * width + w] = (TPixel)val;
                    }
                }
            }
            else
            {
                double factor = 1.0 / scale;
                for (int h = 0; h < height; h++)
                {
                    for (int w = 0; w < width; w++)
                    {
                        int val = 0;
                        for (int kw = 0; kw < kernelWidth; kw++)
                        {
                            for (int kh = 0; kh < kernelHeight; kh++)
                            {
                                val += maskImage[h + kh, w + kw] * kernel[kh, kw];
                            }
                        }
                        start[h * width + w] = (TPixel)(val * factor);
                    }
                }
            }
            maskImage.Dispose();
        }