129e6a6bae522b0e7d3af94893b9669ea8364254
1
module ParasitemiaUI.State
4 open System.Collections.Generic
12 type State (defaultConfig
: ParasitemiaCore.Config.Config) =
13 let sourceImages = List<SourceImage> ()
14 let mutable alteredSinceLastSave = false
15 let mutable patientID = ""
17 member this
.AlteredSinceLastSave = alteredSinceLastSave
18 member val CurrentImage : SourceImage option = None with get
, set
19 member val FilePath : string = "" with get
, set
22 with get
() : string = patientID
24 if id <> patientID then
25 alteredSinceLastSave <- true
28 member this
.GlobalParasitemia : int * int =
31 fun (nbTotal
, nbTotalInfected
) srcImg
->
32 let nb, nbInfected
= srcImg
.ImageParasitemia
33 nbTotal
+ nb, nbTotalInfected
+ nbInfected
36 member this
.SetAsInfected (rbc
: RBC) (infected
: bool) =
37 if infected
<> rbc
.infected
then
38 alteredSinceLastSave <- true
39 rbc
.infected
<- infected
40 rbc
.setManually
<- not
rbc.setManually
43 /// Save the current state. 'FilePath' must have been defined.
45 /// <exception cref="System.IOException">If the file cannot be saved</exception>
47 let data = { PiaZ.DocumentData.patientID = this
.PatientID; PiaZ.DocumentData.images
= List.ofSeq
sourceImages }
48 PiaZ.save
this.FilePath data
49 alteredSinceLastSave <- false
52 /// Load the current state. 'FilePath' must have been defined.
54 /// <exception cref="System.IOException">If the file cannot be loaded</exception>
56 let data = PiaZ.load
this.FilePath defaultConfig
57 this.PatientID <- data.patientID
59 sourceImages.InsertRange (0, data.images
)
60 this.CurrentImage <- if sourceImages.Count > 0 then Some sourceImages.[0] else None
61 alteredSinceLastSave <- false
65 /// <exception cref="System.IOException">If the image cannot be read</exception>
66 member this.AddSourceImage (filePath
: string) (defaultConfig
: ParasitemiaCore.Config.Config) : SourceImage =
67 let srcImg = SourceImage (sourceImages.Count + 1, System.IO.FileInfo(filePath
).Name, defaultConfig
.Copy (), DateTime (0L), new Image<Bgr, byte
> (filePath
), [])
68 sourceImages.Add srcImg
69 if sourceImages.Count = 1 then
70 this.CurrentImage <- Some sourceImages.[0]
71 alteredSinceLastSave <- true
74 member this.RemoveSourceImage (srcImg : SourceImage) =
76 match this.CurrentImage with
77 | Some srcImg' -> srcImg = srcImg'
80 if sourceImages.Remove srcImg then
81 alteredSinceLastSave <- true
83 this.CurrentImage <- if sourceImages.Count > 0 then Some sourceImages.[0] else None
84 // Re-numbered the images.
85 sourceImages |> Seq.iteri
(fun i
srcImg -> srcImg.Num <- i
+ 1)
87 member this.SetName (srcImg : SourceImage) (name
: string) =
88 if name
<> srcImg.Name then
90 alteredSinceLastSave <- true
92 member this.SetResult (imgNum
: int) (result
: ParasitemiaCore.Types.AnalysisResult) =
93 let sourceImage = sourceImages.Find (fun srcImg -> srcImg.Num = imgNum
)
95 let w = sourceImage.Img.Width
96 let h = sourceImage.Img.Height
98 sourceImage.DateLastAnalysis <- DateTime.UtcNow
100 // To match with previously manually altered RBC.
101 let manuallyAlteredPreviousRBCS = sourceImage.RBCs |> List.filter
(fun rbc -> rbc.setManually
)
102 let tolerance = (float sourceImage.Config.RBCRadius.Pixel) * 0.5 // +/-.
103 let getPreviousManuallyAlteredRBC (center
: Point) : RBC option =
104 manuallyAlteredPreviousRBCS
107 rbc.center
.X > center
.X - tolerance &&
108 rbc.center
.X < center
.X + tolerance &&
109 rbc.center
.Y > center
.Y - tolerance &&
110 rbc.center
.Y < center
.Y + tolerance
115 |> List.filter
(fun cell
-> match cell
.cellClass
with ParasitemiaCore.Types.HealthyRBC | ParasitemiaCore.Types.InfectedRBC -> true | _ -> false )
116 |> List.sortByDescending
(fun cell
-> cell
.nucleusArea
, (w - cell
.center
.X) + (h - cell
.center
.Y))
119 let center = Point (float cell.center.X, float cell.center.Y)
120 let infected, setManually
=
121 let infected = cell.cellClass
= ParasitemiaCore.Types.InfectedRBC
122 match getPreviousManuallyAlteredRBC center with
123 | Some rbc when rbc.infected <> infected -> rbc.infected, true // If it has been previously manually changed and now match the result, the manually flag is removed.
124 | _ -> infected, false
128 setManually
= setManually
130 size
= Size (float cell.elements
.Width, float cell.elements
.Height)
131 infectedArea
= cell.nucleusArea
135 alteredSinceLastSave <- true
137 member this.SourceImages : SourceImage seq =
138 sourceImages :> SourceImage seq
140 member this.Reset () =
143 this.CurrentImage <- None
144 sourceImages.Clear ()
145 alteredSinceLastSave <- false