- Removed redundant folder and file opening methods from AiTabView and FaceAiTabView. - Introduced PathPickerField control to streamline path selection and opening functionality across multiple views. - Updated FaceAiTabView and GeneralTabView to utilize PathPickerField for source and destination path selection. - Created PathShellService to encapsulate logic for opening paths in the file explorer. - Simplified XAML structure by replacing manual grid definitions with PathPickerField components. - Removed unused namespaces and cleaned up code for better readability and maintainability.
291 lines
21 KiB
XML
291 lines
21 KiB
XML
<UserControl xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:avaloniaDataGrid="clr-namespace:Avalonia.Controls;assembly=Avalonia.Controls.DataGrid"
|
|
xmlns:controls="clr-namespace:ImageCatalog_2.Controls"
|
|
xmlns:iconPacks="https://github.com/MahApps/IconPacks.Avalonia"
|
|
xmlns:converters="clr-namespace:ImageCatalog_2.Converters"
|
|
x:Class="ImageCatalog_2.AvaloniaViews.FaceAiTabView"
|
|
x:CompileBindings="False">
|
|
<UserControl.Resources>
|
|
<converters:FilePathToBitmapConverter x:Key="FilePathToBitmapConverter" />
|
|
</UserControl.Resources>
|
|
|
|
<TabControl Margin="4">
|
|
<TabItem Header="Encoder">
|
|
<TabControl Margin="0,4,0,0">
|
|
<TabItem Header="Esecuzione">
|
|
<ScrollViewer>
|
|
<StackPanel Margin="4" Spacing="6">
|
|
<TextBlock Text="Face Recognition Encoder" FontWeight="Bold" />
|
|
<TextBlock Text="Esegue il face encoder usando la cartella Destinazione corrente come --images e genera automaticamente file .pkl e log nella cartella di output scelta."
|
|
TextWrapping="Wrap" Opacity="0.8" />
|
|
|
|
<WrapPanel>
|
|
<CheckBox Content="Ricorsivo (--recursive)" IsChecked="{Binding FaceRecursive, Mode=TwoWay}" Margin="0,0,12,6" />
|
|
<CheckBox Content="Includi thumbnail (--include-tn)" IsChecked="{Binding FaceIncludeThumbnails, Mode=TwoWay}" Margin="0,0,12,6" />
|
|
<CheckBox Content="Upsample (--upsample)" IsChecked="{Binding FaceUpsample, Mode=TwoWay}" Margin="0,0,12,6" />
|
|
<CheckBox Content="Usa GPU"
|
|
IsChecked="{Binding UseFaceGpu, Mode=TwoWay}"
|
|
IsEnabled="{Binding FaceGpuOptionEnabled}"
|
|
Margin="0,0,12,6" />
|
|
</WrapPanel>
|
|
|
|
<Grid ColumnDefinitions="Auto,120,Auto,120,*" ColumnSpacing="6">
|
|
<TextBlock Grid.Column="0" Text="Parallelismo:" VerticalAlignment="Center" />
|
|
<ComboBox Grid.Column="1" ItemsSource="{Binding FaceParallelismOptions}" SelectedItem="{Binding FaceParallelism, Mode=TwoWay}" />
|
|
<TextBlock Grid.Column="2" Text="Min size:" VerticalAlignment="Center" />
|
|
<TextBox Grid.Column="3" Text="{Binding FaceMinSize, Mode=TwoWay}" Watermark="35" />
|
|
<TextBlock Grid.Column="4" Text="Usa --multicore in CPU e --multiprocess in GPU." VerticalAlignment="Center" TextWrapping="Wrap" Opacity="0.75" />
|
|
</Grid>
|
|
|
|
<controls:PathPickerField Label="Sorgente:"
|
|
Text="{Binding DestinationPath, Mode=TwoWay}"
|
|
IsTextReadOnly="True"
|
|
PreferenceKey="Picker.DestinationFolder.LastPath"
|
|
PickerTitle="Seleziona cartella sorgente Face Encoder"
|
|
PickerMode="Folder"
|
|
AppendDirectorySeparator="True" />
|
|
|
|
<TextBlock Text="Output encodings" FontWeight="Bold" Margin="0,4,0,0" />
|
|
<controls:PathPickerField Label="Cartella out:"
|
|
Text="{Binding FaceOutputFolderPath, Mode=TwoWay}"
|
|
Watermark="C:\output\face_encoder"
|
|
PreferenceKey="Picker.FaceOutputFolder.LastPath"
|
|
PickerTitle="Seleziona la cartella output per encodings e log"
|
|
PickerMode="Folder" />
|
|
<TextBlock Text="I file vengono creati come face_encodings_yyyyMMdd_HHmmss_nomecartella.pkl e encoder_log_yyyyMMdd_HHmmss_nomecartella.txt."
|
|
TextWrapping="Wrap"
|
|
Opacity="0.75" />
|
|
|
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Spacing="8" Margin="0,6,0,0">
|
|
<Button Name="FaceRunButton" Command="{Binding StartFaceEncoderCommand}" Width="176">
|
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="6" VerticalAlignment="Center">
|
|
<iconPacks:PackIconMaterial Kind="PlayCircle" Width="16" Height="16" Foreground="#2E7D32" />
|
|
<ProgressBar Width="18"
|
|
Height="18"
|
|
IsIndeterminate="True"
|
|
IsVisible="{Binding IsFaceEncoderRunning}"
|
|
ShowProgressText="False"
|
|
VerticalAlignment="Center" />
|
|
<TextBlock Text="Esegui Face Encoder" VerticalAlignment="Center" />
|
|
</StackPanel>
|
|
</Button>
|
|
<Button Command="{Binding StopFaceEncoderCommand}" Width="120">
|
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="6">
|
|
<iconPacks:PackIconMaterial Kind="Cancel" Width="16" Height="16" Foreground="#C62828" />
|
|
<TextBlock Text="Stop" />
|
|
</StackPanel>
|
|
</Button>
|
|
<TextBlock VerticalAlignment="Center" Text="{Binding FaceStatusMessage}" TextWrapping="Wrap" />
|
|
</StackPanel>
|
|
|
|
<TextBlock Text="Output comando" FontWeight="Bold" Margin="0,6,0,0" />
|
|
<TextBox Name="FaceOutputTextBox"
|
|
Text="{Binding FaceCommandOutput}"
|
|
IsReadOnly="True"
|
|
AcceptsReturn="True"
|
|
TextWrapping="Wrap"
|
|
FontFamily="Cascadia Mono, Consolas, monospace"
|
|
Height="220"
|
|
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
|
ScrollViewer.HorizontalScrollBarVisibility="Auto" />
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</TabItem>
|
|
|
|
<TabItem Header="Impostazioni">
|
|
<ScrollViewer>
|
|
<StackPanel Margin="4" Spacing="8">
|
|
<TextBlock Text="Cartella Face Encoder" FontWeight="Bold" />
|
|
<TextBlock Text="Seleziona la cartella base di face recognition"
|
|
TextWrapping="Wrap"
|
|
Opacity="0.8" />
|
|
<TextBlock Text="L'app sceglie automaticamente face_encoder_cpu.exe o face_encoder_gpu.exe in base al checkbox GPU."
|
|
TextWrapping="Wrap"
|
|
Opacity="0.75" />
|
|
|
|
<controls:PathPickerField Label="Percorso:"
|
|
Text="{Binding FaceExecutablePath, Mode=TwoWay}"
|
|
Watermark="C:\tools\Face_Recognition_Windows"
|
|
PreferenceKey="Picker.FaceExecutableFolder.LastPath"
|
|
PickerTitle="Seleziona la cartella Face Recognition Windows"
|
|
PickerMode="Folder" />
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</TabItem>
|
|
</TabControl>
|
|
</TabItem>
|
|
|
|
<TabItem Header="Matcher Test">
|
|
<ScrollViewer>
|
|
<StackPanel Margin="4" Spacing="6">
|
|
<TextBlock Text="Face Matcher Test" FontWeight="Bold" />
|
|
<TextBlock Text="Esegue face_matcher.exe su un'immagine scelta a runtime e confronta i risultati con gli encodings .pkl. I match vengono poi risolti per nome file dentro la cartella Destinazione corrente per facilitare il debug visivo."
|
|
TextWrapping="Wrap" Opacity="0.8" />
|
|
|
|
<TextBlock Text="Eseguibile matcher" FontWeight="Bold" Margin="0,4,0,0" />
|
|
<controls:PathPickerField Label="Percorso:"
|
|
Text="{Binding FaceMatcherExecutablePath, Mode=TwoWay}"
|
|
Watermark="C:\tools\Face_Recognition_Windows\face_matcher.exe"
|
|
PreferenceKey="Picker.FaceMatcherExecutable.LastPath"
|
|
PickerTitle="Seleziona face_matcher.exe"
|
|
PickerMode="OpenFile"
|
|
FileTypeName="Eseguibile"
|
|
FilePatterns="*.exe" />
|
|
|
|
<TextBlock Text="Immagine da testare" FontWeight="Bold" Margin="0,4,0,0" />
|
|
<controls:PathPickerField Label="Immagine:"
|
|
Text="{Binding FaceMatcherSelectedImagePath, Mode=TwoWay}"
|
|
Watermark="Percorso immagine da usare per il match"
|
|
PreferenceKey="Picker.FaceMatcherImage.LastPath"
|
|
PickerTitle="Seleziona immagine per il match"
|
|
PickerMode="OpenFile"
|
|
FileTypeName="Immagini"
|
|
FilePatterns="*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.webp" />
|
|
<TextBlock Text="Questa immagine resta solo runtime e non viene salvata nel file impostazioni."
|
|
TextWrapping="Wrap"
|
|
Opacity="0.75" />
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Text="Preview immagine selezionata" FontWeight="SemiBold" />
|
|
<Border BorderThickness="1" BorderBrush="#808080" Padding="4" HorizontalAlignment="Left">
|
|
<Image Width="184"
|
|
Height="120"
|
|
Stretch="UniformToFill"
|
|
Source="{Binding FaceMatcherSelectedImagePath, Converter={StaticResource FilePathToBitmapConverter}}" />
|
|
</Border>
|
|
</StackPanel>
|
|
|
|
<controls:PathPickerField Label="Destinazione attuale:"
|
|
Text="{Binding DestinationPath, Mode=TwoWay}"
|
|
IsTextReadOnly="True"
|
|
PreferenceKey="Picker.DestinationFolder.LastPath"
|
|
PickerTitle="Seleziona cartella destinazione Face Matcher"
|
|
PickerMode="Folder"
|
|
AppendDirectorySeparator="True" />
|
|
|
|
<TextBlock Text="Encodings e file di appoggio" FontWeight="Bold" Margin="0,4,0,0" />
|
|
<controls:PathPickerField Label="Encodings .pkl:"
|
|
Text="{Binding FaceMatcherEncodingsPath, Mode=TwoWay}"
|
|
Watermark="Se vuoto usa l'ultimo .pkl in output encodings"
|
|
PreferenceKey="Picker.FaceMatcherEncodings.LastPath"
|
|
PickerTitle="Seleziona file encodings .pkl"
|
|
PickerMode="OpenFile"
|
|
FileTypeName="Encodings"
|
|
FilePatterns="*.pkl" />
|
|
|
|
<controls:PathPickerField Label="Risultato CSV:"
|
|
Text="{Binding FaceMatcherOutputPath, Mode=TwoWay}"
|
|
Watermark="Opzionale: file/cartella output CSV"
|
|
PreferenceKey="Picker.FaceMatcherOutput.LastPath"
|
|
PickerTitle="Seleziona output CSV del matcher"
|
|
PickerMode="SaveFile"
|
|
FileTypeName="CSV"
|
|
FilePatterns="*.csv"
|
|
DefaultExtension="csv" />
|
|
|
|
<controls:PathPickerField Label="Log matcher:"
|
|
Text="{Binding FaceMatcherLogPath, Mode=TwoWay}"
|
|
Watermark="Opzionale: file/cartella log txt"
|
|
PreferenceKey="Picker.FaceMatcherLog.LastPath"
|
|
PickerTitle="Seleziona log TXT del matcher"
|
|
PickerMode="SaveFile"
|
|
FileTypeName="Log"
|
|
FilePatterns="*.txt;*.log"
|
|
DefaultExtension="txt" />
|
|
|
|
<Grid ColumnDefinitions="Auto,100,*" ColumnSpacing="6">
|
|
<TextBlock Grid.Column="0" Text="Tolleranza:" VerticalAlignment="Center" />
|
|
<TextBox Grid.Column="1" Text="{Binding FaceMatcherTolerance, Mode=TwoWay}" Watermark="0.50" />
|
|
<TextBlock Grid.Column="2" Text="Range utile: 0.35 - 0.75. Più bassa = match più restrittivo, più alta = più permissivo." VerticalAlignment="Center" TextWrapping="Wrap" Opacity="0.75" />
|
|
</Grid>
|
|
|
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Spacing="8" Margin="0,6,0,0">
|
|
<Button Command="{Binding StartFaceMatcherCommand}" Width="176">
|
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="6" VerticalAlignment="Center">
|
|
<iconPacks:PackIconMaterial Kind="PlayCircle" Width="16" Height="16" Foreground="#2E7D32" />
|
|
<ProgressBar Width="18"
|
|
Height="18"
|
|
IsIndeterminate="True"
|
|
IsVisible="{Binding IsFaceMatcherRunning}"
|
|
ShowProgressText="False"
|
|
VerticalAlignment="Center" />
|
|
<TextBlock Text="Avvia Face Matcher" VerticalAlignment="Center" />
|
|
</StackPanel>
|
|
</Button>
|
|
<Button Command="{Binding StopFaceMatcherCommand}" Width="120">
|
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="6">
|
|
<iconPacks:PackIconMaterial Kind="Cancel" Width="16" Height="16" Foreground="#C62828" />
|
|
<TextBlock Text="Stop" />
|
|
</StackPanel>
|
|
</Button>
|
|
<TextBlock VerticalAlignment="Center" Text="{Binding FaceMatcherStatusMessage}" TextWrapping="Wrap" />
|
|
</StackPanel>
|
|
|
|
<TextBlock Text="Output comando" FontWeight="Bold" Margin="0,6,0,0" />
|
|
<TextBox Name="FaceMatcherOutputTextBox"
|
|
Text="{Binding FaceMatcherCommandOutput}"
|
|
IsReadOnly="True"
|
|
AcceptsReturn="True"
|
|
TextWrapping="Wrap"
|
|
FontFamily="Cascadia Mono, Consolas, monospace"
|
|
Height="220"
|
|
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
|
ScrollViewer.HorizontalScrollBarVisibility="Auto" />
|
|
|
|
<TextBlock Text="Risultati" FontWeight="Bold" Margin="0,8,0,0" />
|
|
<avaloniaDataGrid:DataGrid ItemsSource="{Binding FaceMatcherResults}"
|
|
IsReadOnly="True"
|
|
AutoGenerateColumns="False"
|
|
CanUserResizeColumns="True"
|
|
DoubleTapped="FaceMatcherResults_DoubleTapped"
|
|
MinHeight="220">
|
|
<avaloniaDataGrid:DataGrid.Columns>
|
|
<avaloniaDataGrid:DataGridTextColumn Header="File" Binding="{Binding PhotoId}" Width="2*" />
|
|
<avaloniaDataGrid:DataGridTextColumn Header="Score" Binding="{Binding ScoreDisplay}" Width="Auto" />
|
|
<avaloniaDataGrid:DataGridTextColumn Header="Trovato in destinazione" Binding="{Binding ResolvedImagePath}" Width="3*" />
|
|
<avaloniaDataGrid:DataGridTemplateColumn Header="Candidati" Width="Auto">
|
|
<avaloniaDataGrid:DataGridTemplateColumn.CellTemplate>
|
|
<DataTemplate>
|
|
<TextBlock Text="{Binding CandidateCount}" Margin="10,0,0,0" />
|
|
</DataTemplate>
|
|
</avaloniaDataGrid:DataGridTemplateColumn.CellTemplate>
|
|
</avaloniaDataGrid:DataGridTemplateColumn>
|
|
<avaloniaDataGrid:DataGridTextColumn Header="Debug" Binding="{Binding DebugSummary}" Width="4*" />
|
|
</avaloniaDataGrid:DataGrid.Columns>
|
|
</avaloniaDataGrid:DataGrid>
|
|
|
|
<TextBlock Text="Gallery match risolti" FontWeight="Bold" Margin="0,8,0,0" />
|
|
<ItemsControl ItemsSource="{Binding FaceMatcherResults}">
|
|
<ItemsControl.ItemsPanel>
|
|
<ItemsPanelTemplate>
|
|
<WrapPanel />
|
|
</ItemsPanelTemplate>
|
|
</ItemsControl.ItemsPanel>
|
|
<ItemsControl.ItemTemplate>
|
|
<DataTemplate>
|
|
<Button Click="OpenFaceMatcherPreview_Click"
|
|
Tag="{Binding}"
|
|
Width="184"
|
|
Margin="0,0,8,8"
|
|
HorizontalContentAlignment="Stretch"
|
|
VerticalContentAlignment="Stretch">
|
|
<StackPanel Spacing="4">
|
|
<Border BorderThickness="1" BorderBrush="#808080" Padding="4">
|
|
<Image Width="168"
|
|
Height="112"
|
|
Stretch="UniformToFill"
|
|
Source="{Binding ResolvedImagePath, Converter={StaticResource FilePathToBitmapConverter}}" />
|
|
</Border>
|
|
<TextBlock Text="{Binding PhotoId}" FontWeight="SemiBold" TextWrapping="Wrap" />
|
|
<TextBlock Text="{Binding ScoreDisplay}" Opacity="0.8" />
|
|
<TextBlock Text="{Binding ResolvedImagePath}" TextWrapping="Wrap" MaxHeight="36" Opacity="0.8" />
|
|
</StackPanel>
|
|
</Button>
|
|
</DataTemplate>
|
|
</ItemsControl.ItemTemplate>
|
|
</ItemsControl>
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</TabItem>
|
|
</TabControl>
|
|
</UserControl>
|