* Modify a bit the parasite nucleus detection sensibility.
authorGreg Burri <greg.burri@gmail.com>
Tue, 26 Jan 2016 23:28:56 +0000 (00:28 +0100)
committerGreg Burri <greg.burri@gmail.com>
Tue, 26 Jan 2016 23:28:56 +0000 (00:28 +0100)
* Add a setup.

Parasitemia/ParasitemiaCore/Config.fs
Parasitemia/ParasitemiaCore/MainAnalysis.fs
Parasitemia/ParasitemiaCore/MatchingEllipses.fs
Parasitemia/ParasitemiaUI/About.fs
Parasitemia/ParasitemiaUI/GUI.fs
Parasitemia/ParasitemiaUI/XAML/AboutWindow.xaml
Parasitemia/ParasitemiaUI/XAML/MainWindow.xaml
Parasitemia/Setup/setup.iss [new file with mode: 0644]

index 4b38483..9724d9c 100644 (file)
@@ -66,9 +66,9 @@ let defaultParameters = {
     cytoplasmSensitivity = 0.96
 
     nucleusAreaRatio = 0.01f // 1.0 %
     cytoplasmSensitivity = 0.96
 
     nucleusAreaRatio = 0.01f // 1.0 %
-    infectionSensitivity = 0.9
+    infectionSensitivity = 0.92
 
 
-    standardDeviationMaxRatio = 0.5
+    standardDeviationMaxRatio = 0.6
     minimumCellAreaFactor = 0.4f }
 
 type RBCRadius (radius: float32, parameters: Parameters) =
     minimumCellAreaFactor = 0.4f }
 
 type RBCRadius (radius: float32, parameters: Parameters) =
