| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- using System;
- using System.Collections.Generic;
- using System.Threading.Tasks;
- namespace o0.Project
- {
- public static partial class Extension
- {
- static private Matrix IdentifyEdgeVariance(this Matrix mat)
- {
- var conSize = 3;
- var conArea = conSize * conSize;
- var convolution = new Matrix(new Geometry2D.Vector<int>(mat.Size.x - (conSize - 1), mat.Size.y - (conSize - 1)), Tiling: true);
- var pixelC = convolution.Element;
- var convolutionWidth = convolution.Size.x;
- Parallel.For(0, convolution.Size.x * convolution.Size.y, i => {
- var iPx = i % convolutionWidth;
- var iPy = i / convolutionWidth;
- var mean = 0.0f;
- //var max = 0.0f;
- //var min = 1.0f;
- List<float> rList = new List<float>();
- for (var jX = 0; jX < conSize; ++jX)
- {
- for (var jY = 0; jY < conSize; ++jY)
- {
- var jIndex = (iPx + jX) + (iPy + jY) * mat.Size.x;
- var r = mat.Element[jIndex];
- mean += r;
- rList.Add(r);
- /*
- if (max < r)
- max = r;
- if (min > r)
- min = r;/**/
- }
- }
- mean /= conArea;
- var variance = 0.0f;
- foreach (var j in rList)
- {
- var d = (j - mean);// / mean;
- variance += d * d;
- }
- variance /= conArea;
- variance /= mean;
- /*
- foreach (var j in (Geometry2D.Vector<int>.One * 3).Range())
- {
- var jP = iP + j;
- var jIndex = jP.x + jP.y * Size.x;
- rList.Add(pixelLighted[jIndex].r);
- }/**/
- //pixelC[i] = new UnityEngine.Color(Num.Extension.Variance(rList), 0, 0);
- pixelC[i] = variance;
- });
- return convolution.Map(ignoreExtremum: 10);
- }
- static private Matrix IdentifyEdgeGradientX(this Matrix mat)
- {
- var conSize = 3;
- var conArea = conSize * conSize;
- var convolution = new Matrix(new Geometry2D.Vector<int>(mat.Size.x - (conSize - 1), mat.Size.y - (conSize - 1)), Tiling: true);
- var pixelC = convolution.Element;
- var convolutionWidth = convolution.Size.x;
- Parallel.For(0, convolution.Size.x * convolution.Size.y, i => {
- var iPx = i % convolutionWidth;
- var iPy = i / convolutionWidth;
- pixelC[i] = MathF.Abs(mat.Element[(iPx + 0) + (iPy + 1) * mat.Size.x] - mat.Element[(iPx + 2) + (iPy + 1) * mat.Size.x]);
- });
- return convolution.Map(ignoreExtremum: 10);
- }
- static private Matrix IdentifyEdgeGradientY(this Matrix mat)
- {
- var conSize = 3;
- var conArea = conSize * conSize;
- var convolution = new Matrix(new Geometry2D.Vector<int>(mat.Size.x - (conSize - 1), mat.Size.y - (conSize - 1)), Tiling: true);
- var pixelC = convolution.Element;
- var convolutionWidth = convolution.Size.x;
- Parallel.For(0, convolution.Size.x * convolution.Size.y, i => {
- var iPx = i % convolutionWidth;
- var iPy = i / convolutionWidth;
- pixelC[i] = MathF.Abs(mat.Element[(iPx + 1) + (iPy + 0) * mat.Size.x] - mat.Element[(iPx + 1) + (iPy + 2) * mat.Size.x]);
- });
- return convolution.Map(ignoreExtremum: 10);
- }
- static private Matrix IdentifyEdgeGradient(this Matrix mat)
- {
- var conSize = 3;
- var conArea = conSize * conSize;
- var convolution = new Matrix(new Geometry2D.Vector<int>(mat.Size.x - (conSize - 1), mat.Size.y - (conSize - 1)), Tiling: true);
- var pixelC = convolution.Element;
- var convolutionWidth = convolution.Size.x;
- Parallel.For(0, convolution.Size.x * convolution.Size.y, i => {
- var iPx = i % convolutionWidth;
- var iPy = i / convolutionWidth;
- var gX = mat.Element[(iPx + 2) + (iPy + 1) * mat.Size.x] * 2
- - mat.Element[(iPx + 0) + (iPy + 1) * mat.Size.x] * 2;
- var gY = mat.Element[(iPx + 1) + (iPy + 2) * mat.Size.x] * 2
- - mat.Element[(iPx + 1) + (iPy + 0) * mat.Size.x] * 2;
- float root2 = 1.4142135623730950488016887242097f;
- var gXY = //x0y0向x2y2方向的斜率
- mat.Element[(iPx + 2) + (iPy + 2) * mat.Size.x]
- - mat.Element[(iPx + 0) + (iPy + 0) * mat.Size.x];
- gXY *= root2;
- var gYX = //x2y0向x0y2方向的斜率
- + mat.Element[(iPx + 0) + (iPy + 2) * mat.Size.x]
- - mat.Element[(iPx + 2) + (iPy + 0) * mat.Size.x];
- gYX *= root2;
- pixelC[i] = o0.Max(MathF.Abs(gX), MathF.Abs(gY), MathF.Abs(gXY), MathF.Abs(gYX));
- });
- return convolution.Map(ignoreExtremum: 10);
- }
- ////////////////梯度大小图///梯度方向图 0-360度 数学4象限
- static public (Matrix, Matrix) IdentifyEdge(this Matrix mat)//这个效果最好
- {
- var conSize = 3;
- var conArea = conSize * conSize;
- var convolution = new Matrix(new Geometry2D.Vector<int>(mat.Size.x - (conSize - 1), mat.Size.y - (conSize - 1)), Tiling: true);
- var pixelC = convolution.Element;
- var dirMat = new Matrix(convolution.Size, Tiling: true);
- var pixelDir = dirMat.Element;
- var convolutionWidth = convolution.Size.x;
- Parallel.For(0, convolution.Size.x * convolution.Size.y, i => {
- var iPx = i % convolutionWidth;
- var iPy = i / convolutionWidth;
- var sum = 0.0f;
- //var max = 0.0f;
- //var min = 1.0f;
- for (var jX = 0; jX < conSize; ++jX)
- for (var jY = 0; jY < conSize; ++jY)
- {
- var v = mat.Element[(iPx + jX) + (iPy + jY) * mat.Size.x];
- sum += v;
- /*
- if (max < v)
- max = v;
- if (min > v)
- min = v;/**/
- }
- if (sum == 0.0f)
- return;
- /*
- if (min == 0.0f)
- return;/**/
- var gX = mat.Element[(iPx + 2) + (iPy + 0) * mat.Size.x]
- + mat.Element[(iPx + 2) + (iPy + 1) * mat.Size.x] * 2
- + mat.Element[(iPx + 2) + (iPy + 2) * mat.Size.x]
- - mat.Element[(iPx + 0) + (iPy + 0) * mat.Size.x]
- - mat.Element[(iPx + 0) + (iPy + 1) * mat.Size.x] * 2
- - mat.Element[(iPx + 0) + (iPy + 2) * mat.Size.x];
- var gY = mat.Element[(iPx + 0) + (iPy + 2) * mat.Size.x]
- + mat.Element[(iPx + 1) + (iPy + 2) * mat.Size.x] * 2
- + mat.Element[(iPx + 2) + (iPy + 2) * mat.Size.x]
- - mat.Element[(iPx + 0) + (iPy + 0) * mat.Size.x]
- - mat.Element[(iPx + 1) + (iPy + 0) * mat.Size.x] * 2
- - mat.Element[(iPx + 2) + (iPy + 0) * mat.Size.x];
- float root2 = 1.4142135623730950488016887242097f;
- var gXY = mat.Element[(iPx + 1) + (iPy + 2) * mat.Size.x] //x0y0向x2y2方向的斜率
- + mat.Element[(iPx + 2) + (iPy + 2) * mat.Size.x]
- + mat.Element[(iPx + 2) + (iPy + 1) * mat.Size.x]
- - mat.Element[(iPx + 1) + (iPy + 0) * mat.Size.x]
- - mat.Element[(iPx + 0) + (iPy + 0) * mat.Size.x]
- - mat.Element[(iPx + 0) + (iPy + 1) * mat.Size.x];
- gXY *= root2;
- var gYX = mat.Element[(iPx + 1) + (iPy + 2) * mat.Size.x] //x2y0向x0y2方向的斜率
- + mat.Element[(iPx + 0) + (iPy + 2) * mat.Size.x]
- + mat.Element[(iPx + 0) + (iPy + 1) * mat.Size.x]
- - mat.Element[(iPx + 1) + (iPy + 0) * mat.Size.x]
- - mat.Element[(iPx + 2) + (iPy + 0) * mat.Size.x]
- - mat.Element[(iPx + 2) + (iPy + 1) * mat.Size.x];
- gYX *= root2;
- float[] gra = new float[] { MathF.Abs(gX), MathF.Abs(gY), MathF.Abs(gXY), MathF.Abs(gYX) };
- var maxIndex = o0.MaxIndex(gra);
- pixelC[i] = gra[maxIndex];
- switch (maxIndex)
- {
- case 0:
- pixelDir[i] = gX > 0 ? 0 : 180;
- break;
- case 1:
- pixelDir[i] = gY > 0 ? 90 : 270;
- break;
- case 2:
- pixelDir[i] = gXY > 0 ? 45 : 225;
- break;
- case 3:
- pixelDir[i] = gYX > 0 ? 135 : 315;
- break;
- }
- //pixelC[i] = MathF.Abs(gX) + MathF.Abs(gY) + MathF.Abs(gXY) + MathF.Abs(gYX);
- /*
- if (pixelC[i] / 9f < 1.0f / 256f)
- {
- pixelC[i] = 0;
- return;
- }/**/
- /*
- if (sum < 100f/256f)
- {
- pixelC[i] = 0;
- return;
- }/**/
- //pixelC[i] = o0.Max(MathF.Abs(gX), MathF.Abs(gY), MathF.Abs(gXY), MathF.Abs(gYX));
- //pixelC[i] /= MathF.Pow(sum / 9, 0.1f);
- //pixelC[i] /= min + 0.5f;
- //pixelC[i] /= min + 0.1f;
- pixelC[i] /= sum / 9f + 1f;//+1是为了防止除数太小,结果不合理地过大
- });
- return (convolution.Map(ignoreExtremum: 10), dirMat);
- }
- static public (Matrix, Matrix) IdentifyEdge55GradientFull(this Matrix mat)
- {
- var conSize = 5;
- var conArea = conSize * conSize;
- var convolution = new Matrix(new Geometry2D.Vector<int>(mat.Size.x - (conSize - 1), mat.Size.y - (conSize - 1)), Tiling: true);
- var pixelC = convolution.Element;
- var dirMat = new Matrix(convolution.Size, Tiling: true);
- var pixelDir = dirMat.Element;
- var convolutionWidth = convolution.Size.x;
- Parallel.For(0, convolution.Size.x * convolution.Size.y, i => {
- var iPx = i % convolutionWidth;
- var iPy = i / convolutionWidth;
- var sum = 0.0f;
- for (var jX = 0; jX < conSize; ++jX)
- for (var jY = 0; jY < conSize; ++jY)
- sum += mat.Element[(iPx + jX) + (iPy + jY) * mat.Size.x];
- if (sum == 0.0f)
- return;
- var gX = mat.Element[(iPx + 4) + (iPy + 1) * mat.Size.x] //梯度0度
- + mat.Element[(iPx + 4) + (iPy + 2) * mat.Size.x] * 2
- + mat.Element[(iPx + 4) + (iPy + 3) * mat.Size.x]
- - mat.Element[(iPx + 0) + (iPy + 1) * mat.Size.x]
- - mat.Element[(iPx + 0) + (iPy + 2) * mat.Size.x] * 2
- - mat.Element[(iPx + 0) + (iPy + 3) * mat.Size.x];
- var gY = mat.Element[(iPx + 1) + (iPy + 4) * mat.Size.x] //梯度90度
- + mat.Element[(iPx + 2) + (iPy + 4) * mat.Size.x] * 2
- + mat.Element[(iPx + 3) + (iPy + 4) * mat.Size.x]
- - mat.Element[(iPx + 1) + (iPy + 0) * mat.Size.x]
- - mat.Element[(iPx + 2) + (iPy + 0) * mat.Size.x] * 2
- - mat.Element[(iPx + 3) + (iPy + 0) * mat.Size.x];
- float root2 = 1.4142135623730950488016887242097f;
- var gXY = mat.Element[(iPx + 3) + (iPy + 4) * mat.Size.x] //x0y0向x2y2方向的斜率, 45度
- + mat.Element[(iPx + 4) + (iPy + 4) * mat.Size.x]
- + mat.Element[(iPx + 4) + (iPy + 3) * mat.Size.x]
- - mat.Element[(iPx + 1) + (iPy + 0) * mat.Size.x]
- - mat.Element[(iPx + 0) + (iPy + 0) * mat.Size.x]
- - mat.Element[(iPx + 0) + (iPy + 1) * mat.Size.x];
- gXY *= root2;
- var gYX = mat.Element[(iPx + 1) + (iPy + 4) * mat.Size.x] //x2y0向x0y2方向的斜率, 135度
- + mat.Element[(iPx + 0) + (iPy + 4) * mat.Size.x]
- + mat.Element[(iPx + 0) + (iPy + 3) * mat.Size.x]
- - mat.Element[(iPx + 3) + (iPy + 0) * mat.Size.x]
- - mat.Element[(iPx + 4) + (iPy + 0) * mat.Size.x]
- - mat.Element[(iPx + 4) + (iPy + 1) * mat.Size.x];
- gYX *= root2;
- float[] gra = new float[] { MathF.Abs(gX), MathF.Abs(gY), MathF.Abs(gXY), MathF.Abs(gYX) };
- var maxIndex = o0.MaxIndex(gra);
- pixelC[i] = gra[maxIndex];
- switch (maxIndex)
- {
- case 0:
- pixelDir[i] = gX > 0 ? 0 : 180;
- break;
- case 1:
- pixelDir[i] = gY > 0 ? 90 : 270;
- break;
- case 2:
- pixelDir[i] = gXY > 0 ? 45 : 225;
- break;
- case 3:
- pixelDir[i] = gYX > 0 ? 135 : 315;
- break;
- }
- //pixelC[i] = MathF.Abs(gX) + MathF.Abs(gY) + MathF.Abs(gXY) + MathF.Abs(gYX);
- /*
- if (pixelC[i] / 9f < 1.0f / 256f)
- {
- pixelC[i] = 0;
- return;
- }/**/
- /*
- if (sum < 100f/256f)
- {
- pixelC[i] = 0;
- return;
- }/**/
- //pixelC[i] = o0.Max(MathF.Abs(gX), MathF.Abs(gY), MathF.Abs(gXY), MathF.Abs(gYX));
- //pixelC[i] /= MathF.Pow(sum / 9, 0.1f);
- //pixelC[i] /= min + 0.5f;
- //pixelC[i] /= min + 0.1f;
- pixelC[i] /= sum / 9f + 1f;//+1是为了防止除数太小,结果不合理地过大
- });
- return (convolution.Map(ignoreExtremum: 10), dirMat);
- }
- }
- }
|