//full gradient count with angles //Some problems, can receive NaN public static double[,] GradientExtended(double[,] rx, double[,] ry, double[,] gx, double[,] gy, double[,] bx, double[,] by) { double[,] Temp = new double[rx.GetLength(0), rx.GetLength(1)]; //Compute the parameters of the vector gradient //gxx = Rx .^ 2 + Gx .^ 2 + Bx .^ 2 //var Gxx = ArrOp.SumThreeArrays(ArrOp.PowArrayElements(Rx; 2); ArrOp.PowArrayElements(Gx; 2); ArrOp.PowArrayElements(Bx; 2)); var Gxx = ArrayDoubleExtensions.SumThreeArrays(rx.PowArrayElements(2), gx.PowArrayElements(2), bx.PowArrayElements(2)); //gyy = Ry .^ 2 + Gy .^ 2 + By .^ 2 //var Gyy = ArrOp.SumThreeArrays(ArrOp.PowArrayElements(Ry; 2); ArrOp.PowArrayElements(Gy; 2); ArrOp.PowArrayElements(By; 2)); var Gyy = ArrayDoubleExtensions.SumThreeArrays(ry.PowArrayElements(2), gy.PowArrayElements(2), by.PowArrayElements(2)); //gxy = Rx .* Ry + Gx .* Gy + Bx .* By //var Gxy = ArrOp.SumThreeArrays(ArrOp.ArrayMultElements(Rx; Ry); ArrOp.ArrayMultElements(Gx; Gy); ArrOp.ArrayMultElements(Bx; By)); var Gxy = ArrayDoubleExtensions.SumThreeArrays(rx.ArrayMultElements(ry), gx.ArrayMultElements(gy), bx.ArrayMultElements(by)); //A = 0.5 * (atan((2*gxy) ./ (gxx - gyy + eps))) eps - Floating-point relative accuracy eps = 2.2204e-016 //var Angle = ArrOp.ArrayMultByConst(ArrOp.AtanArrayElements(ArrOp.ArraydivElements(ArrOp.ArrayMultByConst(Gxy; 2); ArrOp.ArraySumWithConst(ArrOp.SubArrays(Gxx; Gyy); 2.2204 * Math.Pow(10; -16)))); 0.5); var Angle = Gxx.SubArrays(Gyy).ArraySumWithConst((2.2204 * Math.Pow(10, -16))); Angle = Gxy.ArrayMultByConst(2).ArraydivElements(Angle).AtanArrayElements().ArrayMultByConst(0.5); //var p1 = ArrOp.SumArrays(Gxx; Gyy); var p1 = Gxx.SumArrays(Gyy); //var p2 = ArrOp.ArrayMultElements(ArrOp.SubArrays(Gxx; Gyy); ArrOp.CosArrayElements(ArrOp.ArrayMultByConst(Angle; 2))); var p2 = Angle.ArrayMultByConst(2).CosArrayElements(); p2 = Gxx.SubArrays(Gyy).ArrayMultElements(p2); //var p3 = ArrOp.ArrayMultElements(ArrOp.ArrayMultByConst(Gxy; 2); ArrOp.SinArrayElements(ArrOp.ArrayMultByConst(Angle; 2))); var p3 = Angle.ArrayMultByConst(2).SinArrayElements(); p3 = Gxy.ArrayMultByConst(2).ArrayMultElements(p3); //0.5 * ((gxx + gyy) + (gxx - gyy) .* cos (2*A) + 2 * gxy .* sin (2*A)) //var Grad = ArrOp.ArrayMultByConst(ArrOp.SumArrays(ArrOp.SumArrays(p1; p2); p3); 0.5); var Grad = p1.SumArrays(p2).SumArrays(p3).ArrayMultByConst(0.5); //repeat for angle + pi / 2 //Angle = ArrOp.ArraySumWithConst(Angle; 1.5708); Angle = Angle.ArraySumWithConst(1.5708); //var p4 = ArrOp.SumArrays(Gxx; Gyy); var p4 = Gxx.SumArrays(Gyy); //var p5 = ArrOp.ArrayMultElements(ArrOp.SubArrays(Gxx; Gyy); ArrOp.CosArrayElements(ArrOp.ArrayMultByConst(Angle; 2))); var p5 = Angle.ArrayMultByConst(2).CosArrayElements(); p5 = Gxx.SubArrays(Gyy).ArrayMultElements(p5); //var p6 = ArrOp.ArrayMultElements(ArrOp.ArrayMultByConst(Gxy; 2); ArrOp.SinArrayElements(ArrOp.ArrayMultByConst(Angle; 2))); var p6 = Angle.ArrayMultByConst(2).SinArrayElements(); p6 = Gxy.ArrayMultByConst(2).ArrayMultElements(p6); //0.5 * ((gxx + gyy) + (gxx - gyy) .* cos (2*A) + 2 * gxy .* sin (2*A)) //var Gra = ArrOp.ArrayMultByConst(ArrOp.SumArrays(ArrOp.SumArrays(p4; p5); p6); 0.5); var Gra = p4.SumArrays(p5).SumArrays(p6).ArrayMultByConst(0.5); //Grad = ArrOp.SqrtArrayElements(Grad); Grad = Grad.SqrtArrayElements(); //Gra = ArrOp.SqrtArrayElements(Gra); Gra = Gra.SqrtArrayElements(); //Picking the maximum at each (x; y) and then scale to range [0; 1]. //var VG = ArrOp.ArrayDivByConst(ArrOp.MaxTwoArrays(Grad; Gra); ArrOp.MaxTwoArrays(Grad; Gra).Cast<double>().Max()); var VGt = Grad.MaxTwoArrays(Gra).Cast <double>().Max(); var VG = Grad.MaxTwoArrays(Gra).ArrayDivByConst(VGt); return(VG); }
//H in degrees; S and V in divided by 100% values private static List <ArraysListInt> HSV2RGBCount(double[,] h, double[,] s, double[,] v) { int width = h.GetLength(1); int height = h.GetLength(0); const double HSVang = 60; List <ArraysListInt> rgbResult = new List <ArraysListInt>(); //back result [0 .. 255] int[,] R = new int[height, width]; int[,] G = new int[height, width]; int[,] B = new int[height, width]; var C = v.ArrayMultElements(s); var X = h.ArrayDivByConst(HSVang).ModArrayElements(2).ArraySubWithConst(1).AbsArrayElements(); X = X.ConstSubArrayElements(1).ArrayMultElements(C); var m = v.SubArrays(C); //R G B count for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { if (h[i, j] >= 0 & h[i, j] < 60) { R[i, j] = (int)((C[i, j] + m[i, j]) * 255); G[i, j] = (int)((X[i, j] + m[i, j]) * 255); B[i, j] = (int)(m[i, j] * 255); } else if (h[i, j] >= 00 & h[i, j] < 120) { R[i, j] = (int)((X[i, j] + m[i, j]) * 255); G[i, j] = (int)((C[i, j] + m[i, j]) * 255); B[i, j] = (int)(m[i, j] * 255); } else if (h[i, j] >= 120 & h[i, j] < 180) { R[i, j] = (int)(m[i, j] * 255); G[i, j] = (int)((C[i, j] + m[i, j]) * 255); B[i, j] = (int)((X[i, j] + m[i, j]) * 255); } else if (h[i, j] >= 180 & h[i, j] < 240) { R[i, j] = (int)(m[i, j] * 255); G[i, j] = (int)((X[i, j] + m[i, j]) * 255); B[i, j] = (int)((C[i, j] + m[i, j]) * 255); } else if (h[i, j] >= 240 & h[i, j] < 300) { R[i, j] = (int)((X[i, j] + m[i, j]) * 255); G[i, j] = (int)(m[i, j] * 255); B[i, j] = (int)((C[i, j] + m[i, j]) * 255); } else if (h[i, j] >= 300 & h[i, j] < 360) { R[i, j] = (int)((C[i, j] + m[i, j]) * 255); G[i, j] = (int)(m[i, j] * 255); B[i, j] = (int)((X[i, j] + m[i, j]) * 255); } } } rgbResult.Add(new ArraysListInt() { Color = R }); rgbResult.Add(new ArraysListInt() { Color = G }); rgbResult.Add(new ArraysListInt() { Color = B }); return(rgbResult); }