private static List <PointCluster> FindClusters(LazerSpot spotParams, byte[] rgbValues, int w, int h, int stride) { var clusters = new List <ScanCluster>(); List <ScanLine> curLines = null; for (var y = 0; y < h; y++) { ScanLine curLine = null; curLines = new List <ScanLine>(); for (var x = 0; x < w; x++) { var ind = x * 3 + y * stride; var red = rgbValues[ind]; var green = rgbValues[ind + 1]; var blue = rgbValues[ind + 2]; var delta = (red - spotParams.patRed) * (red - spotParams.patRed) + (green - spotParams.patGreen) * (green - spotParams.patGreen) + (blue - spotParams.patBlue) * (blue - spotParams.patBlue); var isIn = delta < spotParams.squareDev; if (isIn) { if (curLine == null) { curLine = new ScanLine { y = y, scans = new List <Point> { new Point(x, x) } } } ; else { curLine.scans[0] = new Point(curLine.scans[0].X, x); } } else if (curLine != null) { curLines.Add(curLine); curLine = null; } } if (curLine != null) { curLines.Add(curLine); } if (curLines.Count == 0) { continue; } MergeClusters(curLines, clusters); } if (curLines != null && curLines.Count > 0) { MergeClusters(curLines, clusters); } return(clusters.Select(c => c.ToPointCluster()).ToList()); }
public static List <PointCluster> FindClusters(Bitmap bmp, LazerSpot spotParams) { var rect = new Rectangle(0, 0, bmp.Width, bmp.Height); var bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat); try { IntPtr ptr = bmpData.Scan0; int bytes = Math.Abs(bmpData.Stride) * bmp.Height; var rgbValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); return(FindClusters(spotParams, rgbValues, bmp.Width, bmp.Height, bmpData.Stride)); } finally { bmp.UnlockBits(bmpData); } }