cell histogram
This commit is contained in:
@@ -29,12 +29,12 @@
|
||||
</Border>
|
||||
|
||||
<!-- Settings Panel -->
|
||||
<Border DockPanel.Dock="Right" Width="220" Padding="12" Background="White">
|
||||
<Border DockPanel.Dock="Right" Width="260" Padding="12" Background="White">
|
||||
<ScrollViewer>
|
||||
<StackPanel Spacing="8">
|
||||
<TextBlock Text="Calibration Settings" FontWeight="Bold" FontSize="14" Foreground="Black" />
|
||||
|
||||
|
||||
|
||||
<Button Content="Calibrate" Command="{Binding RunCalibrationCommand}" Margin="0,4"
|
||||
Background="Red" Foreground="White" FontWeight="Bold" />
|
||||
<Button Content="Clear Images" Command="{Binding ClearCalibrationImagesCommand}" Margin="0,4"
|
||||
@@ -53,13 +53,69 @@
|
||||
</TextBlock>
|
||||
<CheckBox Content="Apply Calibration" IsChecked="{Binding ApplyCalibration}"
|
||||
IsEnabled="{Binding IsCalibrated}" Foreground="Black" Margin="0,4" />
|
||||
|
||||
<Separator Margin="0,8" />
|
||||
|
||||
<TextBlock Text="Pattern" FontWeight="Bold" FontSize="14" Foreground="Black" />
|
||||
|
||||
<TextBlock Text="Rows" Foreground="Black" />
|
||||
<NumericUpDown Value="{Binding Rows}" Minimum="1" Maximum="200" Increment="1" FormatString="0" />
|
||||
|
||||
<TextBlock Text="Cols" Foreground="Black" />
|
||||
<NumericUpDown Value="{Binding Cols}" Minimum="1" Maximum="200" Increment="1" FormatString="0" />
|
||||
|
||||
<TextBlock Text="Shape" Foreground="Black" />
|
||||
<ComboBox ItemsSource="{Binding AvailableCellShapes}" SelectedItem="{Binding SelectedCellShape}" HorizontalAlignment="Stretch" />
|
||||
|
||||
<TextBlock Text="Padding (px)" Foreground="Black" />
|
||||
<NumericUpDown Value="{Binding Padding}" Minimum="0" Maximum="500" Increment="1" FormatString="0" />
|
||||
|
||||
<Separator Margin="0,8" />
|
||||
|
||||
<TextBlock Text="ROI (px)" FontWeight="Bold" FontSize="14" Foreground="Black" />
|
||||
|
||||
<TextBlock Text="X" Foreground="Black" />
|
||||
<NumericUpDown Value="{Binding RoiX}" Minimum="0" Maximum="100000" Increment="1" FormatString="0" />
|
||||
<TextBlock Text="Y" Foreground="Black" />
|
||||
<NumericUpDown Value="{Binding RoiY}" Minimum="0" Maximum="100000" Increment="1" FormatString="0" />
|
||||
<TextBlock Text="Width" Foreground="Black" />
|
||||
<NumericUpDown Value="{Binding RoiWidth}" Minimum="0" Maximum="100000" Increment="1" FormatString="0" />
|
||||
<TextBlock Text="Height" Foreground="Black" />
|
||||
<NumericUpDown Value="{Binding RoiHeight}" Minimum="0" Maximum="100000" Increment="1" FormatString="0" />
|
||||
|
||||
<Separator Margin="0,8" />
|
||||
|
||||
<Button Content="Set Reference" Command="{Binding SetReferenceHistogramCommand}" Margin="0,4"
|
||||
Background="#2E7D32" Foreground="White" FontWeight="Bold" HorizontalAlignment="Stretch" />
|
||||
<TextBlock Text="✓ Reference set" Foreground="LimeGreen" IsVisible="{Binding HasReferenceHistogram}" />
|
||||
|
||||
<TextBlock Text="Tolerance" Foreground="Black" Margin="0,4,0,0" />
|
||||
<NumericUpDown Value="{Binding Tolerance}" Minimum="0" Maximum="1" Increment="0.05" FormatString="0.00" />
|
||||
|
||||
<Button Content="Test Pattern" Command="{Binding TestPatternCommand}" Margin="0,4"
|
||||
Background="#1565C0" Foreground="White" FontWeight="Bold" HorizontalAlignment="Stretch" />
|
||||
|
||||
<Separator Margin="0,8" />
|
||||
|
||||
<TextBlock Text="Recipe" FontWeight="Bold" FontSize="14" Foreground="Black" />
|
||||
<TextBlock Foreground="Black">
|
||||
<TextBlock.Text>
|
||||
<MultiBinding StringFormat="Current: {0}">
|
||||
<Binding Path="CurrentRecipeName" />
|
||||
</MultiBinding>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
<Button Content="Save Recipe" Command="{Binding SaveRecipeCommand}" Margin="0,4"
|
||||
Background="#6A1B9A" Foreground="White" FontWeight="Bold" HorizontalAlignment="Stretch" />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
|
||||
<!-- Live Preview -->
|
||||
<Border Background="#1A1A1A" Margin="4">
|
||||
<Image Source="{Binding PreviewImage}" Stretch="Uniform" />
|
||||
<Image x:Name="PreviewImageControl"
|
||||
Source="{Binding PreviewImage}"
|
||||
Stretch="Uniform" />
|
||||
</Border>
|
||||
</DockPanel>
|
||||
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Media.Imaging;
|
||||
using LindtLeerformPlugin.ViewModels;
|
||||
|
||||
namespace LindtLeerformPlugin.Views;
|
||||
|
||||
public partial class CalibrationWindow : Window
|
||||
{
|
||||
private static readonly Cursor HandCursor = new(StandardCursorType.Hand);
|
||||
private static readonly Cursor DefaultCursor = new(StandardCursorType.Arrow);
|
||||
|
||||
public CalibrationWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
PreviewImageControl.PointerMoved += OnPreviewPointerMoved;
|
||||
PreviewImageControl.PointerPressed += OnPreviewPointerPressed;
|
||||
PreviewImageControl.PointerExited += OnPreviewPointerExited;
|
||||
}
|
||||
|
||||
protected override void OnClosing(WindowClosingEventArgs e)
|
||||
@@ -15,4 +24,64 @@ public partial class CalibrationWindow : Window
|
||||
(DataContext as CalibrationWindowViewModel)?.Dispose();
|
||||
base.OnClosing(e);
|
||||
}
|
||||
|
||||
private (int x, int y)? ToImageCoordinates(Avalonia.Point pointerPos)
|
||||
{
|
||||
if (PreviewImageControl.Source is not Bitmap bitmap)
|
||||
return null;
|
||||
|
||||
var ctrlSize = PreviewImageControl.Bounds.Size;
|
||||
var imgSize = bitmap.Size;
|
||||
if (ctrlSize.Width <= 0 || ctrlSize.Height <= 0 || imgSize.Width <= 0 || imgSize.Height <= 0)
|
||||
return null;
|
||||
|
||||
var scale = System.Math.Min(ctrlSize.Width / imgSize.Width, ctrlSize.Height / imgSize.Height);
|
||||
var displayW = imgSize.Width * scale;
|
||||
var displayH = imgSize.Height * scale;
|
||||
var offsetX = (ctrlSize.Width - displayW) / 2;
|
||||
var offsetY = (ctrlSize.Height - displayH) / 2;
|
||||
|
||||
var imgX = (pointerPos.X - offsetX) / scale;
|
||||
var imgY = (pointerPos.Y - offsetY) / scale;
|
||||
|
||||
if (imgX < 0 || imgY < 0 || imgX >= imgSize.Width || imgY >= imgSize.Height)
|
||||
return null;
|
||||
|
||||
return ((int)imgX, (int)imgY);
|
||||
}
|
||||
|
||||
private void OnPreviewPointerMoved(object? sender, PointerEventArgs e)
|
||||
{
|
||||
if (DataContext is not CalibrationWindowViewModel vm)
|
||||
return;
|
||||
|
||||
var coords = ToImageCoordinates(e.GetPosition(PreviewImageControl));
|
||||
if (coords == null)
|
||||
{
|
||||
PreviewImageControl.Cursor = DefaultCursor;
|
||||
return;
|
||||
}
|
||||
|
||||
var cellIndex = vm.HitTestCell(coords.Value.x, coords.Value.y);
|
||||
PreviewImageControl.Cursor = cellIndex.HasValue ? HandCursor : DefaultCursor;
|
||||
}
|
||||
|
||||
private void OnPreviewPointerExited(object? sender, PointerEventArgs e)
|
||||
{
|
||||
PreviewImageControl.Cursor = DefaultCursor;
|
||||
}
|
||||
|
||||
private async void OnPreviewPointerPressed(object? sender, PointerPressedEventArgs e)
|
||||
{
|
||||
if (DataContext is not CalibrationWindowViewModel vm)
|
||||
return;
|
||||
if (!e.GetCurrentPoint(PreviewImageControl).Properties.IsLeftButtonPressed)
|
||||
return;
|
||||
|
||||
var coords = ToImageCoordinates(e.GetPosition(PreviewImageControl));
|
||||
if (coords == null)
|
||||
return;
|
||||
|
||||
await vm.ShowCellHistogramAsync(coords.Value.x, coords.Value.y, this);
|
||||
}
|
||||
}
|
||||
|
||||
26
Plugins/LindtLeerformPlugin/Views/CellHistogramWindow.axaml
Normal file
26
Plugins/LindtLeerformPlugin/Views/CellHistogramWindow.axaml
Normal file
@@ -0,0 +1,26 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:LindtLeerformPlugin.ViewModels"
|
||||
x:Class="LindtLeerformPlugin.Views.CellHistogramWindow"
|
||||
x:DataType="vm:CellHistogramViewModel"
|
||||
Title="{Binding Title}"
|
||||
Width="720" Height="600"
|
||||
Background="#1A1A1A"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
|
||||
<ScrollViewer>
|
||||
<StackPanel Spacing="12" Margin="16">
|
||||
<TextBlock Text="Reference (learned)" FontWeight="Bold" Foreground="White" FontSize="14" />
|
||||
<Border Background="#0A0A0A" Padding="4">
|
||||
<Image Source="{Binding ReferenceImage}" Stretch="Uniform" Height="220" />
|
||||
</Border>
|
||||
|
||||
<TextBlock Text="Selected cell" FontWeight="Bold" Foreground="White" FontSize="14" Margin="0,8,0,0" />
|
||||
<Border Background="#0A0A0A" Padding="4">
|
||||
<Image Source="{Binding CellImage}" Stretch="Uniform" Height="220" />
|
||||
</Border>
|
||||
|
||||
<TextBlock Text="{Binding DistanceText}" Foreground="LightGray" FontSize="13" Margin="0,8,0,0" />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Window>
|
||||
@@ -0,0 +1,11 @@
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace LindtLeerformPlugin.Views;
|
||||
|
||||
public partial class CellHistogramWindow : Window
|
||||
{
|
||||
public CellHistogramWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user