Beispiel #1
0
        //forgive for such implementation. Slow and ugly...
        private static double[,] Conv2Process(double[,] inArray, double[,] convArray, Convback convback)
        {
            ArrGen <double> d = new ArrGen <double>();

            double[,] result = new double[inArray.GetLength(0) + convArray.GetLength(0) - 1, inArray.GetLength(1) + convArray.GetLength(1) - 1];

            List <double> tempResults = new List <double>();

            double[] tempResult = new double[result.GetLength(0)];

            List <VectorsListDouble> aRListIn  = new List <VectorsListDouble>();
            List <VectorsListDouble> aRListOut = new List <VectorsListDouble>();
            List <VectorsListDouble> temp      = new List <VectorsListDouble>();
            List <VectorsListDouble> tempRes   = new List <VectorsListDouble>();

            int sameRow = convArray.GetLength(0); int sameRowPart = inArray.GetLength(0);
            int sameCol = convArray.GetLength(1); int sameColPart = inArray.GetLength(1);

            //lazy cheat
            if (inArray.GetLength(1) < convArray.GetLength(1))
            {
                var tempIn = inArray;
                inArray   = new double[convArray.GetLength(0), convArray.GetLength(1)];
                inArray   = convArray;
                convArray = new double[inArray.GetLength(0), inArray.GetLength(1)];
                convArray = tempIn;
            }

            var arrayCols = d.ReturnListof2DArrayCols(inArray);
            var convCols  = d.ReturnListof2DArrayCols(convArray);

            //conv col by col
            for (int i = 0; i < convArray.GetLength(1); i++)
            {
                for (int j = 0; j < inArray.GetLength(1); j++)
                {
                    tempResult = Convolution.Conv(arrayCols[j].Vect, convCols[i].Vect, Convback.full);
                    aRListIn.Add(new VectorsListDouble()
                    {
                        Vect = tempResult
                    });
                }
            }

            if (convArray.GetLength(1) == 1)
            {
                aRListOut = aRListIn;
            }
            else
            {
                var first = aRListIn[0].Vect;
                var last  = aRListIn[aRListIn.Count - 1].Vect;
                aRListOut.Add(new VectorsListDouble()
                {
                    Vect = first
                });

                aRListIn.RemoveAt(0); aRListIn.RemoveAt(aRListIn.Count - 1);

                int maxAmount      = convArray.GetLength(1);  //максимальное число суммируемых стобцов в один //max number of cols to one sum
                int maxSumCount    = 0;                       //количество maxAmount  //count maxAmount
                int simpleSumCount = 0;                       //количество остальных сумм //count another sums
                int sumCount       = result.GetLength(1) - 2; //кроличество всех сумм //count all sums
                int step           = 0;                       //шаг через который суммируются //sum step

                if (convArray.GetLength(1) == 2)
                {
                    simpleSumCount = inArray.GetLength(1) - 1;
                    step           = inArray.GetLength(1) - 1;

                    for (int i = 0; i < sumCount; i++)
                    {
                        aRListOut.Add(new VectorsListDouble()
                        {
                            Vect = aRListIn[i].Vect.SumVectors(aRListIn[i + step].Vect)
                        });
                    }
                }
                else
                {
                    step           = inArray.GetLength(1) - 2 + 1;
                    maxSumCount    = Math.Abs(inArray.GetLength(1) - convArray.GetLength(1)) + 1;
                    simpleSumCount = result.GetLength(1) - maxSumCount - 2;

                    tempResult = new double[result.GetLength(0)];
                    for (int i = 0; i < simpleSumCount / 2; i++)
                    {
                        int baka = i + 1;
                        int c    = 0;
                        for (int j = 0; j <= baka; j++)
                        {
                            temp.Add(new VectorsListDouble()
                            {
                                Vect = aRListIn[i + c].Vect
                            });
                            c = c + step;
                        }

                        for (int k = 0; k < temp.Count; k++)
                        {
                            tempResult = tempResult.SumVectors(temp[k].Vect);
                        }
                        aRListOut.Add(new VectorsListDouble()
                        {
                            Vect = tempResult
                        });

                        temp = new List <VectorsListDouble>(); tempResult = new double[result.GetLength(0)];
                    }

                    for (int i = 0; i < maxSumCount; i++)
                    {
                        int maxstep       = 0;
                        int maxFirstIndex = simpleSumCount / 2;
                        for (int j = 0; j < maxAmount; j++)
                        {
                            temp.Add(new VectorsListDouble()
                            {
                                Vect = aRListIn[i + maxFirstIndex + maxstep].Vect
                            });
                            maxstep = maxstep + step;
                        }

                        for (int k = 0; k < temp.Count; k++)
                        {
                            tempResult = tempResult.SumVectors(temp[k].Vect);
                        }
                        aRListOut.Add(new VectorsListDouble()
                        {
                            Vect = tempResult
                        });

                        temp = new List <VectorsListDouble>(); tempResult = new double[result.GetLength(0)];
                    }

                    for (int i = 0; i < simpleSumCount / 2; i++)
                    {
                        int baka = i + 1;
                        int c    = 0;
                        int kap  = aRListIn.Count - 1;
                        for (int j = 0; j <= baka; j++)
                        {
                            temp.Add(new VectorsListDouble()
                            {
                                Vect = aRListIn[kap - i - c].Vect
                            });
                            c = c + step;
                        }

                        for (int k = 0; k < temp.Count; k++)
                        {
                            tempResult = tempResult.SumVectors(temp[k].Vect);
                        }

                        tempRes.Add(new VectorsListDouble()
                        {
                            Vect = tempResult
                        });

                        temp = new List <VectorsListDouble>(); tempResult = new double[result.GetLength(0)];
                    }

                    for (int i = tempRes.Count - 1; i >= 0; i--)
                    {
                        aRListOut.Add(new VectorsListDouble()
                        {
                            Vect = tempRes[i].Vect
                        });
                    }
                }
                aRListOut.Add(new VectorsListDouble()
                {
                    Vect = last
                });
            }

            for (int i = 0; i < aRListOut.Count; i++)
            {
                var getCol = aRListOut[i].Vect;
                tempResults.AddRange(getCol);
            }

            var convResult = d.VecorToArrayColbyCol(result.GetLength(0), result.GetLength(1), tempResults.ToArray());

            result = convResult;

            if (convback == Convback.same)
            {
                int indexCols = 0;
                int indexRows = 0;

                if (sameCol % 2 != 0)
                {
                    indexCols = (sameCol - 1) / 2;
                }
                else
                {
                    indexCols = sameCol / 2;
                }

                if (sameRow % 2 != 0)
                {
                    indexRows = (sameRow - 1) / 2;
                }
                else
                {
                    indexRows = sameRow / 2;
                }

                tempResults = new List <double>();
                var RowsCut = d.ArrayToVectorColByCol(convResult).ToList();
                for (int i = 0; i < convResult.GetLength(1); i++)
                {
                    int index  = convResult.GetLength(0) * i + indexRows;
                    var rowPal = RowsCut.GetRange(index, sameRowPart);
                    tempResults.AddRange(rowPal);
                }

                var sameRows = d.VecorToArrayColbyCol(sameRowPart, convResult.GetLength(1), tempResults.ToArray());

                tempResults = new List <double>();
                var ColsCut = sameRows.Cast <double>().ToList();
                for (int i = 0; i < sameRowPart; i++)
                {
                    int index  = convResult.GetLength(1) * i + indexCols;
                    var colPal = ColsCut.GetRange(index, sameColPart);
                    tempResults.AddRange(colPal);
                }

                result = new double[sameRowPart, sameColPart];
                result = d.VecorToArrayRowByRow(sameRowPart, sameColPart, tempResults.ToArray());
            }

            result.DecimalCorrection();
            return(result);
        }
