Use k-means instead of k-medians.
[master-thesis.git] / Parasitemia / Parasitemia / ImgTools.fs
index f567e68..5e32ccb 100644 (file)
@@ -36,11 +36,13 @@ let suppressMConnections (img: Matrix<byte>) =
     let h = img.Height
     for i in 1 .. h - 2 do
         for j in 1 .. w - 2 do
-            if img.[i, j] > 0uy && img.Data.[i + 1, j] > 0uy && (img.Data.[i, j - 1] > 0uy && img.Data.[i - 1, j + 1] = 0uy || img.Data.[i, j + 1] > 0uy && img.Data.[i - 1, j - 1] = 0uy) then
+            if img.[i, j] > 0uy && img.Data.[i + 1, j] > 0uy && (img.Data.[i, j - 1] > 0uy && img.Data.[i - 1, j + 1] = 0uy || img.Data.[i, j + 1] > 0uy && img.Data.[i - 1, j - 1] = 0uy)
+            then
                 img.[i, j] <- 0uy
     for i in 1 .. h - 2 do
         for j in 1 .. w - 2 do
-            if img.[i, j] > 0uy && img.Data.[i - 1, j] > 0uy && (img.Data.[i, j - 1] > 0uy && img.Data.[i + 1, j + 1] = 0uy || img.Data.[i, j + 1] > 0uy && img.Data.[i + 1, j - 1] = 0uy) then
+            if img.[i, j] > 0uy && img.Data.[i - 1, j] > 0uy && (img.Data.[i, j - 1] > 0uy && img.Data.[i + 1, j + 1] = 0uy || img.Data.[i, j + 1] > 0uy && img.Data.[i + 1, j - 1] = 0uy)
+            then
                 img.[i, j] <- 0uy
 
 let findEdges (img: Image<Gray, float32>) : Matrix<byte> * Image<Gray, float> * Image<Gray, float> =
@@ -109,7 +111,8 @@ let findEdges (img: Image<Gray, float32>) : Matrix<byte> * Image<Gray, float> *
                 else magnitudes.Data.[i - sign, j + sign]
 
             let m = magnitudes.Data.[i, j]
-            if m < mNeigbors 1 || m < mNeigbors -1 || m < thresholdLow then
+            if m < mNeigbors 1 || m < mNeigbors -1 || m < thresholdLow
+            then
                 nms.Data.[i, j] <- 0uy
 
     // suppressMConnections nms // It's not usefull for the rest of the process (ellipse detection).
@@ -120,7 +123,8 @@ let findEdges (img: Image<Gray, float32>) : Matrix<byte> * Image<Gray, float> *
     let toVisit = Stack<Point>()
     for i in 0 .. h - 1 do
         for j in 0 .. w - 1 do
-            if nms.Data.[i, j] = 1uy && magnitudes.Data.[i, j] >= thresholdHigh then
+            if nms.Data.[i, j] = 1uy && magnitudes.Data.[i, j] >= thresholdHigh
+            then
                 nms.Data.[i, j] <- 0uy
                 toVisit.Push(Point(j, i))
                 while toVisit.Count > 0 do
@@ -128,10 +132,12 @@ let findEdges (img: Image<Gray, float32>) : Matrix<byte> * Image<Gray, float> *
                     edges.Data.[p.Y, p.X] <- 1uy
                     for i' in -1 .. 1  do
                         for j' in -1 .. 1 do
-                            if i' <> 0 || j' <> 0 then
+                            if i' <> 0 || j' <> 0
+                            then
                                 let ni = p.Y + i'
                                 let nj = p.X + j'
-                                if ni >= 0 && ni < h && nj >= 0 && nj < w && nms.Data.[ni, nj] = 1uy then
+                                if ni >= 0 && ni < h && nj >= 0 && nj < w && nms.Data.[ni, nj] = 1uy
+                                then
                                     nms.Data.[ni, nj] <- 0uy
                                     toVisit.Push(Point(nj, ni))
 
@@ -580,12 +586,6 @@ let thin (mat: Matrix<byte>) =
         data2 <- tmp
 
 
-// FIXME: replace by a queue or stack.
-let pop (l: List<'a>) : 'a =
-    let n = l.[l.Count - 1]
-    l.RemoveAt(l.Count - 1)
-    n
-
 // Remove all 8-connected pixels with an area equal or greater than 'areaSize'.
 // Modify 'mat' in place.
 let removeArea (mat: Matrix<byte>) (areaSize: int) =
@@ -611,37 +611,37 @@ let removeArea (mat: Matrix<byte>) (areaSize: int) =
         for j in 0..w-1 do
             if data'.[i, j] = 1uy
             then
-                let neighborhood = List<(int*int)>()
-                let neighborsToCheck = List<(int*int)>()
-                neighborsToCheck.Add((i, j))
+                let neighborhood = List<Point>()
+                let neighborsToCheck = Stack<Point>()
+                neighborsToCheck.Push(Point(j, i))
                 data'.[i, j] <- 0uy
 
                 while neighborsToCheck.Count > 0 do
-                    let (ci, cj) = pop neighborsToCheck
-                    neighborhood.Add((ci, cj))
+                    let n = neighborsToCheck.Pop()
+                    neighborhood.Add(n)
                     for (ni, nj) in neighbors do
-                        let pi = ci + ni
-                        let pj = cj + nj
+                        let pi = n.Y + ni
+                        let pj = n.X + nj
                         if pi >= 0 && pi < h && pj >= 0 && pj < w && data'.[pi, pj] = 1uy
                         then
-                            neighborsToCheck.Add((pi, pj))
+                            neighborsToCheck.Push(Point(pj, pi))
                             data'.[pi, pj] <- 0uy
                 if neighborhood.Count <= areaSize
                 then
-                    for (ni, nj) in neighborhood do
-                        data.[ni, nj] <- 0uy
+                    for n in neighborhood do
+                        data.[n.Y, n.X] <- 0uy
 
 let connectedComponents (img: Image<Gray, byte>) (startPoints: List<Point>) : List<Point> =
     let w = img.Width
     let h = img.Height
 
     let pointChecked = Points()
-    let pointToCheck = List<Point>(startPoints);
+    let pointToCheck = Stack<Point>(startPoints);
 
     let data = img.Data
 
     while pointToCheck.Count > 0 do
-        let next = pop pointToCheck
+        let next = pointToCheck.Pop()
         pointChecked.Add(next) |> ignore
         for ny in -1 .. 1 do
             for nx in -1 .. 1 do
@@ -650,7 +650,7 @@ let connectedComponents (img: Image<Gray, byte>) (startPoints: List<Point>) : Li
                     let p = Point(next.X + nx, next.Y + ny)
                     if p.X >= 0 && p.X < w && p.Y >= 0 && p.Y < h && data.[p.Y, p.X, 0] > 0uy && not (pointChecked.Contains p)
                     then
-                        pointToCheck.Add(p)
+                        pointToCheck.Push(p)
 
     List<Point>(pointChecked)