- // 1) Remove ellipses touching the edges.
- let ellipsesInside = ellipses |> List.map (fun e ->
- EllipseFlaggedKd (e, Removed = e.isOutside (float fg.Width) (float fg.Height)))
-
- // 2) Associate touching ellipses with each ellipses.
- let tree = KdTree.Tree.BuildTree ellipsesInside
- let neighbors (e: Ellipse) : (EllipseFlaggedKd * PointD * PointD) list =
- tree.Search (searchRegion e)
- // We only keep the ellipses touching 'e'.
- |> List.choose (fun otherE ->
- match EEOver.EEOverlapArea e otherE with
- | Some (area, px, py) when area > 0.0 && px.Length >= 2 && py.Length >= 2 ->
- Some (otherE, PointD(px.[0], py.[0]), PointD(px.[1], py.[1]))
- | _ ->
- None )
-
- let ellipsesWithNeigbors = ellipsesInside |> List.choose (fun e -> if e.Removed then None else Some (e, neighbors e))
-
- // 3) Remove ellipse with a lower percentage of foreground.
- let fgData = fg.Data
- for e, neighbors in ellipsesWithNeigbors do
- let minX, minY, maxX, maxY = ellipseWindow e
-
- let mutable totalElement = 0
- let mutable fgElement = 0
-
- for y in minY .. maxY do
- for x in minX .. maxX do
- let yf, xf = float y, float x
- if e.Contains xf yf && neighbors |> List.forall (fun (otherE, _, _) -> not <| otherE.Contains xf yf)
- then
- totalElement <- totalElement + 1
- if fgData.[y, x, 0] > 0uy
- then
- fgElement <- fgElement + 1
-
- if totalElement < config.minimumCellArea || (float fgElement) / (float totalElement) < config.percentageOfFgValidCell
- then
- e.Removed <- true
-
- // 3) Define pixels associated to each ellipse and create the cells.