Beispiel #2
0
        private static double[,] Conv2Process(double[,] inArray, double[] hrow, double[] hcol, Convback convback)
        {
            ArrGen <double> d = new ArrGen <double>();

            double[,] result = new double[inArray.GetLength(0) + hrow.Length - 1, inArray.GetLength(1) + hcol.Length - 1];

            List <double> tempColList = new List <double>();
            List <double> tempRowList = new List <double>();
            List <double> tempResults = new List <double>();

            var arrayCols = d.ReturnListof2DArrayCols(inArray);

            //first convolves columns with col vector
            for (int i = 0; i < inArray.GetLength(1); i++)
            {
                tempResults = Convolution.Conv(arrayCols[i].Vect, hrow, Convback.full).ToList();
                tempColList.AddRange(tempResults);
            }

            var colsResult = d.VecorToArrayColbyCol(result.GetLength(0), inArray.GetLength(1), tempColList.ToArray());
            var arrayRows  = d.ReturnListof2DArrayRows(colsResult);

            //convolves rows of the result with row vector
            for (int i = 0; i < colsResult.GetLength(0); i++)
            {
                tempResults = Convolution.Conv(arrayRows[i].Vect, hcol, Convback.full).ToList();
                tempRowList.AddRange(tempResults);
            }

            var convResult = d.VecorToArrayRowByRow(result.GetLength(0), result.GetLength(1), tempRowList.ToArray());

            result = convResult;

            if (convback == Convback.same)
            {
                int indexCols = 0;
                int indexRows = 0;

                if (hcol.Length % 2 != 0)
                {
                    indexCols = (hcol.Length - 1) / 2;
                }
                else
                {
                    indexCols = hcol.Length / 2;
                }

                if (hrow.Length % 2 != 0)
                {
                    indexRows = (hrow.Length - 1) / 2;
                }
                else
                {
                    indexRows = hrow.Length / 2;
                }

                tempResults = new List <double>();
                var RowsCut = d.ArrayToVectorColByCol(convResult).ToList();
                for (int i = 0; i < convResult.GetLength(1); i++)
                {
                    int index  = convResult.GetLength(0) * i + indexRows;
                    var rowPal = RowsCut.GetRange(index, inArray.GetLength(0));
                    tempResults.AddRange(rowPal);
                }

                var sameRows = d.VecorToArrayColbyCol(inArray.GetLength(0), convResult.GetLength(1), tempResults.ToArray());

                tempResults = new List <double>();
                var ColsCut = sameRows.Cast <double>().ToList();
                for (int i = 0; i < inArray.GetLength(0); i++)
                {
                    int index  = convResult.GetLength(1) * i + indexCols;
                    var colPal = ColsCut.GetRange(index, inArray.GetLength(1));
                    tempResults.AddRange(colPal);
                }

                result = new double[inArray.GetLength(0), inArray.GetLength(1)];
                result = d.VecorToArrayRowByRow(inArray.GetLength(0), inArray.GetLength(1), tempResults.ToArray());
            }

            result.DecimalCorrection();
            return(result);
        }
