private static List <Rect> GetBelowHorizontalFlagRect(Rect belowFlgRect, Bitmap image) { List <Rect> result = new List <Rect>(); Rect rect; bool[,] marker = new bool[image.Width, image.Height]; int y = belowFlgRect.GetCenterPoint().y; int x = belowFlgRect.GetCenterPoint().x; int totalFlgRect = Constant.BELOW_HORIZONTAL_FLAG_RECT; Point p; while (result.Count < totalFlgRect) { p = new Point(x, y); if (!p.IsValidPoint()) { throw new Exception(ErrorUtils.getError(ErrorUtils.CAN_NOT_GET_ENOUGH_HORIZONTAL_FLAG_RECT, "Can not get enough horizontal flag rect!!")); } if (!marker[x, y] && CommonImageProcessing.IsBlackColor(new Point(x, y), image)) { rect = CommonImageProcessing.ExpandTheRectBlackPixel(new Point(x, y), image, ref marker); if (rect == null) { throw new Exception(ErrorUtils.getError(ErrorUtils.CAN_NOT_GET_ENOUGH_HORIZONTAL_FLAG_RECT, "Can not get enough horizontal flag rect!!")); } if (CommonImageProcessing.IsFlagRectangle(rect)) { result.Add(rect); } } x--; } return(result); }
private static Rect DetectBottomRightCorner(Bitmap image) { var marker = new bool[image.Width, image.Height]; Point p = CommonImageProcessing.FindDifferentColorPoint(new Point(Constant.AS_RIGHT_BORDER, Constant.AS_BOTTOM_BORDER), image, Constant.WHITE, ref marker); Rect bottomRightRect = CommonImageProcessing.ExpandTheRectBlackPixel(p, image, ref marker); if (bottomRightRect == null) { p = CommonImageProcessing.FindDifferentColorPoint(new Point(Constant.AS_RIGHT_BORDER, Constant.AS_BOTTOM_BORDER), image, Constant.WHITE, ref marker); bottomRightRect = CommonImageProcessing.ExpandTheRectBlackPixel(p, image, ref marker); if (bottomRightRect == null) { throw new Exception(ErrorUtils.getError(ErrorUtils.CAN_NOT_FIND_THE_TOP_RIGHT_FLAG_RECT, "Can not detect the top right flag rectangle. Tried 2 attempts!!")); } else { ValidateBottomRightFlagRect(bottomRightRect); return(bottomRightRect); } } else { ValidateBottomRightFlagRect(bottomRightRect); return(bottomRightRect); } }
private static Rect DetectTopRightFlagRect(Bitmap image) { //In case the points expanded not match the template rectangle. We need to mark the visited point, so we don't go to these point again var marker = new bool[image.Width, image.Height]; Point p = CommonImageProcessing.FindDifferentColorPoint(new Point(Constant.AS_RIGHT_BORDER, Constant.AS_TOP_BORDER), image, Constant.WHITE, ref marker); Rect topRightFlagRect = CommonImageProcessing.ExpandTheRectBlackPixel(p, image, ref marker); if (topRightFlagRect == null) { p = CommonImageProcessing.FindDifferentColorPoint(new Point(Constant.AS_RIGHT_BORDER, Constant.AS_TOP_BORDER), image, Constant.WHITE, ref marker); topRightFlagRect = CommonImageProcessing.ExpandTheRectBlackPixel(p, image, ref marker); if (topRightFlagRect == null) { throw new Exception(ErrorUtils.getError(ErrorUtils.CAN_NOT_FIND_THE_TOP_RIGHT_FLAG_RECT, "Can not detect the top right flag rectangle. Tried 2 attempts!!")); } else { ValidateTopRightFlagRect(topRightFlagRect); return(topRightFlagRect); } } else { ValidateTopRightFlagRect(topRightFlagRect); return(topRightFlagRect); } }
private static List <Rect> GetVerticalFlagRect(Rect aboveFlgRect, Bitmap image) { List <Rect> result = new List <Rect>(); Rect rect; bool[,] marker = new bool[image.Width, image.Height]; int y = aboveFlgRect.GetCenterPoint().y; int x = aboveFlgRect.GetCenterPoint().x; int totalFlgRect = TemplateUtils.GetNumberOfVerticalFLagRect(Globals.currentTemplate); Point p; while (result.Count < totalFlgRect) { p = new Point(x, y); if (!p.IsValidPoint()) { throw new Exception(ErrorUtils.getError(ErrorUtils.CAN_NOT_GET_ENOUGH_VERTICAL_FLAG_RECT, "Can not get enough vertical flag rect!!")); } if (!marker[x, y] && CommonImageProcessing.IsBlackColor(new Point(x, y), image)) { rect = CommonImageProcessing.ExpandTheRectBlackPixel(new Point(x, y), image, ref marker); if (rect == null) { throw new Exception(ErrorUtils.getError(ErrorUtils.CAN_NOT_GET_ENOUGH_VERTICAL_FLAG_RECT, "Can not get enough vertical flag rect!!")); } if (CommonImageProcessing.IsFlagRectangle(rect)) { result.Add(rect); } } y++; } return(result); }
private static void ValidateBottomRightFlagRect(Rect rect) { if (rect.topLeft.x > Constant.AS_TOP_BOTTOM_RIGHT_Y_MAX || rect.topLeft.x < Constant.AS_TOP_BOTTOM_RIGHT_Y_MIN) { throw new Exception(ErrorUtils.getError(ErrorUtils.TOP_RIGHT_FLAG_RECT_NOT_VALID, "Can not find the top right flag rectangle")); } }
//BFS and find the first point that different to the specific color //Used to detect the top right and bottom right flag rectangle public static Point FindDifferentColorPoint(Point src, Bitmap image, int color, ref bool[,] marker) { if (marker == null) { marker = new bool[image.Height, image.Width]; } Point top; Point res = new Point(); Queue <Point> queue = new Queue <Point>(); queue.Enqueue(src); marker[src.x, src.y] = true; while (queue.Count != 0) { top = queue.Dequeue(); if (!IsTheSameColor(top, image, color)) { return(top); } List <Point> availableMoves = top.GetAvailableMoves(); foreach (Point point in availableMoves) { if (!marker[point.x, point.y]) { marker[point.x, point.y] = true; queue.Enqueue(point); } } } throw new Exception(ErrorUtils.getError(ErrorUtils.CAN_NOT_FIND_DIFF_COLOR, "Can not find the pixel with diferrent color")); }
//Expanded the black pixel but return the rectangle object //Used to recognize the rectangle that specified for the answer on AS //In case the shape expanded not match the Flag Rect - return null public static Rect ExpandTheRectBlackPixel(Point src, Bitmap image, ref bool[,] marker) { if (marker == null) { marker = new bool[image.Width, image.Height]; } Point topLeft = null, bottomRight = null; var queue = new Queue <Point>(); Point top; int numberOfPoints = 0; queue.Enqueue(src); marker[src.x, src.y] = true; topLeft = new Point(src.x, src.y); bottomRight = new Point(src.x, src.y); while (queue.Count != 0) { top = queue.Dequeue(); numberOfPoints++; if (numberOfPoints > Constant.FLAG_RECT_UPPER_AREA) { return(null); } topLeft.x = Math.Min(topLeft.x, top.x); topLeft.y = Math.Min(topLeft.y, top.y); bottomRight.x = Math.Max(bottomRight.x, top.x); bottomRight.y = Math.Max(bottomRight.y, top.y); List <Point> availableMoves = top.GetAvailableMoves(); foreach (Point point in availableMoves) { if (!marker[point.x, point.y] && IsBlackColor(point, image)) { marker[point.x, point.y] = true; queue.Enqueue(point); } } } if (bottomRight == null || topLeft == null) { throw new Exception(ErrorUtils.getError(ErrorUtils.CAN_NOT_FIND_THE_RECTANGLE_CORNER, "Can not find the flag rectangle corner")); } Rect result = new Rect(topLeft, bottomRight); if (!IsFlagRectangle(result)) { return(null); } return(new Rect(topLeft, bottomRight)); }