public WatershedPixel RemoveAtFront() { WatershedPixel temp = queue[0]; queue.RemoveAt(0); return(temp); }
private void CreatePixelMapAndHeightSortedArray(Image <Gray, byte> wtImg) { MIplImage data = wtImg.MIplImage; _pictureWidth = data.width; _pictureHeight = data.height; // pixel map holds every pixel thus size of (_pictureWidth * _pictureHeight) _pixelMap = new Dictionary <string, WatershedPixel>(_pictureWidth * _pictureHeight); unsafe { int offset = data.widthStep - data.width; byte *ptr = (byte *)(data.imageData); // get histogram of all values in grey = height for (int y = 0; y < data.height; y++) { for (int x = 0; x < data.width; x++, ptr++) { WatershedPixel p = new WatershedPixel(x, y, *ptr); // add every pixel to the pixel map _pixelMap.Add(p.X.ToString() + "," + p.Y.ToString(), p); _heightSortedList[*ptr].Add(p); } ptr += offset; } } this._currentLabel = 0; }
public void AddToEnd(WatershedPixel p) { queue.Add(p); }
private List<WatershedPixel> GetNeighbouringPixels(WatershedPixel centerPixel) { List<WatershedPixel> temp = new List<WatershedPixel>(); if (_numberOfNeighbours == 8) { /* CP = Center pixel (X,Y) -- get all 8 connected |-1,-1|0,-1|1,-1| |-1, 0| CP |1, 0| |-1,+1|0,+1|1,+1| */ // -1, -1 if ((centerPixel.X - 1) >= 0 && (centerPixel.Y - 1) >= 0) temp.Add(_pixelMap[(centerPixel.X - 1).ToString() + "," + (centerPixel.Y - 1).ToString()]); // 0, -1 if ((centerPixel.Y - 1) >= 0) temp.Add(_pixelMap[centerPixel.X.ToString() + "," + (centerPixel.Y - 1).ToString()]); // 1, -1 if ((centerPixel.X + 1) < _pictureWidth && (centerPixel.Y - 1) >= 0) temp.Add(_pixelMap[(centerPixel.X + 1).ToString() + "," + (centerPixel.Y - 1).ToString()]); // -1, 0 if ((centerPixel.X - 1) >= 0) temp.Add(_pixelMap[(centerPixel.X - 1).ToString() + "," + centerPixel.Y.ToString()]); // 1, 0 if ((centerPixel.X + 1) < _pictureWidth) temp.Add(_pixelMap[(centerPixel.X + 1).ToString() + "," + centerPixel.Y.ToString()]); // -1, 1 if ((centerPixel.X - 1) >= 0 && (centerPixel.Y + 1) < _pictureHeight) temp.Add(_pixelMap[(centerPixel.X - 1).ToString() + "," + (centerPixel.Y + 1).ToString()]); // 0, 1 if ((centerPixel.Y + 1) < _pictureHeight) temp.Add(_pixelMap[centerPixel.X.ToString() + "," + (centerPixel.Y + 1).ToString()]); // 1, 1 if ((centerPixel.X + 1) < _pictureWidth && (centerPixel.Y + 1) < _pictureHeight) temp.Add(_pixelMap[(centerPixel.X + 1).ToString() + "," + (centerPixel.Y + 1).ToString()]); } else { /* CP = Center pixel, N/A = not used (X,Y) -- get only 4 connected | N/A |0,-1| N/A | |-1, 0| CP |+1, 0| | N/A |0,+1| N/A | */ // -1, 0 if ((centerPixel.X - 1) >= 0) temp.Add(_pixelMap[(centerPixel.X - 1).ToString() + "," + centerPixel.Y.ToString()]); // 0, -1 if ((centerPixel.Y - 1) >= 0) temp.Add(_pixelMap[centerPixel.X.ToString() + "," + (centerPixel.Y - 1).ToString()]); // 1, 0 if ((centerPixel.X + 1) < _pictureWidth) temp.Add(_pixelMap[(centerPixel.X + 1).ToString() + "," + centerPixel.Y.ToString()]); // 0, 1 if ((centerPixel.Y + 1) < _pictureHeight) temp.Add(_pixelMap[centerPixel.X.ToString() + "," + (centerPixel.Y + 1).ToString()]); } return temp; }
private void CreatePixelMapAndHeightSortedArray(Image<Gray, byte> wtImg) { MIplImage data = wtImg.MIplImage; _pictureWidth = data.width; _pictureHeight = data.height; // pixel map holds every pixel thus size of (_pictureWidth * _pictureHeight) _pixelMap = new Dictionary<string, WatershedPixel>(_pictureWidth * _pictureHeight); unsafe { int offset = data.widthStep - data.width; byte* ptr = (byte*)(data.imageData); // get histogram of all values in grey = height for (int y = 0; y < data.height; y++) { for (int x = 0; x < data.width; x++, ptr++) { WatershedPixel p = new WatershedPixel(x, y, *ptr); // add every pixel to the pixel map _pixelMap.Add(p.X.ToString() + "," + p.Y.ToString(), p); _heightSortedList[*ptr].Add(p); } ptr += offset; } } this._currentLabel = 0; }
public override bool Equals(Object obj) { WatershedPixel p = (WatershedPixel)obj; return(X == p.X && X == p.Y); }
private List <WatershedPixel> GetNeighbouringPixels(WatershedPixel centerPixel) { List <WatershedPixel> temp = new List <WatershedPixel>(); if (_numberOfNeighbours == 8) { /* * CP = Center pixel * (X,Y) -- get all 8 connected |-1,-1|0,-1|1,-1| |-1, 0| CP |1, 0| |-1,+1|0,+1|1,+1| */ // -1, -1 if ((centerPixel.X - 1) >= 0 && (centerPixel.Y - 1) >= 0) { temp.Add(_pixelMap[(centerPixel.X - 1).ToString() + "," + (centerPixel.Y - 1).ToString()]); } // 0, -1 if ((centerPixel.Y - 1) >= 0) { temp.Add(_pixelMap[centerPixel.X.ToString() + "," + (centerPixel.Y - 1).ToString()]); } // 1, -1 if ((centerPixel.X + 1) < _pictureWidth && (centerPixel.Y - 1) >= 0) { temp.Add(_pixelMap[(centerPixel.X + 1).ToString() + "," + (centerPixel.Y - 1).ToString()]); } // -1, 0 if ((centerPixel.X - 1) >= 0) { temp.Add(_pixelMap[(centerPixel.X - 1).ToString() + "," + centerPixel.Y.ToString()]); } // 1, 0 if ((centerPixel.X + 1) < _pictureWidth) { temp.Add(_pixelMap[(centerPixel.X + 1).ToString() + "," + centerPixel.Y.ToString()]); } // -1, 1 if ((centerPixel.X - 1) >= 0 && (centerPixel.Y + 1) < _pictureHeight) { temp.Add(_pixelMap[(centerPixel.X - 1).ToString() + "," + (centerPixel.Y + 1).ToString()]); } // 0, 1 if ((centerPixel.Y + 1) < _pictureHeight) { temp.Add(_pixelMap[centerPixel.X.ToString() + "," + (centerPixel.Y + 1).ToString()]); } // 1, 1 if ((centerPixel.X + 1) < _pictureWidth && (centerPixel.Y + 1) < _pictureHeight) { temp.Add(_pixelMap[(centerPixel.X + 1).ToString() + "," + (centerPixel.Y + 1).ToString()]); } } else { /* * CP = Center pixel, N/A = not used * (X,Y) -- get only 4 connected | N/A |0,-1| N/A | |-1, 0| CP |+1, 0| | N/A |0,+1| N/A | */ // -1, 0 if ((centerPixel.X - 1) >= 0) { temp.Add(_pixelMap[(centerPixel.X - 1).ToString() + "," + centerPixel.Y.ToString()]); } // 0, -1 if ((centerPixel.Y - 1) >= 0) { temp.Add(_pixelMap[centerPixel.X.ToString() + "," + (centerPixel.Y - 1).ToString()]); } // 1, 0 if ((centerPixel.X + 1) < _pictureWidth) { temp.Add(_pixelMap[(centerPixel.X + 1).ToString() + "," + centerPixel.Y.ToString()]); } // 0, 1 if ((centerPixel.Y + 1) < _pictureHeight) { temp.Add(_pixelMap[centerPixel.X.ToString() + "," + (centerPixel.Y + 1).ToString()]); } } return(temp); }
private void Segment() { // Geodesic SKIZ (skeleton by influence zones) of each level height for (int h = 0; h < _heightSortedList.Count; h++) { // get all pixels for current height foreach (WatershedPixel heightSortedPixel in _heightSortedList[h]) { heightSortedPixel.Label = WatershedCommon.MASK; // for each pixel on current height get neighbouring pixels List <WatershedPixel> neighbouringPixels = GetNeighbouringPixels(heightSortedPixel); // initialize queue with neighbours at level h of current basins or watersheds foreach (WatershedPixel neighbouringPixel in neighbouringPixels) { if (neighbouringPixel.Label > 0 || neighbouringPixel.Label == WatershedCommon.WSHED) { heightSortedPixel.Distance = 1; _fifoQueue.AddToEnd(heightSortedPixel); break; } } } _currentDistance = 1; _fifoQueue.AddToEnd(FictitiousPixel); // extend basins while (true) { WatershedPixel p = _fifoQueue.RemoveAtFront(); if (p.Equals(FictitiousPixel)) { if (_fifoQueue.IsEmpty) { break; } else { _fifoQueue.AddToEnd(FictitiousPixel); _currentDistance++; p = _fifoQueue.RemoveAtFront(); } } List <WatershedPixel> neighbouringPixels = GetNeighbouringPixels(p); // labelling p by inspecting neighbours foreach (WatershedPixel neighbouringPixel in neighbouringPixels) { // neighbouringPixel belongs to an existing basin or to watersheds // in the original algorithm the condition is: // if (neighbouringPixel.Distance < currentDistance && // (neighbouringPixel.Label > 0 || neighbouringPixel.Label == WatershedCommon.WSHED)) // but this returns incomplete borders so the this one is used if (neighbouringPixel.Distance <= _currentDistance && (neighbouringPixel.Label > 0 || neighbouringPixel.Label == WatershedCommon.WSHED)) { if (neighbouringPixel.Label > 0) { // the commented condition is also in the original algorithm // but it also gives incomplete borders if (p.Label == WatershedCommon.MASK /*|| p.Label == WatershedCommon.WSHED*/) { p.Label = neighbouringPixel.Label; } else if (p.Label != neighbouringPixel.Label) { p.Label = WatershedCommon.WSHED; _watershedPixelCount++; } } else if (p.Label == WatershedCommon.MASK) { p.Label = WatershedCommon.WSHED; _watershedPixelCount++; } } // neighbouringPixel is plateau pixel else if (neighbouringPixel.Label == WatershedCommon.MASK && neighbouringPixel.Distance == 0) { neighbouringPixel.Distance = _currentDistance + 1; _fifoQueue.AddToEnd(neighbouringPixel); } } } // detect and process new minima at height level h foreach (WatershedPixel p in _heightSortedList[h]) { // reset distance to zero p.Distance = 0; // if true then p is inside a new minimum if (p.Label == WatershedCommon.MASK) { // create new label _currentLabel++; p.Label = _currentLabel; _fifoQueue.AddToEnd(p); while (!_fifoQueue.IsEmpty) { WatershedPixel q = _fifoQueue.RemoveAtFront(); // check neighbours of q List <WatershedPixel> neighbouringPixels = GetNeighbouringPixels(q); foreach (WatershedPixel neighbouringPixel in neighbouringPixels) { if (neighbouringPixel.Label == WatershedCommon.MASK) { neighbouringPixel.Label = _currentLabel; _fifoQueue.AddToEnd(neighbouringPixel); } } } } } } }