* Code documentation.
open Types
open Utils
-
type private EllipseFlaggedKd (e: Ellipse) =
inherit Ellipse (e.Cx, e.Cy, e.A, e.B, e.Alpha)
member this.X = this.Cx
member this.Y = this.Cy
-
let findCells (ellipses: Ellipse list) (parasites: ParasitesMarker.Result) (img: Image<Gray, float32>) (config: Config.Config) : Cell list =
if ellipses.IsEmpty
then
if stdDeviation > globalStdDeviation * config.Parameters.standardDeviationMaxRatio then
e.Removed <- true
-
// 4) Remove ellipses with little area.
let minArea = config.RBCRadius.MinArea
for e, neighbors in ellipsesWithNeigbors do
open Config
open Types
+/// <summary>
+/// Analyze the given image and detect reb blood cell (RBC) in it.
+/// </summary>
+/// <param name="img">The image</param>
+/// <param name="name">The name, used during logging</param>
+/// <param name="config">The configuration, must not be shared with another analysis</param>
+/// <param name="reportProgress">An optional function to report progress and/or cancel the process.
+/// The first call returning 'false' will cancel the analysis.
+/// The 'int' parameter correspond to the progression from 0 to 100</param>
+/// <returns>A list of detected cells or nothing if the process has been cancelled</returns>
let doAnalysis (img: Image<Bgr, byte>) (name: string) (config: Config) (reportProgress: (int -> bool) option) : Cell list option =
+
// To report the progress of this function from 0 to 100.
+ // Return 'None' if the process must be aborted.
let reportWithVal (percent: int) (value: 'a) : 'a option =
match reportProgress with
| Some f ->
let report (percent: int) : unit option =
reportWithVal percent ()
- let inline buildLogWithName (text: string) = sprintf "(%s) %s" name text
+ let inline buildLogWithName (text: string) = sprintf "(%s) %s" name text
let logWithName mess = Log.User(buildLogWithName mess)
let inline logTimeWithName (text: string) (f: unit -> 'a option) : 'a option = Log.LogWithTime((buildLogWithName text), Severity.USER, f)
let initialAreaOpening = int <| config.RBCRadiusByResolution.Area * config.Parameters.ratioAreaPaleCenter * 1.2f // 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 () -> ImgTools.areaOpenF filteredGreen initialAreaOpening; report 10)
- //do! report 10
-
let range =
let delta = config.Parameters.granulometryRange * config.RBCRadiusByResolution.Pixel
int <| config.RBCRadiusByResolution.Pixel - delta, int <| config.RBCRadiusByResolution.Pixel + delta
/// <summary>
/// Do multiple analyses on the same time. The number of concurrent process depends if the number of the core.
/// </summary>
-/// <param name="imgs"></param>
-/// <param name="reportProgress">An optional function to report progress. The process is aborted if the returned value is false</param>
+/// <param name="imgs">The images: (name * configuration * image)</param>
+/// <param name="reportProgress">An optional function to report progress and/or cancel the process.
+/// The first call returning 'false' will cancel the analysis.
+/// The 'int' parameter correspond to the progression from 0 to 100</param>
+/// <returns>'None' if the process has been cancelled or the list of result as (name * cells), 'name' corresponds to the given name<returns>
let doMultipleAnalysis (imgs: (string * Config * Image<Bgr, byte>) list) (reportProgress: (int -> bool) option) : (string * Cell list) list option =
let report (percent: int) : bool =
match reportProgress with
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [<assembly: AssemblyVersion("1.0.*")>]
-[<assembly: AssemblyVersion("1.0.0.1")>]
-[<assembly: AssemblyFileVersion("1.0.0.1")>]
+[<assembly: AssemblyVersion("1.0.0.2")>]
+[<assembly: AssemblyFileVersion("1.0.0.2")>]
do
()
\ No newline at end of file
let scrollRBC: ScrollViewer = ctrl "scrollRBC"
let stackRBC: StackPanel = ctrl "stackRBC"
+ let imgLogos: Border = ctrl "imgLogos"
+
// Initializations.
+ let canvasCurrentImageColor = canvasCurrentImage.Background
menuHightlightRBC.IsChecked <- displayHealthy
// Utils.
sprintf "%.1f %% (%d / %d)" percent nb nbTotal
let updateCurrentImageInformation () =
+ txtImageInformation1.Inlines.Clear()
+ txtImageInformation2.Inlines.Clear()
+
match state.CurrentImage with
| Some srcImg ->
let parasitemiaStr = percentText (state.ImageParasitemia srcImg)
- txtImageInformation1.Inlines.Clear()
txtImageInformation1.Inlines.Add(Documents.Run("Parasitemia: ", FontWeight = FontWeights.Bold))
txtImageInformation1.Inlines.Add(parasitemiaStr)
txtImageInformation1.Inlines.Add(Documents.LineBreak())
txtImageInformation1.Inlines.Add(Documents.Run("Last analysis: ", FontWeight = FontWeights.Bold))
txtImageInformation1.Inlines.Add(Documents.Run(if srcImg.dateLastAnalysis.Ticks = 0L then "<Never>" else srcImg.dateLastAnalysis.ToLocalTime().ToString()))
- txtImageInformation2.Inlines.Clear()
let alteredStr = percentText (state.ImageNbAltered srcImg)
txtImageInformation2.Inlines.Add(Documents.Run("Number of erytrocytes manually altered: ", FontWeight = FontWeights.Bold))
txtImageInformation2.Inlines.Add(Documents.Run(alteredStr))
let updateCurrentImage () =
match state.CurrentImage with
| Some srcImg ->
+ imgLogos.Visibility <- Visibility.Collapsed
+
// Highlight the preview.
stackPreviews.Children
|> Seq.cast<Views.ImageSourcePreview>
updateRBCFramesCurrent ()
updateRBCFramesPreview ()
- updateCurrentImageInformation ()
| None ->
+ imgLogos.Visibility <- Visibility.Visible
stackRBC.Children.Clear()
canvasCurrentImage.Children.Clear()
- canvasCurrentImage.Background <- Brushes.Black
+ canvasCurrentImage.Background <- canvasCurrentImageColor
+
+ updateCurrentImageInformation ()
let setCurrentImage (srcImg: SourceImage) =
if state.CurrentImage.IsNone || state.CurrentImage.Value <> srcImg
<Import Project="$(FSharpTargetsPath)" />
<ItemGroup>
<Compile Include="AssemblyInfo.fs" />
+ <Resource Include="Resources\chuv_logo.png" />
+ <Resource Include="Resources\hes-so_logo.png" />
<Resource Include="Resources\icon.ico" />
<Resource Include="XAML\NumericUpDown.xaml" />
<Compile Include="XAML\NumericUpDown.xaml.fs" />
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="700" Width="1000" MinHeight="200" MinWidth="300" Title="Parasitemia" Icon="pack://application:,,,/Resources/icon.ico" ResizeMode="CanResizeWithGrip">
+ x:Name="MainWindow" Height="700" Width="1000" MinHeight="300" MinWidth="400" Title="Parasitemia" Icon="pack://application:,,,/Resources/icon.ico" ResizeMode="CanResizeWithGrip">
<DockPanel x:Name="dockPanelMain" LastChildFill="True">
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
- <ColumnDefinition Width="180"/>
+ <ColumnDefinition Width="180" />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid x:Name="gridGlobalInfo" Grid.ColumnSpan="2" Margin="3,3,3,3" >
<TextBox x:Name="txtPatient" Grid.Column="2" Margin="3,4,10,4" TextWrapping="Wrap" VerticalAlignment="Center" />
<TextBox x:Name="txtGlobalParasitemia" Grid.Column="2" Grid.Row="1" Margin="3,4,10,4" TextWrapping="Wrap" VerticalAlignment="Center" IsReadOnly="True" />
</Grid>
- <Border BorderBrush="Black" BorderThickness="1" Margin="3" Grid.Row="1" >
+ <Border BorderBrush="Black" BorderThickness="0" Margin="3" Grid.Row="1" >
<ScrollViewer x:Name="scrollPreviews" VerticalScrollBarVisibility="Auto" >
<StackPanel x:Name="stackPreviews" />
</ScrollViewer>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
- <ScrollViewer x:Name="scrollViewCurrentImage" Grid.Row="1" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" Background="Black" MinHeight="100" MinWidth="100">
+ <ScrollViewer x:Name="scrollViewCurrentImage" Grid.Row="1" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" Background="#FF535353" MinHeight="100" MinWidth="100">
<Border x:Name="borderCurrentImage" BorderBrush="Transparent">
<Canvas x:Name="canvasCurrentImage" Height="100" Width="100" />
</Border>
</ScrollViewer>
+ <Border Grid.Row="1" x:Name="imgLogos">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="1*"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="1*"/>
+ </Grid.RowDefinitions>
+ <Image Grid.Row="1" Source="pack://application:,,,/Resources/chuv_logo.png" Stretch="None" Panel.ZIndex="1" Margin="0,0,0,10" />
+ <Image Grid.Row="2" Source="pack://application:,,,/Resources/hes-so_logo.png" Stretch="None" Panel.ZIndex="1" Margin="0,10,0,0" />
+ </Grid>
+ </Border>
<ScrollViewer x:Name="scrollRBC" VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Visible" Grid.RowSpan="1" Margin="3">
<StackPanel x:Name="stackRBC" Orientation="Horizontal" />
</ScrollViewer>