public Mat Recovery(ComplexMoments decomposition)
        {
            var result = Mat.Zeros(Polynomials[0][0].Item1.Mat.SizeOfDimension[0], Polynomials[0][0].Item1.Mat.SizeOfDimension[1], DepthType.Cv64F, 1);

            for (var n = 0; n < Polynomials.Count; ++n)
            {
                for (var m = 0; m < n + 1; ++m)
                {
                    if ((n - m) % 2 == 0)
                    {
                        result += Polynomials[n][m].Item1.Mat * decomposition.Real.GetValue(n, m) - Polynomials[n][m].Item1.Mat * decomposition.Image.GetValue(n, m);
                    }
                    //Result += Polynomials[n][m].Item1.Mat * decomposition.image.GetValue(n, m) + Polynomials[n][m].Item2.Mat * decomposition.real.GetValue(n, m);
                }
            }

            return(result);
        }
        public ComplexMoments Decompose(Mat blob)
        {
            var result = new ComplexMoments
            {
                Real  = Mat.Zeros(Polynomials.Count, Polynomials.Count, DepthType.Cv64F, 1),
                Image = Mat.Zeros(Polynomials.Count, Polynomials.Count, DepthType.Cv64F, 1),
                Abs   = Mat.Zeros(Polynomials.Count, Polynomials.Count, DepthType.Cv64F, 1),
                Phase = Mat.Zeros(Polynomials.Count, Polynomials.Count, DepthType.Cv64F, 1)
            };
            var tmpBlob = new Mat();

            _ = new Point[1];
            blob.MinMax(out var min, out var max, out _, out _);
            var alpha = 255 / (max[0] - min[0]);
            var beta  = -255 * min[0] / ((max[0] - min[0]));

            blob.ConvertTo(blob, DepthType.Cv64F, alpha, beta);
            for (var n = 0; n < Polynomials.Count; ++n)
            {
                for (var m = 0; m < n + 1; ++m)
                {
                    if ((n - m) % 2 != 0)
                    {
                        continue;
                    }
                    var tmpMoment = tmpBlob.Dot(Polynomials[n][m].Item1);
                    result.Real.SetValue(n, m, Math.Abs(tmpMoment) > 1e-20 ? tmpMoment : 0);
                    tmpMoment = -tmpBlob.Dot(Polynomials[n][m].Item2);
                    result.Image.SetValue(n, m, Math.Abs(tmpMoment) > 1e-20 ? tmpMoment : 0);
                    var    tmpReal  = result.Real.GetValue(n, m);
                    var    tmpImage = result.Image.GetValue(n, m);
                    double tmp      = Math.Sqrt(tmpReal * tmpReal + tmpImage * tmpImage);
                    result.Abs.SetValue(n, m, tmp);
                    double tmpAngle = Math.Atan2(tmpImage, tmpReal);
                    result.Phase.SetValue(n, m, tmpAngle);
                }
            }

            return(result);
        }