c6e639069bde08c813f76c3eb525e31ab690430f
1
module Parasitemia.GUI.Main
6 open System.Windows.Media
7 open System.Windows.Markup
8 open System.Windows.Shapes
9 open System.Windows.Controls
10 open System.Diagnostics
11 open Microsoft.Win32 // For the common dialogs.
14 //open Emgu.CV.Structure
20 let run (defaultConfig
: Config) =
21 let app = new Application()
22 let mainWindow = Views.MainWindow()
23 let ctrl (name
: string): 'a =
24 mainWindow.Root.FindName(name) :?> 'a
26 // Utils.log <- (fun m -> log mainWindow m)
28 let colorRBCHealthy = Brushes.Green
29 let colorRBCInfected = Brushes.Yellow
31 let state = State.State()
33 let exit: MenuItem = ctrl "menuExit"
34 let saveFile: MenuItem = ctrl "menuSave"
35 let loadFile: MenuItem = ctrl "menuOpen"
36 let newFile: MenuItem = ctrl "menuNew"
38 let addSourceImage: MenuItem = ctrl "menuAddSourceImage"
39 let txtPatient: TextBox = ctrl "txtPatient"
40 let stackPreviews: StackPanel = ctrl "stackPreviews"
41 let butStartAnalysis: Button = ctrl "butStartAnalysis"
43 let scrollViewCurrentImage: ScrollViewer = ctrl "scrollViewCurrentImage"
44 let borderCurrentImage: Border = ctrl "borderCurrentImage"
45 let canvasCurrentImage: Canvas = ctrl "canvasCurrentImage"
50 let synchronizeState () =
51 state.PatientID <- txtPatient.Text
53 let setCurrentImage (srcImg
: SourceImage) =
54 canvasCurrentImage.Height <- float srcImg.img
.Height
55 canvasCurrentImage.Width <- float srcImg.img
.Width
56 canvasCurrentImage.Background <- ImageBrush(BitmapSourceConvert.ToBitmapSource(srcImg.img
))
58 // Remove all image canvas children and add the RBC.
59 canvasCurrentImage.Children.Clear()
60 for rbc
in (*srcImg.rbcs*) [{ num
= 1; infected
= true; addedManually
= false; removed
= false; center
= Point(100., 100.); size
= Size(40., 40.); stainArea
= 10 }] do
63 Height = rbc
.size
.Height,
64 Width = rbc
.size
.Width,
65 Stroke = (if rbc
.infected
then colorRBCInfected else colorRBCHealthy),
67 Canvas.SetLeft(rectangle, rbc
.center
.X + rbc
.size
.Width / 2.)
68 Canvas.SetTop(rectangle, rbc
.center
.Y + rbc
.size
.Height / 2.)
69 canvasCurrentImage.Children.Add(rectangle) |> ignore
71 let addPreview (srcImg: SourceImage) =
72 let imgCtrl = Views.ImageSourcePreview(Margin = Thickness(3.))
73 imgCtrl.lblImageNumber
.Content <- srcImg.num
75 let height = srcImg.img
.Height * width / srcImg.img
.Width
76 imgCtrl.imagePreview
.Source <- BitmapSourceConvert.ToBitmapSource(srcImg.img
.Resize(width, height, Emgu.CV.CvEnum.Inter.Cubic))
77 stackPreviews.Children.Add(imgCtrl) |> ignore
79 let updatePreviews () =
80 stackPreviews.Children.Clear ()
81 if state.SourceImages.Count() > 0
83 for srcImg in state.SourceImages do
85 setCurrentImage (state.SourceImages.First())
88 txtPatient.Text <- state.PatientID
91 exit.Click.AddHandler(fun obj args
-> mainWindow.Root.Close())
92 saveFile.Click.AddHandler(fun obj args
->
94 if state.FilePath = ""
96 let dialog = SaveFileDialog(AddExtension = true, DefaultExt = Pia.extension
, Filter = Pia.filter
);
97 let res = dialog.ShowDialog()
98 if res.HasValue && res.Value
100 state.FilePath <- dialog.FileName
105 loadFile.Click.AddHandler(fun obj args
->
106 // TODO: if current state not saved and not empty, ask to save it.
107 let dialog = OpenFileDialog(Filter = Pia.filter
)
108 let res = dialog.ShowDialog()
109 if res.HasValue && res.Value
111 state.FilePath <- dialog.FileName
115 newFile.Click.AddHandler(fun obj args
->
116 // TODO: if current state not saved and not empty, ask to save it.
120 addSourceImage.Click.AddHandler(fun obj args
->
121 let dialog = OpenFileDialog(Filter = "Image Files|*.png;*.jpg;*.tif;*.tiff")
122 let res = dialog.ShowDialog()
123 if res.HasValue && res.Value
125 let srcImg = state.AddSourceImage(dialog.FileName)
127 if state.SourceImages.Count() = 1
129 setCurrentImage srcImg)
131 butStartAnalysis.Click.AddHandler(fun obj args
-> ())
133 // Zoom on the current image.
134 let adjustCurrentImageBorders (deltaX
: float) (deltaY
: float) =
135 borderCurrentImage.BorderThickness <-
137 (scrollViewCurrentImage.ViewportWidth + deltaX
) / 2.,
138 (scrollViewCurrentImage.ViewportHeight + deltaY
) / 2.,
139 (scrollViewCurrentImage.ViewportWidth + deltaX
) / 2.,
140 (scrollViewCurrentImage.ViewportHeight + deltaY
) / 2.)
142 canvasCurrentImage.SizeChanged.AddHandler(fun obj args
->
143 let deltaX = args
.NewSize.Width - args
.PreviousSize.Width
144 let deltaY = args
.NewSize.Height - args
.PreviousSize.Height
145 if deltaX > 0.5 || deltaY > 0.5
147 adjustCurrentImageBorders 0.0
0.0
148 // Center the view at the center of the image initialy.
149 scrollViewCurrentImage.UpdateLayout()
150 scrollViewCurrentImage.ScrollToHorizontalOffset(borderCurrentImage.ActualWidth / 2. - scrollViewCurrentImage.ViewportWidth / 2.)
151 scrollViewCurrentImage.ScrollToVerticalOffset(borderCurrentImage.ActualHeight / 2. - scrollViewCurrentImage.ViewportHeight / 2.))
153 scrollViewCurrentImage.SizeChanged.AddHandler(fun obj args
->
154 let deltaX = args
.NewSize.Width - args
.PreviousSize.Width
155 let deltaY = args
.NewSize.Height - args
.PreviousSize.Height
156 adjustCurrentImageBorders deltaX deltaY
157 scrollViewCurrentImage.ScrollToHorizontalOffset(scrollViewCurrentImage.HorizontalOffset + deltaX / 8.)
158 scrollViewCurrentImage.ScrollToVerticalOffset(scrollViewCurrentImage.VerticalOffset + deltaY / 8.))
160 let mutable currentScale = 1.
161 let mutable maxScale = 5.
162 let mutable minScale = 0.1
163 let currentImageScaleTransform = ScaleTransform()
164 canvasCurrentImage.LayoutTransform <- currentImageScaleTransform
165 borderCurrentImage.PreviewMouseWheel.AddHandler(fun obj args
->
166 let scaleFactor = if args
.Delta > 0 then 2.0 else 0.5
167 if scaleFactor > 1. && currentScale < maxScale || scaleFactor < 1. && currentScale > minScale
169 let previousScale = currentScale
171 let newScale = currentScale * scaleFactor
172 if newScale > maxScale then maxScale elif newScale < minScale then minScale else newScale
173 let realScaleFactor = currentScale / previousScale
175 let centerX = scrollViewCurrentImage.HorizontalOffset + scrollViewCurrentImage.ViewportWidth / 2. - borderCurrentImage.BorderThickness.Left
176 let centerY = scrollViewCurrentImage.VerticalOffset + scrollViewCurrentImage.ViewportHeight / 2. - borderCurrentImage.BorderThickness.Top
178 //canvasCurrentImage.Margin <- Thickness(canvasCurrentImage.Margin.Top * realScaleFactor)
179 currentImageScaleTransform.ScaleX <- currentScale
180 currentImageScaleTransform.ScaleY <- currentScale
182 scrollViewCurrentImage.ScrollToHorizontalOffset(centerX * realScaleFactor - scrollViewCurrentImage.ViewportWidth / 2. + borderCurrentImage.BorderThickness.Left)
183 scrollViewCurrentImage.ScrollToVerticalOffset(centerY * realScaleFactor - scrollViewCurrentImage.ViewportHeight / 2. + borderCurrentImage.BorderThickness.Top)
184 args
.Handled <- true)
186 // Pan on the current image.
187 let mutable scrollStartPosition = Point(0., 0.)
188 let mutable scrollStartOffsetX = 0.
189 let mutable scrollStartOffsetY = 0.
190 borderCurrentImage.PreviewMouseLeftButtonDown.AddHandler(fun obj args
->
191 scrollStartPosition <- args
.GetPosition(scrollViewCurrentImage)
192 scrollStartOffsetX <- scrollViewCurrentImage.HorizontalOffset
193 scrollStartOffsetY <- scrollViewCurrentImage.VerticalOffset
194 borderCurrentImage.Cursor <- Input.Cursors.ScrollAll
195 borderCurrentImage.CaptureMouse() |> ignore
196 args
.Handled <- true)
198 borderCurrentImage.PreviewMouseMove.AddHandler(fun obj args
->
199 if borderCurrentImage.IsMouseCaptured
201 let position = args
.GetPosition(scrollViewCurrentImage)
202 let deltaX = scrollStartPosition.X - position.X
203 let deltaY = scrollStartPosition.Y - position.Y
204 scrollViewCurrentImage.ScrollToHorizontalOffset(deltaX + scrollStartOffsetX)
205 scrollViewCurrentImage.ScrollToVerticalOffset(deltaY + scrollStartOffsetY)
206 args
.Handled <- true)
208 borderCurrentImage.PreviewMouseLeftButtonUp.AddHandler(fun obj args
->
209 if borderCurrentImage.IsMouseCaptured
211 borderCurrentImage.Cursor <- Input.Cursors.Arrow
212 borderCurrentImage.ReleaseMouseCapture()
213 args
.Handled <- true)
215 (* let txtPatient: Controls.TextBox = ctrl "txtPatient"
216 txtPatient.TextChanged.AddHandler(fun obj args ->
217 state.PatientID <- txtPatient.Text) *)
219 (* saveFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*" ;
220 saveFileDialog1.FilterIndex = 2 ;
221 saveFileDialog1.RestoreDirectory = true ; *)
223 // display mainWindow img
224 mainWindow.Root.Show()