//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); }
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); }
//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); }