/// <summary> /// 该方法是找出所有相似的点,然后取最左边的点和最右边的点的中间,即使小人的中心点 /// </summary> /// <param name="bitmap"></param> /// <param name="width"></param> /// <param name="sy"></param> /// <param name="ey"></param> /// <param name="personColor"></param> /// <returns></returns> public static PersonEntity GetLittlePersonBottom(Bitmap bitmap, int width, int sy, int ey, Color personColor, Action <string, Label> timeAction, Label label) { var lx = width; var ly = 0; var rx = 0; var ry = 0; var miny = bitmap.Height; var maxy = 0; Stopwatch sw = new Stopwatch(); sw.Start(); LockBitmap lockbmp = new LockBitmap(bitmap); lockbmp.LockBits(); for (var y = sy; y < ey; ++y) { for (var x = 0; x < width; ++x) { //var color = bitmap.GetPixel(x, y); var color = lockbmp.GetPixel(x, y); if (Math.Abs(color.R - personColor.R) <= 10 && Math.Abs(color.G - personColor.G) <= 10 && Math.Abs(color.B - personColor.B) <= 10) { //bitmap.SetPixel(x, y, Color.Red); if (x <= lx) { lx = x; ly = y; } if (x >= rx) { rx = x; ry = y; } if (y < miny) { miny = y; } if (y > maxy) { maxy = y; } } } } lockbmp.UnlockBits(); var px = (rx - lx) / 2 + lx; var py = ly; var g = Graphics.FromImage(bitmap); //最左边的点 g.FillEllipse(Brushes.Red, new Rectangle(lx - 2, ly - 2, 5, 5)); //真正需要的点 g.FillEllipse(Brushes.Red, new Rectangle(px - 5, py - 5, 11, 11)); g.Dispose(); sw.Stop(); timeAction?.Invoke(sw.ElapsedMilliseconds.ToString(), label); //return new Point(px, py); return(new PersonEntity() { Center = new Point() { X = px, Y = py }, LeftUp = new Point() { X = lx - 5, Y = miny - 5 }, RightDown = new Point() { X = rx + 5, Y = maxy + 5 } }); }
/// <summary> /// 该方法是先找出盒子的顶点,然后找最左边颜色跟顶点相近的点,在取最右边的点,左右中心即是要的点 /// </summary> /// <param name="bitmap"></param> /// <param name="width"></param> /// <param name="sy"></param> /// <param name="ey"></param> /// <returns></returns> public static Point GetBoxCenterPoint(Bitmap bitmap, int width, int sy, int ey, PersonEntity pe, Action <string, Label> timeAction, Label label) { Stopwatch sw = new Stopwatch(); sw.Start(); LockBitmap lockbitmap = new LockBitmap(bitmap); lockbitmap.LockBits(); //去背景色 var background = lockbitmap.GetPixel(5, sy + 5); var A = new Point(-1, -1); //下一个盒子的顶点 var B = new Point(width, -1); //下一个盒子的最左边的点 var C = new Point(-1, -1); //下一个盒子的最右边的点 var boxColor = Color.Empty; //遍历 //找A点 for (var y = sy; (y < ey) && (A.X == -1); ++y) { for (var x = 0; x < width; ++x) { if (x >= pe.LeftUp.X && x <= pe.RightDown.X && y >= pe.LeftUp.Y && y <= pe.RightDown.Y) { continue; } var color = lockbitmap.GetPixel(x, y); if (Math.Abs(color.R - background.R) > 12 || Math.Abs(color.G - background.G) > 12 || Math.Abs(color.B - background.B) > 12) { A.X = x; //因为会有阴影,所以向下加几个像素 A.Y = y + 3; //记录盒子的颜色 boxColor = lockbitmap.GetPixel(A.X, A.Y); //结束获取A break; } } } //找B点 var bsx = A.X - 300; var bex = A.X + 300; bsx = bsx < 0 ? 0 : bsx; bex = bex > width ? width - 10 : bex; var count = 0; //有的靠很近,所以不用加太多 //for (var y = A.Y + 50; (y < A.Y + 300) && count <= 30; ++y) for (var y = A.Y + 1; (y < A.Y + 300) && count <= 30; ++y) { for (var x = bsx; x < bex; ++x) { var color = lockbitmap.GetPixel(x, y); if (Math.Abs(color.R - boxColor.R) <= 3 && Math.Abs(color.G - boxColor.G) <= 3 && Math.Abs(color.B - boxColor.B) <= 3) { if (x < B.X) { B.X = x; B.Y = y; } else if (x >= B.X) { ++count; } break; } } } var centerPoint = new Point(A.X, B.Y); lockbitmap.UnlockBits(); var g = Graphics.FromImage(bitmap); //取背景色的点 g.FillEllipse(Brushes.Red, 5, sy + 5, 10, 10); //A点 g.FillEllipse(Brushes.Red, new Rectangle(A.X - 5, A.Y - 5, 11, 11)); //B点 g.FillEllipse(Brushes.Red, new Rectangle(B.X - 5, B.Y - 5, 11, 11)); //中心点 g.FillEllipse(Brushes.Red, new Rectangle(centerPoint.X - 5, centerPoint.Y - 5, 11, 11)); g.Dispose(); sw.Stop(); timeAction?.Invoke(sw.ElapsedMilliseconds.ToString(), label); return(centerPoint); }