-// A simpler algorithm than 'areaOpen' but slower.
-let areaOpen2 (img: Image<Gray, byte>) (area: int) =
- let w = img.Width
- let h = img.Height
- let imgData = img.Data
- let se = [| -1, 0; 0, -1; 1, 0; 0, 1 |]
-
- let histogram = Array.zeroCreate 256
- for i in 0 .. h - 1 do
- for j in 0 .. w - 1 do
- let v = imgData.[i, j, 0] |> int
- histogram.[v] <- histogram.[v] + 1
-
- let flooded : bool[,] = Array2D.zeroCreate h w
-
- let pointsChecked = HashSet<Point>()
- let pointsToCheck = Stack<Point>()
-
- for level in 255 .. -1 .. 0 do
- let mutable n = histogram.[level]
- if n > 0
- then
- for i in 0 .. h - 1 do
- for j in 0 .. w - 1 do
- if not flooded.[i, j] && imgData.[i, j, 0] = byte level
- then
- let mutable maxNeighborValue = 0uy
- pointsChecked.Clear()
- pointsToCheck.Clear()
- pointsToCheck.Push(Point(j, i))
-
- while pointsToCheck.Count > 0 do
- let next = pointsToCheck.Pop()
- pointsChecked.Add(next) |> ignore
- flooded.[next.Y, next.X] <- true
-
- for nx, ny in se do
- let p = Point(next.X + nx, next.Y + ny)
- if p.X >= 0 && p.X < w && p.Y >= 0 && p.Y < h
- then
- let v = imgData.[p.Y, p.X, 0]
- if v = byte level
- then
- if not (pointsChecked.Contains(p))
- then
- pointsToCheck.Push(p)
- elif v > maxNeighborValue
- then
- maxNeighborValue <- v
-
- if int maxNeighborValue < level && pointsChecked.Count <= area
- then
- for p in pointsChecked do
- imgData.[p.Y, p.X, 0] <- maxNeighborValue
-
-// Zhang and Suen algorithm.
-// Modify 'mat' in place.