public void Apply(SRegion region) { Rectangle bounds = region.RegionRectangle; unsafe { int dilationCenterX = (structElementSize.Width - 1) / 2; int dilationCenterY = (structElementSize.Height - 1) / 2; int dilationMaxX = structElementSize.Width - 1; int dilationMaxY = structElementSize.Height - 1; int* _dilationCenterX = (int*)dilationCenterX; int* _dilationCenterY = (int*)dilationCenterY; int* _dilationMaxX = (int*)dilationMaxX; int* _dilationMaxY = (int*)dilationMaxX; int* x_min = (int*)bounds.X; int* x_max = (int*)(bounds.X + bounds.Width - (int)_dilationCenterX); int* y_min = (int*)bounds.Y; int* y_max = (int*)(bounds.Y + bounds.Height - (int)_dilationCenterY); for (int* x = x_min; x < x_max; x++) { for (int* y = y_min; y < y_max; y++) { bool bitVal = region[(int)x, (int)y]; for (int* sX = (int*)0; sX < _dilationMaxX; sX++) { for (int* sY = (int*)0; sY < _dilationMaxY; sY++) { if (structElement[(int)sX, (int)sY] & region[(int)x + (int)sX, (int)y + (int)sY]) { region.AddPoint((int)x + dilationCenterX, (int)y + dilationCenterY); } } } } } } }
private unsafe void CreateRegionCollection() { ///Create regions collection Dictionary<int, SRegion> regionDictionary = new Dictionary<int, SRegion>(); unchecked { for (int x = 0; x < Image.Size.Width; x++) { for (int y = 0; y < Image.Size.Height; y++) { int regionId = binaryMask[x, y]; if (regionId > 0) { if (regionDictionary.ContainsKey(regionId)) { regionDictionary[regionId].AddPoint(x, y); } else { SRegion region = new SRegion(ref binaryMask, regionId, base.Image.Size); region.AddPoint(x, y); regionDictionary.Add(regionId, region); } } } } } ///Convert region connection to array of regions regions = new SRegion[regionDictionary.Count]; int index = 0; foreach (SRegion r in regionDictionary.Values) { regions[index] = r; index++; } }
public override void Execute() { foreach (IPreProcessFilter filter in preProcessFilters) { filter.Apply(base.Image.Size, this.regionMask); } int regionIndex = 1; regionMask = new int[base.Image.Width, base.Image.Height]; for (int x = 0; x < base.Image.Width; x++) { for (int y = 0; y < base.Image.Height; y++) { if (regionMask[x, y] == 0 & learned.Contains(base.Image.GetPixel(x, y))) { ///Flood-Fill algorithm Queue<Point> q = new Queue<Point>(); if (regionMask[x, y] != 0) continue; regionIndex++; q.Enqueue(new Point(x, y)); while (q.Count > 0) { Point p = q.Peek(); int x1 = p.X; int y1 = p.Y; if (IsValid(p) & learned.Contains(base.Image.GetPixel(x1, y1))) { regionMask[x1, y1] = regionIndex; } if (IsValid(new Point(x1, y1 + 1))) { regionMask[x1, y1 + 1] = regionIndex; q.Enqueue(new Point(x1, y1 + 1)); } if (IsValid(new Point(x1, y1 - 1))) { regionMask[x1, y1 - 1] = regionIndex; q.Enqueue(new Point(x1, y1 - 1)); } if (IsValid(new Point(x1 + 1, y1))) { regionMask[x1 + 1, y1] = regionIndex; q.Enqueue(new Point(x1 + 1, y1)); } if (IsValid(new Point(x1 - 1, y1))) { regionMask[x1 - 1, y1] = regionIndex; q.Enqueue(new Point(x1 - 1, y1)); } q.Dequeue(); } ///end of Flood-Fill algorithm } } } ///TODO: Check this. ///scan regionsMask pixel-by-pixel and forming regions groups Dictionary<int, SRegion> regionDictionary = new Dictionary<int, SRegion>(); for (int x = 0; x < base.Image.Size.Width; x++) { for (int y = 0; y < base.Image.Size.Height; y++) { int regionId = regionMask[x, y]; if (regionId > 0) { if (regionDictionary.ContainsKey(regionId)) { regionDictionary[regionId].AddPoint(x, y); } else { //SRegion region = new SRegion(base.Image.Size); SRegion region = new SRegion(ref regionMask, regionIndex, base.Image.Size); region.AddPoint(x, y); regionDictionary.Add(regionId, region); } } } } regions = new SRegion[regionDictionary.Count]; int index = 0; foreach (SRegion r in regionDictionary.Values) { regions[index] = r; index++; } foreach (IPostProcessFilter filter in regionFilters) { filter.Apply(ref regions); } foreach (IPostProcessFilter filter in regionFilters) { foreach (SRegion region in regions) { filter.Apply(region); } } }