From 8013d6a586604e443332e6e9a715c86df444a875 Mon Sep 17 00:00:00 2001 From: Greg Burri Date: Mon, 11 Jan 2016 18:01:39 +0100 Subject: [PATCH] * Add the possibility to set an RBC as healthy or infected --- Parasitemia/Parasitemia/Classifier.fs | 1 + Parasitemia/Parasitemia/GUI/GUI.fs | 190 +++++++++++++++--- Parasitemia/Parasitemia/GUI/MainWindow.xaml | 15 +- Parasitemia/Parasitemia/GUI/PiaZ.fs | 4 +- Parasitemia/Parasitemia/GUI/RBCFrame.xaml | 21 ++ Parasitemia/Parasitemia/GUI/RBCFrame.xaml.fs | 11 + Parasitemia/Parasitemia/GUI/State.fs | 25 ++- Parasitemia/Parasitemia/GUI/Types.fs | 11 +- Parasitemia/Parasitemia/Parasitemia.fsproj | 3 + .../Parasitemia/Resources/logo_256.png | Bin 0 -> 34510 bytes Parasitemia/Parasitemia/Types.fs | 1 + 11 files changed, 239 insertions(+), 43 deletions(-) create mode 100644 Parasitemia/Parasitemia/GUI/RBCFrame.xaml create mode 100644 Parasitemia/Parasitemia/GUI/RBCFrame.xaml.fs create mode 100644 Parasitemia/Parasitemia/Resources/logo_256.png diff --git a/Parasitemia/Parasitemia/Classifier.fs b/Parasitemia/Parasitemia/Classifier.fs index 3a679e7..1a22129 100644 --- a/Parasitemia/Parasitemia/Classifier.fs +++ b/Parasitemia/Parasitemia/Classifier.fs @@ -229,5 +229,6 @@ let findCells (ellipses: Ellipse list) (parasites: ParasitesMarker.Result) (img: Some { cellClass = cellClass center = Point(roundInt e.Cx, roundInt e.Cy) + infectedArea = infectedPixels.Count stainArea = stainPixels elements = elements }) diff --git a/Parasitemia/Parasitemia/GUI/GUI.fs b/Parasitemia/Parasitemia/GUI/GUI.fs index 2aadefe..8aef251 100644 --- a/Parasitemia/Parasitemia/GUI/GUI.fs +++ b/Parasitemia/Parasitemia/GUI/GUI.fs @@ -27,6 +27,7 @@ let run (defaultConfig: Config) = let colorRBCInfected = Brushes.Red let state = State.State() + let mutable currentScale = 1. let exit: MenuItem = ctrl "menuExit" let saveFile: MenuItem = ctrl "menuSave" @@ -35,15 +36,157 @@ let run (defaultConfig: Config) = let addSourceImage: MenuItem = ctrl "menuAddSourceImage" let txtPatient: TextBox = ctrl "txtPatient" - let stackPreviews: StackPanel = ctrl "stackPreviews" + let txtGlobalParasitemia: TextBox = ctrl "txtGlobalParasitemia" + let butStartAnalysis: Button = ctrl "butStartAnalysis" + let stackPreviews: StackPanel = ctrl "stackPreviews" + let scrollViewCurrentImage: ScrollViewer = ctrl "scrollViewCurrentImage" let borderCurrentImage: Border = ctrl "borderCurrentImage" let canvasCurrentImage: Canvas = ctrl "canvasCurrentImage" + let txtImageInformation: TextBlock = ctrl "txtImageInformation" + + let scrollRBC: ScrollViewer = ctrl "scrollRBC" + let stackRBC: StackPanel = ctrl "stackRBC" // Initializations. + // Utils. + let extractRBCPreview (img: Emgu.CV.Image) (rbc: RBC) : Emgu.CV.Image = + let rbcWidth = rbc.size.Width + let rbcHeight = rbc.size.Height + img.GetSubRect(System.Drawing.Rectangle(System.Drawing.Point(rbc.center.X - rbcWidth / 2. |> Utils.roundInt, rbc.center.Y - rbcHeight / 2. |> Utils.roundInt), + System.Drawing.Size(Utils.roundInt rbcWidth, Utils.roundInt rbcHeight))) + + let setRBCFrameStyle (rbc: RBC) (frame: Views.RBCFrame) = + frame.Opacity <- if rbc.setManually || rbc.infected then 1. else 0. + let color = if rbc.infected then colorRBCInfected else colorRBCHealthy + frame.manuallyAdded.Visibility <- if rbc.setManually then Visibility.Visible else Visibility.Hidden + frame.manuallyAdded.Fill <- color + frame.border.Stroke <- color + + let RBCFrameFromExisting (rbc: RBC) (frame: Views.RBCFrame) : Views.RBCFrame = + frame.Visibility <- Visibility.Visible + frame.Height <- rbc.size.Height + frame.Width <- rbc.size.Width + frame.Tag <- rbc + setRBCFrameStyle rbc frame + frame.border.StrokeThickness <- 1. + frame.lblRBCNumber.Content <- rbc.num + frame + + let highlightRBCFrame (frame: Views.RBCFrame) (highlight: bool) = + let rbc = frame.Tag :?> RBC + if highlight + then + frame.border.StrokeThickness <- 3. + if not rbc.infected && not rbc.setManually then frame.Opacity <- 1. + else + frame.border.StrokeThickness <- 1. + if not rbc.infected && not rbc.setManually then frame.Opacity <- 0. + + let zoomToRBC (rbc: RBC) = + scrollViewCurrentImage.ScrollToHorizontalOffset(rbc.center.X * currentScale - scrollViewCurrentImage.ViewportWidth / 2. + borderCurrentImage.BorderThickness.Left) + scrollViewCurrentImage.ScrollToVerticalOffset(rbc.center.Y * currentScale - scrollViewCurrentImage.ViewportHeight / 2. + borderCurrentImage.BorderThickness.Top) + + let parasitemiaText (nbTotal: int, nbInfected: int) : string = + if nbTotal = 0 + then + "" + else + let percent = 100. * (float nbInfected) / (float nbTotal) + sprintf "%.2f %% (%d / %d)" percent nbInfected nbTotal + + let updateCurrentImageInformation () = + match state.CurrentImage with + | Some srcImg -> + let parasitemiaStr = parasitemiaText (state.ImageParasitemia srcImg) + txtImageInformation.Text <- sprintf "Parasitemia: %s" parasitemiaStr + | _ -> () + + let updateGlobalParasitemia () = + txtGlobalParasitemia.Text <- parasitemiaText state.GlobalParasitemia + + let rec setAsInfected (rbc: RBC) (infected: bool) = + rbc.SetAsInfected infected + canvasCurrentImage.Children + |> Seq.cast + |> Seq.iter + (fun frame -> + if (frame.Tag :?> RBC) = rbc + then + setRBCFrameStyle rbc frame) + updateRBCFramesPreview () + updateCurrentImageInformation () + updateGlobalParasitemia () + + and RBCFrame (rbc: RBC) : Views.RBCFrame = + let f = RBCFrameFromExisting rbc (Views.RBCFrame()) + f.menuRBCSetAsHealthy.Click.AddHandler(fun obj args -> setAsInfected (f.Tag :?> RBC) false) + f.menuRBCSetAsInfected.Click.AddHandler(fun obj args -> setAsInfected (f.Tag :?> RBC) true) + f.ContextMenuOpening.AddHandler( + fun obj args -> + if (f.Tag :?> RBC).infected + then + f.menuRBCSetAsHealthy.Visibility <- Visibility.Visible + f.menuRBCSetAsInfected.Visibility <- Visibility.Collapsed + else + f.menuRBCSetAsHealthy.Visibility <- Visibility.Collapsed + f.menuRBCSetAsInfected.Visibility <- Visibility.Visible) + + f.ContextMenuClosing.AddHandler(fun obj args -> if not f.IsMouseOver then highlightRBCFrame f false ) + f.MouseEnter.AddHandler(fun obj args -> highlightRBCFrame f true) + f.MouseLeave.AddHandler(fun obj args -> if not f.grid.ContextMenu.IsOpen then highlightRBCFrame f false) + f + + and updateRBCFramesPreview () = + match state.CurrentImage with + | Some srcImg -> + let mutable currentPreview = 0 + for rbc in srcImg.rbcs |> List.filter (fun rbc -> rbc.infected) do + let previewInfected = + if currentPreview < stackRBC.Children.Count + then + RBCFrameFromExisting rbc (stackRBC.Children.[currentPreview] :?> Views.RBCFrame) + else + let f = RBCFrame rbc + f.MouseLeftButtonUp.AddHandler(fun obj args -> zoomToRBC ((obj :?> Views.RBCFrame).Tag :?> RBC)) + stackRBC.Children.Add(f) |> ignore + f + + currentPreview <- currentPreview + 1 + + previewInfected.Height <- stackRBC.ActualHeight + previewInfected.Width <- stackRBC.ActualHeight * rbc.size.Width / rbc.size.Height + previewInfected.border.Fill <- ImageBrush(BitmapSourceConvert.ToBitmapSource(extractRBCPreview srcImg.img rbc)) + + stackRBC.Children.RemoveRange(currentPreview, stackRBC.Children.Count - currentPreview) + | _ -> () + + let updateRBCFramesCurrent () = + match state.CurrentImage with + | Some srcImg -> + let mutable currentCanvas = 0 + for rbc in srcImg.rbcs do + let frame = + if currentCanvas < canvasCurrentImage.Children.Count + then + RBCFrameFromExisting rbc (canvasCurrentImage.Children.[currentCanvas] :?> Views.RBCFrame) + else + let f = RBCFrame rbc + canvasCurrentImage.Children.Add(f) |> ignore + f + + currentCanvas <- currentCanvas + 1 + + Canvas.SetLeft(frame, rbc.center.X - rbc.size.Width / 2.) + Canvas.SetTop(frame, rbc.center.Y - rbc.size.Height / 2.) + + for i in currentCanvas .. canvasCurrentImage.Children.Count - 1 do + canvasCurrentImage.Children.[i].Visibility <- Visibility.Hidden + | _ -> () + // Operations. let synchronizeState () = state.PatientID <- txtPatient.Text @@ -60,33 +203,10 @@ let run (defaultConfig: Config) = canvasCurrentImage.Width <- float srcImg.img.Width canvasCurrentImage.Background <- ImageBrush(BitmapSourceConvert.ToBitmapSource(srcImg.img)) - // Remove all image canvas children and add the RBC. - canvasCurrentImage.Children.Clear() - for rbc in srcImg.rbcs do - let rectangle = - Rectangle( - Height = rbc.size.Height, - Width = rbc.size.Width, - Stroke = (if rbc.infected then colorRBCInfected else colorRBCHealthy), - StrokeThickness = 1., - Fill = SolidColorBrush(Color.FromArgb(0uy, 0uy, 0uy, 0uy)), - Tag = rbc, - Opacity = if rbc.infected then 1. else 0.) - Canvas.SetLeft(rectangle, rbc.center.X - rbc.size.Width / 2.) - Canvas.SetTop(rectangle, rbc.center.Y - rbc.size.Height / 2.) - canvasCurrentImage.Children.Add(rectangle) |> ignore - rectangle.MouseEnter.AddHandler( - fun obj args -> match obj with - | :? Rectangle as r -> - r.StrokeThickness <- 3. - if not (r.Tag :?> RBC).infected then r.Opacity <- 1. - | _ -> ()) - rectangle.MouseLeave.AddHandler( - fun obj args -> match obj with - | :? Rectangle as r -> - r.StrokeThickness <- 1. - if not (r.Tag :?> RBC).infected then r.Opacity <- 0. - | _ -> ()) + updateRBCFramesCurrent () + updateRBCFramesPreview () + updateCurrentImageInformation () + let addPreview (srcImg: SourceImage) = let imgCtrl = Views.ImageSourcePreview(Margin = Thickness(3.)) @@ -103,11 +223,14 @@ let run (defaultConfig: Config) = then for srcImg in state.SourceImages do addPreview srcImg - setCurrentImage (state.SourceImages.First()) + match state.CurrentImage with + | Some srcImg -> setCurrentImage srcImg + | _ -> () let updateGUI () = txtPatient.Text <- state.PatientID updatePreviews () + updateGlobalParasitemia () exit.Click.AddHandler(fun obj args -> mainWindow.Root.Close()) saveFile.Click.AddHandler(fun obj args -> @@ -145,6 +268,7 @@ let run (defaultConfig: Config) = then let srcImg = state.AddSourceImage(dialog.FileName) addPreview srcImg + updateGlobalParasitemia () if state.SourceImages.Count() = 1 then setCurrentImage srcImg) @@ -153,7 +277,12 @@ let run (defaultConfig: Config) = let results = ImageAnalysis.doMultipleAnalysis (state.SourceImages |> Seq.map (fun srcImg -> string srcImg.num, srcImg.img) |> Seq.toList) defaultConfig for id, cells in results do state.SetResult (int id) cells - ) + updateGlobalParasitemia () + + // Refresh current image. + match state.CurrentImage with + | Some srcImg -> setCurrentImage srcImg + | _ -> ()) // Zoom on the current image. let adjustCurrentImageBorders (deltaX: float) (deltaY: float) = @@ -182,7 +311,6 @@ let run (defaultConfig: Config) = scrollViewCurrentImage.ScrollToHorizontalOffset(scrollViewCurrentImage.HorizontalOffset + deltaX / 8.) scrollViewCurrentImage.ScrollToVerticalOffset(scrollViewCurrentImage.VerticalOffset + deltaY / 8.)) - let mutable currentScale = 1. let mutable maxScale = 4. let mutable minScale = 0.25 let currentImageScaleTransform = ScaleTransform() diff --git a/Parasitemia/Parasitemia/GUI/MainWindow.xaml b/Parasitemia/Parasitemia/GUI/MainWindow.xaml index 281493b..9aecf1b 100644 --- a/Parasitemia/Parasitemia/GUI/MainWindow.xaml +++ b/Parasitemia/Parasitemia/GUI/MainWindow.xaml @@ -1,5 +1,9 @@  + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + mc:Ignorable="d" + x:Name="MainWindow" Height="681.888" Width="787.61" MinHeight="200" MinWidth="300" Title="Parasitemia" Icon="pack://application:,,,/Resources/logo_256.png"> @@ -13,7 +17,6 @@ - @@ -32,7 +35,7 @@ - diff --git a/Parasitemia/Parasitemia/GUI/PiaZ.fs b/Parasitemia/Parasitemia/GUI/PiaZ.fs index 900ec65..a373e53 100644 --- a/Parasitemia/Parasitemia/GUI/PiaZ.fs +++ b/Parasitemia/Parasitemia/GUI/PiaZ.fs @@ -71,7 +71,7 @@ let save (filePath: string) (data: FileData) = rbc.num, rbc.infected, rbc.setManually, decimal rbc.center.X, decimal rbc.center.Y, decimal rbc.size.Width, decimal rbc.size.Height, - rbc.stainArea) |]) + rbc.infectedArea) |]) let imgJSONEntry = file.CreateEntry(imgFilename + ".json", CompressionLevel.Fastest) use imgJSONFileWriter = new StreamWriter(imgJSONEntry.Open()) @@ -98,5 +98,5 @@ let load (filePath: string) : FileData = { num = rbc.Num; infected = rbc.Infected; setManually = rbc.SetManually; center = Point(float rbc.PosX, float rbc.PosY); size = Size(float rbc.Width, float rbc.Height); - stainArea = rbc.StainArea } ] } ] + infectedArea = rbc.StainArea } ] } ] { sources = sources; patientID = mainJSON.PatientId } \ No newline at end of file diff --git a/Parasitemia/Parasitemia/GUI/RBCFrame.xaml b/Parasitemia/Parasitemia/GUI/RBCFrame.xaml new file mode 100644 index 0000000..2a56b00 --- /dev/null +++ b/Parasitemia/Parasitemia/GUI/RBCFrame.xaml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/Parasitemia/Parasitemia/GUI/RBCFrame.xaml.fs b/Parasitemia/Parasitemia/GUI/RBCFrame.xaml.fs new file mode 100644 index 0000000..1ef4d31 --- /dev/null +++ b/Parasitemia/Parasitemia/GUI/RBCFrame.xaml.fs @@ -0,0 +1,11 @@ +namespace Parasitemia.GUI.Views + +open System +open System.Windows +open System.Windows.Data +open System.Windows.Input + +open FSharp.ViewModule +open FsXaml + +type RBCFrame = XAML<"GUI/RBCFrame.xaml", true> diff --git a/Parasitemia/Parasitemia/GUI/State.fs b/Parasitemia/Parasitemia/GUI/State.fs index a1ae052..44de2e3 100644 --- a/Parasitemia/Parasitemia/GUI/State.fs +++ b/Parasitemia/Parasitemia/GUI/State.fs @@ -15,6 +15,16 @@ type State () = member val FilePath: string = "" with get, set member val PatientID: string = "" with get, set + member this.ImageParasitemia (srcImg: SourceImage) : int * int = + List.length srcImg.rbcs, + srcImg.rbcs |> List.fold (fun nbInfected rbc -> if rbc.infected then nbInfected + 1 else nbInfected) 0 + + member this.GlobalParasitemia : int * int = + sourceImages + |> Seq.fold (fun (nbTotal, nbTotalInfected) srcImg -> + let nb, nbInfected = this.ImageParasitemia srcImg + nbTotal + nb, nbTotalInfected + nbInfected) (0, 0) + member this.Save () = let data = { PiaZ.sources = List.ofSeq sourceImages; PiaZ.patientID = this.PatientID } PiaZ.save this.FilePath data @@ -24,23 +34,30 @@ type State () = this.PatientID <- data.patientID sourceImages.Clear() sourceImages.InsertRange(0, data.sources) + if sourceImages.Count > 0 + then this.CurrentImage <- Some sourceImages.[0] member this.AddSourceImage (filePath: string) : SourceImage = let srcImg = { num = sourceImages.Count + 1; rbcs = []; img = new Image(filePath) } sourceImages.Add(srcImg) + if sourceImages.Count = 1 + then this.CurrentImage <- Some sourceImages.[0] srcImg - member this.SetResult (num: int) (cells: Cell list) = - let sourceImage = sourceImages.Find(fun srcImg -> srcImg.num = num) + member this.SetResult (imgNum: int) (cells: Cell list) = + let sourceImage = sourceImages.Find(fun srcImg -> srcImg.num = imgNum) + let w = sourceImage.img.Width + let h = sourceImage.img.Height sourceImage.rbcs <- cells |> List.filter (fun cell -> match cell.cellClass with HealthyRBC | InfectedRBC -> true | _ -> false ) + |> List.sortByDescending (fun cell -> cell.infectedArea, (w - cell.center.X) + (h - cell.center.Y)) |> List.mapi (fun i cell -> - { num = i + { num = i + 1 infected = cell.cellClass = InfectedRBC setManually = false center = Point(float cell.center.X, float cell.center.Y) size = Size(float cell.elements.Width, float cell.elements.Height) - stainArea = cell.stainArea }) + infectedArea = cell.infectedArea }) member this.SourceImages : SourceImage seq = sourceImages :> SourceImage seq diff --git a/Parasitemia/Parasitemia/GUI/Types.fs b/Parasitemia/Parasitemia/GUI/Types.fs index e912ad3..6e00586 100644 --- a/Parasitemia/Parasitemia/GUI/Types.fs +++ b/Parasitemia/Parasitemia/GUI/Types.fs @@ -8,12 +8,17 @@ open Emgu.CV.Structure type RBC = { num: int - infected: bool - setManually: bool + mutable infected: bool + mutable setManually: bool center: Point size: Size - stainArea: int } + infectedArea: int } with + member this.SetAsInfected (infected: bool) = + if infected <> this.infected + then + this.infected <- infected + this.setManually <- not this.setManually type SourceImage = { num: int diff --git a/Parasitemia/Parasitemia/Parasitemia.fsproj b/Parasitemia/Parasitemia/Parasitemia.fsproj index d3289c6..b3a7e59 100644 --- a/Parasitemia/Parasitemia/Parasitemia.fsproj +++ b/Parasitemia/Parasitemia/Parasitemia.fsproj @@ -94,6 +94,8 @@ + + @@ -103,6 +105,7 @@ + diff --git a/Parasitemia/Parasitemia/Resources/logo_256.png b/Parasitemia/Parasitemia/Resources/logo_256.png new file mode 100644 index 0000000000000000000000000000000000000000..857a793d6826dc34053d8c34f03a0dbc781803a1 GIT binary patch literal 34510 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 Y|C|1W&L?JfTmS$707*qoM6N<$g0QP`&j0`b literal 0 HcmV?d00001 diff --git a/Parasitemia/Parasitemia/Types.fs b/Parasitemia/Parasitemia/Types.fs index 872844b..5275b3a 100644 --- a/Parasitemia/Parasitemia/Types.fs +++ b/Parasitemia/Parasitemia/Types.fs @@ -48,6 +48,7 @@ type CellClass = HealthyRBC | InfectedRBC | Peculiar type Cell = { cellClass: CellClass center: Point + infectedArea: int stainArea: int elements: Matrix } -- 2.43.0