Beispiel #3
0
        //linear motion of a camera by Len pixels
        //with an angle of Theta degrees
        //realization at the level "Bratiwka, ya tebe pokywat prines"
        private static double[,] MotionProcess(uint len, double theta)
        {
            double[,] result = new double[1, 1];
            ArrGen <double> d = new ArrGen <double>();

            if (len > 1)
            {
                //Floating-point relative accuracy
                double eps = 2.2204 * Math.Pow(10, -16);

                //rotate half length around center
                var half = ((double)len - 1) / 2;
                var phi  = (theta % 180) / 180 * Math.PI;

                var cosPhi = Math.Cos(phi);
                var sinPhi = Math.Sin(phi);
                var xsign  = Math.Sign(cosPhi);
                if (xsign == 0 || xsign == -1)
                {
                    Console.WriteLine("Something wrong with input parameters. Return empty."); return(result);
                }
                double linewdt = 1;

                //define mesh for the half matrix, eps takes care of the right size for 0 & 90 rotation
                var sx = half * cosPhi + linewdt * xsign - len * eps;
                if (sx > 0)
                {
                    sx = Math.Floor(sx);
                }
                else
                {
                    sx = -(Math.Floor(-sx));
                }

                var sy = half * sinPhi + linewdt - len * eps;
                if (sy > 0)
                {
                    sy = Math.Floor(sy);
                }
                else
                {
                    sy = -(Math.Floor(-sy));
                }

                double[,] x = new double[(int)sy + 1, (int)sx + 1];
                double[,] y = new double[(int)sy + 1, (int)sx + 1];

                for (int i = 0; i <= sy; i++)
                {
                    for (int j = 0; j <= sx; j++)
                    {
                        x[i, j] = j;
                        y[i, j] = i;
                    }
                }

                //define shortest distance from a pixel to the rotated line
                var dist2line = y.ArrayMultByConst(cosPhi).SubArrays(x.ArrayMultByConst(sinPhi));
                var rad       = x.PowArrayElements(2).SumArrays(y.PowArrayElements(2)).SqrtArrayElements();

                //find points beyond the line's end-point but within the line width
                var tempGreater = rad.MarkGreaterEqual(half, BabaYaga.logic);
                var tempLess    = dist2line.AbsArrayElements().MarkLessEqual(linewdt, BabaYaga.logic);
                tempGreater = tempGreater.ArrayMultElements(tempLess);

                List <int> lastpix = new List <int>();

                var lastPixVector = d.ArrayToVectorColByCol(tempGreater);
                for (int i = 0; i < lastPixVector.Count(); i++)
                {
                    if (lastPixVector[i] != 0)
                    {
                        lastpix.Add(i);
                    }
                }

                //distance to the line's end-point parallel to the line
                //transform into vectors, for more convenient process (for me naturally :D)
                var xVector         = d.ArrayToVectorColByCol(x);
                var dist2lineVector = d.ArrayToVectorColByCol(dist2line);

                List <double> x2lastpix = new List <double>();
                for (int i = 0; i < lastpix.Count; i++)
                {
                    x2lastpix.Add(half - Math.Abs((xVector[lastpix[i]] + dist2lineVector[lastpix[i]] * sinPhi) / cosPhi));
                    dist2lineVector[lastpix[i]] = Math.Sqrt(Math.Pow(dist2lineVector[lastpix[i]], 2) + Math.Pow(x2lastpix[i], 2));
                }

                for (int i = 0; i < dist2lineVector.Length; i++)
                {
                    dist2lineVector[i] = linewdt + eps - Math.Abs(dist2lineVector[i]);
                    if (dist2lineVector[i] < 0)
                    {
                        dist2lineVector[i] = 0;                         //zero out anything beyond line width
                    }
                }

                //back to 2D
                dist2line = d.VecorToArrayColbyCol(dist2line.GetLength(0), dist2line.GetLength(1), dist2lineVector);

                //unfold half - matrix to the full size
                result = new double[dist2line.GetLength(0) * 2 - 1, dist2line.GetLength(1) * 2 - 1];
                var temp    = Rotate90.RotateArray90(dist2line, 2);
                var reverse = d.VecorToArrayRowByRow(temp.GetLength(0), temp.GetLength(1), temp.Cast <double>().Reverse().ToArray());

                for (int i = 0; i < temp.GetLength(0); i++)
                {
                    for (int j = 0; j < temp.GetLength(1); j++)
                    {
                        result[i, j] = temp[i, j];
                    }
                }

                for (int i = 0; i < reverse.GetLength(0); i++)
                {
                    for (int j = 0; j < reverse.GetLength(1); j++)
                    {
                        result[i + reverse.GetLength(0) - 1, j + reverse.GetLength(1) - 1] = reverse[i, j];
                    }
                }

                result = result.ArrayDivByConst(result.Cast <double>().Sum() + eps * len * len);

                if (cosPhi > 0)
                {
                    result = d.FlipArray(result);
                }
            }
            else
            {
                Console.WriteLine("Len must be positive integer value, greater than 1. Method: FSpecial.Motion(). Return black rectangle.");
            }

            return(result);
        }