示例#1
0
        //circular averaging filter
        //within the square matrix of side 2*radius+1
        //realization at the level "Bratiwka, ya tebe pokywat prines"
        private static double[,] DiskProcess(double radius)
        {
            double[,] result = new double[1, 1];
            ArrGen <double> d = new ArrGen <double>();

            if (radius > 0)
            {
                var crad = Math.Ceiling(radius - 0.5);
                int rc   = 0;
                for (int i = (int)(-crad); i <= crad; i++)
                {
                    rc++;
                }

                double[,] x = new double[rc, rc];
                double[,] y = new double[rc, rc];

                var trap = -crad;
                for (int i = 0; i < rc; i++)
                {
                    for (int j = 0; j < rc; j++)
                    {
                        x[i, j] = trap + j;
                        y[i, j] = trap + i;
                    }
                }

                var maxxy = x.AbsArrayElements().MaxTwoArrays(y.AbsArrayElements());
                var minxy = x.AbsArrayElements().MinTwoArrays(y.AbsArrayElements());

                var maxxyVector = maxxy.Cast <double>().ToArray();
                var minxyVector = minxy.Cast <double>().ToArray();

                //temp vectors and variables
                double[] temp1 = new double[rc * rc];
                double[] temp2 = new double[rc * rc];
                double   temp  = 0;
                Complex  tempComplex;

                //m1 count by partial
                double[] m1tempCusum = new double[rc * rc];

                for (int i = 0; i < m1tempCusum.Length; i++)
                {
                    //a = (rad^2 < (maxxy+0.5).^2 + (minxy-0.5).^2).*(minxy-0.5)
                    if (Math.Pow(radius, 2) < (Math.Pow(maxxyVector[i] + 0.5, 2) + Math.Pow(minxyVector[i] - 0.5, 2)))
                    {
                        temp = 1;
                    }
                    temp1[i] = temp * (minxyVector[i] - 0.5); temp = 0;

                    // b =(rad^2 >= (maxxy+0.5).^2 + (minxy-0.5).^2).* sqrt(rad ^ 2 - (maxxy + 0.5).^ 2)
                    if (Math.Pow(radius, 2) >= (Math.Pow(maxxyVector[i] + 0.5, 2) + Math.Pow(minxyVector[i] - 0.5, 2)))
                    {
                        temp = 1;
                    }
                    tempComplex = Complex.Sqrt(Math.Pow(radius, 2) - Math.Pow(maxxyVector[i] + 0.5, 2));
                    temp2[i]    = temp * (tempComplex.Real + tempComplex.Imaginary); temp = 0;
                }
                //a + b
                m1tempCusum = temp1.SumVectors(temp2);
                var m1 = d.VecorToArrayRowByRow(rc, rc, m1tempCusum);

                temp1 = new double[rc * rc]; temp2 = new double[rc * rc];
                //m2 count by partial
                double[] m2tempCusum = new double[rc * rc];

                for (int i = 0; i < m2tempCusum.Length; i++)
                {
                    //a = (rad^2 > (maxxy-0.5).^2 + (minxy+0.5).^2).*(minxy+0.5)
                    if (Math.Pow(radius, 2) > (Math.Pow(maxxyVector[i] - 0.5, 2) + Math.Pow(minxyVector[i] + 0.5, 2)))
                    {
                        temp = 1;
                    }
                    temp1[i] = temp * (minxyVector[i] + 0.5); temp = 0;

                    // b = (rad^2 <= (maxxy-0.5).^2 + (minxy+0.5).^2).* sqrt(rad ^ 2 - (maxxy - 0.5).^ 2)
                    if (Math.Pow(radius, 2) <= (Math.Pow(maxxyVector[i] - 0.5, 2) + Math.Pow(minxyVector[i] + 0.5, 2)))
                    {
                        temp = 1;
                    }
                    temp2[i] = temp * Math.Sqrt(Math.Pow(radius, 2) - Math.Pow(maxxyVector[i] - 0.5, 2)); temp = 0;
                }
                //a + b
                m2tempCusum = temp1.SumVectors(temp2);
                var m2 = d.VecorToArrayRowByRow(rc, rc, m2tempCusum);

                temp1 = new double[rc * rc]; temp2 = new double[rc * rc];
                //sgrid count by partial
                double[] sgridVector = new double[rc * rc];

                for (int i = 0; i < sgridVector.Length; i++)
                {
                    //rad^2*(0.5*(asin(m2/rad) - asin(m1/rad)) + 0.25 * (sin(2 * asin(m2 / rad)) - sin(2 * asin(m1 / rad)))) - (maxxy - 0.5).* (m2 - m1) + (m1 - minxy + 0.5)
                    temp1[i] = Math.Pow(radius, 2) * (0.5 * (Math.Asin(m2tempCusum[i] / radius) - Math.Asin(m1tempCusum[i] / radius)) +
                                                      0.25 * (Math.Sin(2 * Math.Asin(m2tempCusum[i] / radius)) - Math.Sin(2 * Math.Asin(m1tempCusum[i] / radius)))) -
                               (maxxyVector[i] - 0.5) * (m2tempCusum[i] - m1tempCusum[i]) +
                               (m1tempCusum[i] - minxyVector[i] + 0.5);

                    // ((rad^2 < (maxxy+0.5).^2 + (minxy+0.5).^2) & (rad ^ 2 > (maxxy - 0.5).^ 2 + (minxy - 0.5).^ 2)) | ((minxy == 0) & (maxxy - 0.5 < rad) & (maxxy + 0.5 >= rad))
                    if (Math.Pow(radius, 2) < (Math.Pow(maxxyVector[i] + 0.5, 2) + Math.Pow(minxyVector[i] + 0.5, 2)))
                    {
                        temp = 1;
                    }

                    if (Math.Pow(radius, 2) > (Math.Pow(maxxyVector[i] - 0.5, 2) + Math.Pow(minxyVector[i] - 0.5, 2)) && temp == 1)
                    {
                        temp = 1;
                    }
                    else
                    {
                        temp = 0;
                    }

                    if (((minxyVector[i] == 0) && (maxxyVector[i] - 0.5 < radius) && (maxxyVector[i] + 0.5 >= radius)) || temp == 1)
                    {
                        temp = 1;
                    }
                    else
                    {
                        temp = 0;
                    }

                    temp2[i] = temp; temp = 0;
                }

                //a * b
                sgridVector = temp1.MultVectors(temp2);

                for (int i = 0; i < sgridVector.Length; i++)
                {
                    if ((Math.Pow(maxxyVector[i] + 0.5, 2) + Math.Pow(minxyVector[i] + 0.5, 2)) < Math.Pow(radius, 2))
                    {
                        temp = 1;
                    }

                    sgridVector[i] = sgridVector[i] + temp; temp = 0;
                }

                var sgrid = d.VecorToArrayRowByRow(rc, rc, sgridVector);
                sgrid[(int)crad, (int)crad] = Math.Min(Math.PI * Math.Pow(radius, 2), Math.PI / 2);

                if ((crad > 0) && (radius > (crad - 0.5)) && (Math.Pow(radius, 2) < (Math.Pow(crad - 0.5, 2) + 0.25)))
                {
                    var tempm1  = Math.Sqrt(Math.Pow(radius, 2) - Math.Pow(crad - 0.5, 2));
                    var tempm1n = tempm1 / radius;
                    var sg0     = 2 * (Math.Pow(radius, 2) * (0.5 * Math.Asin(tempm1n) +
                                                              0.25 * Math.Sin(2 * Math.Asin(tempm1n))) - tempm1 * (crad - 0.5));

                    sgrid[2 * (int)crad, (int)crad] = sg0;
                    sgrid[(int)crad, 2 * (int)crad] = sg0;
                    sgrid[(int)crad, 0]             = sg0;
                    sgrid[0, (int)crad]             = sg0;

                    sgrid[2 * (int)crad - 1, (int)crad] = sgrid[(2 * (int)crad - 1), (int)crad] - sg0;
                    sgrid[(int)crad, 2 * (int)crad - 1] = sgrid[(int)crad, 2 * (int)crad - 1] - sg0;
                    sgrid[(int)crad, 1] = sgrid[(int)crad, 1] - sg0;
                    sgrid[1, (int)crad] = sgrid[1, (int)crad] - sg0;
                }
                sgrid[(int)crad, (int)crad] = Math.Min(sgrid[(int)crad, (int)crad], 1);

                result = new double[rc, rc];
                result = d.VecorToArrayRowByRow(rc, rc, sgrid.Cast <double>().ToArray().VectorDivByConst(sgrid.Cast <double>().ToArray().Sum()));
            }
            else
            {
                Console.WriteLine("Radius must be greater 0. Method: FSpecial.Radius(). Return black point.");
            }

            return(result);
        }