index 1d2ced3..926aeac 100644 (file)
@@ -59,7 +59,7 @@ let doAnalysis (img: Image<Bgr, byte>) (name: string) (config: Config) (reportPr
         use img_parasites = img_float.[2] // mergeChannelsWithProjection img_float config.Parameters.averageColor_Parasite config.Parameters.averageColor_RBC 255.
         use img_parasites_filtered = gaussianFilter img_parasites config.LPFStandardDeviationParasite
 
         use img_parasites = img_float.[2] // mergeChannelsWithProjection img_float config.Parameters.averageColor_Parasite config.Parameters.averageColor_RBC 255.
         use img_parasites_filtered = gaussianFilter img_parasites config.LPFStandardDeviationParasite
 
-        logWithName (sprintf "Nominal erytrocyte diameter: %A" config.RBCRadiusByResolution)
+        logWithName (sprintf "Nominal erythrocyte diameter: %A" config.RBCRadiusByResolution)
 
         let initialAreaOpening = int <| config.RBCRadiusByResolution.Area * config.Parameters.ratioAreaPaleCenter * 1.1f // We do an area opening a little larger to avoid to do a second one in the case the radius found is near the initial one.
         do! logTimeWithName "First area opening" (fun () -> areaOpenF img_RBC_filtered initialAreaOpening; report 10)
 
         let initialAreaOpening = int <| config.RBCRadiusByResolution.Area * config.Parameters.ratioAreaPaleCenter * 1.1f // We do an area opening a little larger to avoid to do a second one in the case the radius found is near the initial one.
         do! logTimeWithName "First area opening" (fun () -> areaOpenF img_RBC_filtered initialAreaOpening; report 10)
@@ -70,7 +70,7 @@ let doAnalysis (img: Image<Bgr, byte>) (name: string) (config: Config) (reportPr
         let! radius = logTimeWithName "Granulometry (area)" (fun() -> reportWithVal 10 (Granulometry.findRadiusByAreaClosing img_RBC_filtered range |> float32))
         config.SetRBCRadius <| radius
 
         let! radius = logTimeWithName "Granulometry (area)" (fun() -> reportWithVal 10 (Granulometry.findRadiusByAreaClosing img_RBC_filtered range |> float32))
         config.SetRBCRadius <| radius
 
-        logWithName (sprintf "Found erytrocyte diameter: %A" config.RBCRadius)
+        logWithName (sprintf "Found erythrocyte diameter: %A" config.RBCRadius)
 
         do! report 20
 
 
         do! report 20
 
index 3ed8ad6..bfa042b 100644 (file)
@@ -10,10 +10,10 @@ open Types
 open Utils
 
 // All ellipses with a score below this are removed.
 open Utils
 
 // All ellipses with a score below this are removed.
-let matchingScoreThreshold = 0.4f
+let matchingScoreThresholdPerRadiusUnit = 0.02f // For a radius of 1.
 let matchingScorePower = 20.f
 let windowSizeRadiusFactor = 1.f / 2.f
 let matchingScorePower = 20.f
 let windowSizeRadiusFactor = 1.f / 2.f
-let minimumDistanceFromCenterRadiusFactor = 1.f / 3.f
+let minimumDistanceFromCenterRadiusFactor = 1.f / 3.f // 1.f / 3.f
 
 type private EllipseScoreFlaggedKd (matchingScore: float32, e: Ellipse) =
     let mutable matchingScore = matchingScore
 
 type private EllipseScoreFlaggedKd (matchingScore: float32, e: Ellipse) =
     let mutable matchingScore = matchingScore
@@ -72,6 +72,7 @@ type MatchingEllipses (radius: float32) =
                         | _ -> ()
 
             // 3) Remove ellipses whose center is near the center of another ellipse with a better score.
                         | _ -> ()
 
             // 3) Remove ellipses whose center is near the center of another ellipse with a better score.
+            let matchingScoreThreshold = matchingScoreThresholdPerRadiusUnit * radius
             for e in ellipses do
                 if e.MatchingScore < matchingScoreThreshold
                 then
             for e in ellipses do
                 if e.MatchingScore < matchingScoreThreshold
                 then
index 5f1be66..44dd881 100644 (file)
@@ -19,10 +19,22 @@ let showWindow (parent: Window) =
     let butClose: Button = ctrl "butClose"
     let txtAbout: TextBlock = ctrl "txtAbout"
 
     let butClose: Button = ctrl "butClose"
     let txtAbout: TextBlock = ctrl "txtAbout"
 
+    let linkHESSO: Documents.Hyperlink = ctrl "linkHESSO"
+    let linkCHUV: Documents.Hyperlink = ctrl "linkCHUV"
+    let linkGBurri: Documents.Hyperlink = ctrl "linkGBurri"
+
     let version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version
     let txtVersion = sprintf " %d.%d.%d" version.Major version.Minor version.Revision
     txtAbout.Inlines.FirstInline.ElementEnd.InsertTextInRun(txtVersion)
 
     let version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version
     let txtVersion = sprintf " %d.%d.%d" version.Major version.Minor version.Revision
     txtAbout.Inlines.FirstInline.ElementEnd.InsertTextInRun(txtVersion)
 
+    let navigateTo = Navigation.RequestNavigateEventHandler(fun obj args ->
+        Process.Start(ProcessStartInfo(args.Uri.AbsoluteUri)) |> ignore
+        args.Handled <- true)
+
+    linkHESSO.RequestNavigate.AddHandler(navigateTo);
+    linkCHUV.RequestNavigate.AddHandler(navigateTo);
+    linkGBurri.RequestNavigate.AddHandler(navigateTo);
+
 #if DEBUG
     txtAbout.Inlines.FirstInline.ElementEnd.InsertTextInRun(" - DEBUG")
 #endif
 #if DEBUG
     txtAbout.Inlines.FirstInline.ElementEnd.InsertTextInRun(" - DEBUG")
 #endif
index f67c613..3746461 100644 (file)
@@ -165,7 +165,7 @@ let run (defaultConfig: Config) (fileToOpen: string option) =
         then
             txtGlobalParasitemia.Inlines.Add(
                 Documents.Run(
         then
             txtGlobalParasitemia.Inlines.Add(
                 Documents.Run(
-                    sprintf " Warning: the number of erytrocytes should be above %d" warningBelowNumberOfRBC,
+                    sprintf " Warning: the number of erythrocytes should be above %d" warningBelowNumberOfRBC,
                     FontWeight = FontWeights.Bold,
                     Foreground = Brushes.Red))
 
                     FontWeight = FontWeights.Bold,
                     Foreground = Brushes.Red))
 
index e35d234..d08f4c4 100644 (file)
@@ -4,20 +4,20 @@
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         mc:Ignorable="d"
         x:Name="AboutWindow" Height="220" Width="280" MinHeight="220" MinWidth="280" Title="About" Icon="pack://application:,,,/Resources/icon.ico" ResizeMode="NoResize">
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         mc:Ignorable="d"
         x:Name="AboutWindow" Height="220" Width="280" MinHeight="220" MinWidth="280" Title="About" Icon="pack://application:,,,/Resources/icon.ico" ResizeMode="NoResize">
-   <Grid>
+   <Grid Margin="3">
       <Grid.RowDefinitions>
          <RowDefinition Height="Auto"/>
          <RowDefinition Height="Auto"/>
          <RowDefinition/>
       </Grid.RowDefinitions>
       <Image HorizontalAlignment="Left" Height="64" VerticalAlignment="Top" Width="64" Margin="6" Source="pack://application:,,,/Resources/icon.ico"/>
       <Grid.RowDefinitions>
          <RowDefinition Height="Auto"/>
          <RowDefinition Height="Auto"/>
          <RowDefinition/>
       </Grid.RowDefinitions>
       <Image HorizontalAlignment="Left" Height="64" VerticalAlignment="Top" Width="64" Margin="6" Source="pack://application:,,,/Resources/icon.ico"/>
-      <TextBlock x:Name="txtAbout" HorizontalAlignment="Left" Margin="6" Grid.Row="1" TextWrapping="Wrap">
-         <Bold>Parasitemia </Bold>
+      <TextBlock x:Name="txtAbout" HorizontalAlignment="Left" Margin="20,6" Grid.Row="1" TextWrapping="Wrap">
+         <Bold FontSize="14.667">Parasitemia </Bold>
          <LineBreak />
          <LineBreak />
-         <Hyperlink NavigateUri="http://www.hes-so.ch">HES-SO</Hyperlink> /
-         <Hyperlink NavigateUri="http://www.chuv.ch/">CHUV</Hyperlink>
+         <Hyperlink x:Name="linkHESSO" NavigateUri="http://www.hes-so.ch" >HES-SO</Hyperlink> /
+         <Hyperlink x:Name="linkCHUV" NavigateUri="http://www.chuv.ch/" >CHUV</Hyperlink>
          <LineBreak />
          <LineBreak />
-         GrĂ©gory Burri
+         <Hyperlink x:Name="linkGBurri" NavigateUri="mailto:greg.burri@gmail.com"> GrĂ©gory Burri</Hyperlink>
       </TextBlock>
       <Button x:Name="butClose" Content="Close" HorizontalAlignment="Right" Margin="3" VerticalAlignment="Bottom" Width="75" Grid.Row="2" Height="20"/>
    </Grid>
       </TextBlock>
       <Button x:Name="butClose" Content="Close" HorizontalAlignment="Right" Margin="3" VerticalAlignment="Bottom" Width="75" Grid.Row="2" Height="20"/>
    </Grid>
index 000da4e..a330fa3 100644 (file)
@@ -23,7 +23,7 @@
             <MenuItem x:Name="menuStartAnalysis" Header="_Show Analysis Window" />
          </MenuItem>
          <MenuItem x:Name="menuView" Header="_View">
             <MenuItem x:Name="menuStartAnalysis" Header="_Show Analysis Window" />
          </MenuItem>
          <MenuItem x:Name="menuView" Header="_View">
-            <MenuItem x:Name="menuHightlightRBC" Header="_Highlight All Erytrocytes" IsCheckable="True" />
+            <MenuItem x:Name="menuHightlightRBC" Header="_Highlight All Erythrocytes" IsCheckable="True" />
          </MenuItem>
          <MenuItem x:Name="menuHelp" Header="_Help">
             <MenuItem x:Name="menuAbout" Header="_About" />
          </MenuItem>
          <MenuItem x:Name="menuHelp" Header="_Help">
             <MenuItem x:Name="menuAbout" Header="_About" />
diff --git a/Parasitemia/Setup/setup.iss b/Parasitemia/Setup/setup.iss
new file mode 100644 (file)
index 0000000..51c8b64
--- /dev/null
@@ -0,0 +1,52 @@
+[code]
+#define ApplicationDir ".."
+
+#define AppName "Parasitemia"
+#define ExePath ApplicationDir + "/ParasitemiaUI/bin/Release/ParasitemiaUI.exe"
+#define Version GetStringFileInfo(ExePath, 'ProductVersion')
+#define BuildTime GetStringFileInfo(ExePath, 'BuildTime')
+
+[Setup]
+AppName={#AppName}
+AppVersion={#Version}          
+SetupIconFile={#ApplicationDir}/ParasitemiaUI/Resources/icon.ico 
+DefaultDirName={pf}/{#AppName}
+DefaultGroupName={#AppName}
+UninstallDisplayIcon={app}/ParasitemiaUI.exe
+Compression=lzma2
+SolidCompression=yes
+OutputBaseFilename={#AppName}-{#Version}-Setup
+ChangesAssociations=yes
+
+[Files]
+Source: "{#ApplicationDir}/ParasitemiaUI/bin/Release/ParasitemiaUI.exe"; DestDir: "{app}"; Flags: comparetimestamp
+Source: "{#ApplicationDir}/ParasitemiaUI/bin/Release/Emgu.CV.dll"; DestDir: "{app}"; Flags: comparetimestamp
+Source: "{#ApplicationDir}/ParasitemiaUI/bin/Release/Emgu.Util.dll"; DestDir: "{app}"; Flags: comparetimestamp
+Source: "{#ApplicationDir}/ParasitemiaUI/bin/Release/FSharp.Collections.ParallelSeq.dll"; DestDir: "{app}"; Flags: comparetimestamp
+Source: "{#ApplicationDir}/ParasitemiaUI/bin/Release/FSharp.Core.dll"; DestDir: "{app}"; Flags: comparetimestamp
+Source: "{#ApplicationDir}/ParasitemiaUI/bin/Release/FSharp.ViewModule.dll"; DestDir: "{app}"; Flags: comparetimestamp
+Source: "{#ApplicationDir}/ParasitemiaUI/bin/Release/FsXaml.Wpf.dll"; DestDir: "{app}"; Flags: comparetimestamp     
+Source: "{#ApplicationDir}/ParasitemiaUI/bin/Release/FsXaml.Wpf.TypeProvider.dll"; DestDir: "{app}"; Flags: comparetimestamp
+Source: "{#ApplicationDir}/ParasitemiaUI/bin/Release/Logger.dll"; DestDir: "{app}"; Flags: comparetimestamp
+Source: "{#ApplicationDir}/ParasitemiaUI/bin/Release/MathNet.Numerics.dll"; DestDir: "{app}"; Flags: comparetimestamp
+Source: "{#ApplicationDir}/ParasitemiaUI/bin/Release/Newtonsoft.Json.dll"; DestDir: "{app}"; Flags: comparetimestamp
+Source: "{#ApplicationDir}/ParasitemiaUI/bin/Release/ParasitemiaCore.dll"; DestDir: "{app}"; Flags: comparetimestamp   
+Source: "{#ApplicationDir}/ParasitemiaUI/bin/Release/System.Windows.Interactivity.dll"; DestDir: "{app}"; Flags: comparetimestamp
+Source: "{#ApplicationDir}/ParasitemiaUI/bin/Release/WPF.dll"; DestDir: "{app}"; Flags: comparetimestamp        
+Source: "{#ApplicationDir}/ParasitemiaUI/bin/Release/ParasitemiaUI.exe.config"; DestDir: "{app}"; Flags: comparetimestamp
+
+Source: "{#ApplicationDir}/ParasitemiaUI/bin/Release/x64/*"; DestDir: "{app}/x64"; Flags: comparetimestamp recursesubdirs
+
+[Icons]     
+Name: "{group}\Parasitemia"; Filename: "{app}/ParasitemiaUI.exe"; WorkingDir: "{app}"                      
+
+[Tasks]
+Name: ParasitemiaFileAssociation; Description: "Use Parasitemia to open ""piaz"" files"; GroupDescription: File extensions:
+
+[Registry]
+Root: HKCR; Subkey: ".piaz"; ValueType: string; ValueName: ""; ValueData: "Parasitemia"; Flags: uninsdeletevalue; Tasks: ParasitemiaFileAssociation 
+Root: HKCR; Subkey: "Parasitemia"; ValueType: string; ValueName: ""; ValueData: "Parasitemia Prog"; Flags: uninsdeletekey
+Root: HKCR; Subkey: "OptInvest\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\ParasitemiaUI.exe,0"
+
+[Run]
+Filename: "{app}/ParasitemiaUI.exe"; Flags: nowait postinstall runasoriginaluser; Description: "Launch Parasitemia"
\ No newline at end of file