| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 | 
							- using System;
 
- using System.Collections.Generic;
 
- using System.Linq;
 
- using System.Text;
 
- using System.Threading.Tasks;
 
- using UnityEngine;
 
- using UnityEngine.UI;
 
- using o0.Geometry2D.Float;
 
- namespace o0.Project
 
- {
 
-     public static partial class Extension
 
-     {
 
-         public static (Vector, float) lineSegGradient(Matrix mat, Matrix dir, float gradient, Vector start, Vector end, bool reverseXY)
 
-         {
 
-             int startX, endX;
 
-             if (start.x < end.x)
 
-             {
 
-                 startX = Mathf.RoundToInt(start.x) + 1;
 
-                 endX = Mathf.RoundToInt(end.x) + 1;
 
-             }
 
-             else
 
-             {
 
-                 startX = Mathf.RoundToInt(start.x) - 1;
 
-                 endX = Mathf.RoundToInt(end.x) - 1;
 
-             }
 
-             if(startX == endX)
 
-                 return (new Vector(start.x, start.y), 0);
 
-             var xDiff = end.x - start.x;
 
-             var xToYRate = (float)(end.y - start.y) / xDiff;
 
-             Func<float, float> xToYFunc = (x) => (x - start.x) * xToYRate + start.y;
 
-             var B1 = Mathf.RoundToInt(start.x);
 
-             var B1V = mat[B1, Mathf.RoundToInt(start.y)];
 
-             var Sum1 = B1V;
 
-             foreach (var x in startX.Range(endX))
 
-             {
 
-                 var y = xToYFunc(x);
 
-                 var y1 = Mathf.FloorToInt(y);
 
-                 var y2 = Mathf.CeilToInt(y);
 
-                 var y0 = y1 - 1;
 
-                 var y3 = y2 + 1;
 
-                 int C0I, C3I;
 
-                 int C1I, C2I;
 
-                 if (reverseXY)
 
-                 {
 
-                     C0I = mat.Index(y0, x);
 
-                     C1I = mat.Index(y1, x);
 
-                     C2I = mat.Index(y2, x);
 
-                     C3I = mat.Index(y3, x);
 
-                 }
 
-                 else
 
-                 {
 
-                     C0I = mat.Index(x, y0);
 
-                     C1I = mat.Index(x, y1);
 
-                     C2I = mat.Index(x, y2);
 
-                     C3I = mat.Index(x, y3);
 
-                 }
 
-                 var C0A = dir.Element[C0I];
 
-                 var C1A = dir.Element[C1I];
 
-                 var C2A = dir.Element[C2I];
 
-                 var C3A = dir.Element[C3I];
 
-                 //var CV = (y2 - y) * mat.Element[C1I] + (y - y1) * mat.Element[C2I];
 
-                 var CV = o0.Max(mat.Element[C0I], mat.Element[C1I], mat.Element[C2I], mat.Element[C3I]);
 
-                 //var avaAngle2 = 22.5;
 
-                 var avaAngle = 90;
 
-                 var halfAvaAngle = avaAngle/2;
 
-                 //var avaAngle2 = 33.75;
 
-                 if (!(MathF.Abs(C0A - gradient) <= halfAvaAngle || MathF.Abs(C0A - 360 - gradient) <= halfAvaAngle  || MathF.Abs(C0A + 360 - gradient) <= halfAvaAngle
 
-                 || MathF.Abs(C1A - gradient) <= halfAvaAngle    || MathF.Abs(C1A - 360 - gradient) <= halfAvaAngle  || MathF.Abs(C1A + 360 - gradient) <= halfAvaAngle
 
-                 || MathF.Abs(C2A - gradient) <= halfAvaAngle    || MathF.Abs(C2A - 360 - gradient) <= halfAvaAngle  || MathF.Abs(C2A + 360 - gradient) <= halfAvaAngle
 
-                 || MathF.Abs(C3A - gradient) <= halfAvaAngle    || MathF.Abs(C3A - 360 - gradient) <= halfAvaAngle  || MathF.Abs(C3A + 360 - gradient) <= halfAvaAngle))
 
-                 {
 
-                     break;
 
-                 }
 
-                 B1 = x;
 
-                 Sum1 += CV;
 
-             }
 
-             return (new Vector(B1, xToYFunc(B1)), Sum1);
 
-         }
 
-         public static (Line, float) lineSegGradient(Matrix mat, Matrix dir, float gradient, Vector start)
 
-         {
 
-             var lineDir = (gradient + 90) % 180;//需要检测的线的角度
 
-             var line = mat.MaskLine(start, lineDir);
 
-             var range = (6, 2);
 
-             if (lineDir < 45 || lineDir > 135)
 
-             {
 
-                 //var (p1, sum1) = lineSegGradient(mat, dir, gradient, start, line.A, false); 
 
-                 //var (p2, sum2) = lineSegGradient(mat, dir, gradient, start, line.B, false);
 
-                 var (p1, sum1) = ZIMLineSegGradient(mat, dir, gradient, start, line.A, range, false);
 
-                 var (p2, sum2) = ZIMLineSegGradient(mat, dir, gradient, start, line.B, range, false);
 
-                 return (new Line(p1, p2), sum1 + sum2);
 
-             }
 
-             else
 
-             {
 
-                 var startR = new Vector(start.y, start.x);
 
-                 //var (p1, sum1) = lineSegGradient(mat, dir, gradient, startR, new Vector(line.A.y, line.A.x), true);
 
-                 //var (p2, sum2) = lineSegGradient(mat, dir, gradient, startR, new Vector(line.B.y, line.B.x), true);
 
-                 var (p1, sum1) = ZIMLineSegGradient(mat, dir, gradient, startR, new Vector(line.A.y, line.A.x), range, true);
 
-                 var (p2, sum2) = ZIMLineSegGradient(mat, dir, gradient, startR, new Vector(line.B.y, line.B.x), range, true);
 
-                 return (new Line(new Vector(p1.y, p1.x), new Vector(p2.y, p2.x)), sum1 + sum2);
 
-             }
 
-         }/**/
 
-         /// <summary>
 
-         /// List<(Line, float, float)>
 
-         ///       线  线梯度和 线梯度方向0-180
 
-         /// </summary>
 
-         /// <returns>以梯度和最高值到最低值排列</returns>
 
-         static public List<(Line, float, float)> IdentifyLineLSD(this Matrix mat, float minLength = 100)
 
-         {
 
-             var (edge, edgeDir) = mat.IdentifyEdge();
 
-             return edge.IdentifyLineLSD(edgeDir, minLength);
 
-         }
 
-         /// <summary>
 
-         /// List<(Line, float, float)>
 
-         ///       线  线梯度和 线梯度方向0-180
 
-         /// </summary>
 
-         /// <param name="LineCaptureSize">获取line后,在line的位置清空多大范围的数据,以防重复获取(比如线段长10,size为5,3,则清空3像素宽,15像素长的长方形区域)</param>
 
-         /// <returns>以梯度和最高值到最低值排列</returns>
 
-         static public List<(Line, float, float)> IdentifyLineLSD(this Matrix gradientValueMat, Matrix gradientDirMat, float minLength = 100,
 
-             int maxReturnCount = int.MaxValue, Vector LineCaptureSize = default)
 
-         {
 
-             if (LineCaptureSize == default)
 
-                 LineCaptureSize = Vector.One * minLength;
 
-             var matBuffer = gradientValueMat;
 
-             //var (mat, gradientMat) = tex.IdentifyEdge();
 
-             //var lineMinLength = 50;
 
-             var avaAngle = 60;
 
-             var halfAvaAngle = avaAngle / 2;
 
-             var returnLines = new List<(Line, float, float)> ();
 
-             // while (mat.Element[maxIndex] != default)
 
-             int count = 0;
 
-             /*
 
-             var minIndex = matBuffer.Element.MinIndex(matBuffer.Width * matBuffer.Height / 2);
 
-             foreach (var i in minIndex)
 
-                 matBuffer.Element[i] = 0;/**/
 
-             var maxIndex = matBuffer.Element.MaxIndex();
 
-             var maxPos = matBuffer.Position(maxIndex);
 
-             var maxVector = new Vector(maxPos.Item1, maxPos.Item2);
 
-             while (matBuffer.Element[maxIndex] != 0 && count <= maxReturnCount)
 
-             {
 
-                 count++;
 
-                 var gradient = gradientDirMat.Element[maxIndex];//梯度
 
-                 var lines = new List<(Line, float, float, float)>(avaAngle);
 
-                 Parallel.For((int)Math.Floor(gradient - halfAvaAngle), (int)Math.Ceiling(gradient + halfAvaAngle) + 1, gradientI =>//需要检测的梯度
 
-                 {
 
-                     //var gradientF = (float)gradientI / scale;
 
-                     if (gradientI < 0)
 
-                         gradientI += 360;
 
-                     else if (gradientI > 360)
 
-                         gradientI -= 360;
 
-                     var dir = (gradientI + 90) % 180;//需要检测的线的角度
 
-                     //var (line, sum) = lineSegGradient(matBuffer, gradientDirMat, gradientF, maxVector);
 
-                     var (line, sum) = lineSegGradient(gradientValueMat, gradientDirMat, gradientI, maxVector);
 
-                     if (line.A != line.B)
 
-                         lock (matBuffer)
 
-                         {
 
-                             lines.Add((line, line.Length, sum, gradientI));
 
-                             //drawLineMap.DrawLine(line, sum);
 
-                         }
 
-                 });
 
-                 var (line , lineLength, sum, gradientI) = lines.Max((a, b) => a.Item3.CompareTo(b.Item3));
 
-                 if(lineLength != 0)
 
-                 {
 
-                     matBuffer.DrawLine(line, (x, y) => 0, LineCaptureSize);
 
-                 }
 
-                 if (lineLength > minLength)
 
-                     returnLines.Add((line, sum, gradientI));
 
-                 else
 
-                     matBuffer.Element[maxIndex] = 0;
 
-                 maxIndex = matBuffer.Element.MaxIndex();
 
-                 maxPos = matBuffer.Position(maxIndex);
 
-                 maxVector = new Vector(maxPos.Item1, maxPos.Item2);
 
-             }/**/
 
-             returnLines.Sort((a, b) => b.Item2.CompareTo(a.Item2));
 
-             return returnLines;
 
-             /*
 
-             var drawLineMap = new MatrixF2D(matBuffer.Width, matBuffer.Height);
 
-             var returnMaxLines = returnLines.Sub(0,10);
 
-             foreach (var (line, sum, gradient) in returnMaxLines)
 
-             {
 
-                 drawLineMap.DrawLine(line, (x, y) => 1, new Vector(0, 10));
 
-                 //drawLineMap.DrawLine(line, (x, y) => sum / line.Length, new Vector(0, 10));
 
-                 Debug.Log(line);
 
-             }
 
-             Debug.Log(returnLines.Count);
 
-             return drawLineMap;/**/
 
-         }
 
-     }
 
- }
 
 
  |