Пример #1
0
        private void GenerateElasticPixels <TColor>(
            int kernelSize,
            double sigma,
            double alpha,
            Span <TColor> sourcePixels,
            Span <TColor> destPixels,
            int width,
            int height,
            Vector2[] facePointsSource,
            Vector2[] facePointsDest)
            where TColor : struct, IPixel <TColor>
        {
            //var length = width * height;
            double[] kernel        = GeometryHelpers.Create2Dgaussian(kernelSize, sigma);
            double[] displacementX = ArrayPoolManager.DoubleArrayPool.Rent(width * height).Random(-1, 1).Multiply(alpha).Convolve(width, height, kernel, kernelSize);
            double[] displacementY = ArrayPoolManager.DoubleArrayPool.Rent(width * height).Random(-1, 1).Multiply(alpha).Convolve(width, height, kernel, kernelSize);
            //double[,] displacementX = new double[width, height];
            //double[,] displacementY = new double[width, height];
            double[] distances = ArrayPoolManager.DoubleArrayPool.Rent(facePointsSource.Length);

            for (int i = 0; i < facePointsSource.Length; i++)
            {
                distances[i] = double.MaxValue;
            }
            try
            {
                //displacementX = displacementX.Random(-1, 1).Multiply(alpha).Convolve(kernel);
                //displacementY = displacementY.Random(-1, 1).Multiply(alpha).Convolve(kernel);

                Parallel.For(0, width, Bootstrapper.Instance.MaxDegreeOfParalelism, xDest =>
                {
                    for (int yDest = 0; yDest < height; yDest++)
                    {
                        var position = xDest + yDest * width;

                        double xOrg = xDest + displacementX[position];
                        double yOrg = yDest + displacementY[position];

                        SetNearest(facePointsSource, facePointsDest, distances, xOrg, yOrg);

                        int xI1 = (int)Math.Floor(xOrg);
                        int xI2 = (int)Math.Ceiling(xOrg);
                        int yI1 = (int)Math.Floor(yOrg);
                        int yI2 = (int)Math.Ceiling(yOrg);

                        int xOrgI1 = xI1.ClampDown(0).ClampUp(width - 1);
                        int xOrgI2 = xI2.ClampDown(0).ClampUp(width - 1);
                        int yOrgI1 = yI1.ClampDown(0).ClampUp(height - 1);
                        int yOrgI2 = yI2.ClampDown(0).ClampUp(height - 1);

                        TColor colorPosI1 = sourcePixels[xOrgI1 + yOrgI1 * width];
                        TColor colorPosI2 = sourcePixels[xOrgI2 + yOrgI1 * width];
                        TColor colorPosI3 = sourcePixels[xOrgI1 + yOrgI2 * width];
                        TColor colorPosI4 = sourcePixels[xOrgI2 + yOrgI2 * width];

                        var colorPosI1Vector = colorPosI1.ToVector4();
                        var colorPosI2Vector = colorPosI2.ToVector4();
                        var colorPosI3Vector = colorPosI3.ToVector4();
                        var colorPosI4Vector = colorPosI4.ToVector4();

                        var rgbVector = new Vector4();
                        rgbVector.X   = Interpolate(xOrg, yOrg, xI1, xI2, yI1, yI2, colorPosI1Vector.X, colorPosI2Vector.X,
                                                    colorPosI3Vector.X, colorPosI4Vector.X);
                        rgbVector.Y = Interpolate(xOrg, yOrg, xI1, xI2, yI1, yI2, colorPosI1Vector.Y, colorPosI2Vector.Y,
                                                  colorPosI3Vector.Y, colorPosI4Vector.Y);
                        rgbVector.Z = Interpolate(xOrg, yOrg, xI1, xI2, yI1, yI2, colorPosI1Vector.Z, colorPosI2Vector.Z,
                                                  colorPosI3Vector.Z, colorPosI4Vector.Z);
                        rgbVector.W = 255;

                        TColor newColor = new TColor();
                        newColor.PackFromVector4(rgbVector);
                        destPixels[xDest + yDest * width] = newColor;
                    }
                });
            }
            finally
            {
                ArrayPoolManager.DoubleArrayPool.Return(displacementX);
                ArrayPoolManager.DoubleArrayPool.Return(displacementY);
                ArrayPoolManager.DoubleArrayPool.Return(distances);
            }
        }