WPF C# - 鼠标位置坐标不正确



我想通过在图像上绘制矩形来绘制选择,但似乎选择有很大的差距。这是我的代码。

EdgeDetectionWindow.xaml

<Window x:Class="SenpiCHC.EdgeDetectionWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SenpiCHC"
xmlns:codeg="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="EdgeDetectionWindow" Width="1270" Height="720"
WindowState="Maximized"
WindowStyle="None">
<Window.Resources>
<ObjectDataProvider x:Key="dataFromEnum" 
MethodName="GetValues"
ObjectType="{x:Type codeg:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:SelectedEdgeDetectionType"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<Grid>
<StackPanel>
<Image x:Name="imgDynamic" 
MouseDown="ImgDynamic_MouseDown"
MouseMove="ImgDynamic_MouseMove"
MouseUp="ImgDynamic_MouseUp"
Width="1000"
Height="562"/>
<Button Content="Select file" 
Margin="30"
Width="100" 
x:Name="selectFileBtn"
Click="SelectFileBtn_Click"/>
<ComboBox Margin="10"
Width="100"
x:Name="edgeDetectionCbox"
SelectionChanged="EdgeDetectionCbox_SelectionChanged"
ItemsSource="{Binding Source={StaticResource dataFromEnum}}">
</ComboBox>
<Button Content="Detect now!" 
Margin="30"
Width="100" 
x:Name="detectBtn" 
Click="DetectBtn_Click"/>
</StackPanel>
</Grid>
</Window>

EdgeDetectionWindow.xaml.cs

public partial class EdgeDetectionWindow : Window
{
Image<Bgr, byte> _imgInput;
private bool IsSelecting = false;
private double X0, Y0, X1, Y1;
private Bitmap ImageCopy;
public EdgeDetectionWindow()
{
InitializeComponent();
}
private void SelectFileBtn_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == true)
{
Uri fileUri = new Uri(openFileDialog.FileName);
imgDynamic.Source = new BitmapImage(fileUri); // Why bitmapimage? //put the imagefile into the window
ImageCopy = new Bitmap(openFileDialog.FileName);
_imgInput = new Image<Bgr, byte>(openFileDialog.FileName);
}
}
private void ImgDynamic_MouseDown(object sender, MouseButtonEventArgs e)
{
IsSelecting = true;
X0 = e.GetPosition(imgDynamic).X;
Y0 = e.GetPosition(imgDynamic).Y;
}
private void ImgDynamic_MouseMove(object sender, MouseEventArgs e)
{
if (!IsSelecting) return;

//Save the final point
X1 = e.GetPosition(this.imgDynamic).X;
Y1 = e.GetPosition(this.imgDynamic).Y;
//Make a bitmap to display the rectangle
Bitmap bm = new Bitmap(ImageCopy);
//Draw the rectangle
using (Graphics gr = Graphics.FromImage(bm))
{
gr.DrawRectangle(Pens.Red,
(float)Math.Min(X0, X1), (float)Math.Min(Y0, Y1),
(float)Math.Abs(X0 - X1), (float)Math.Abs(Y0 - Y1));
}
//Display the rectangle
imgDynamic.Source = BitmapToImageSource(bm);
}
private void ImgDynamic_MouseUp(object sender, MouseButtonEventArgs e)
{
if (!IsSelecting) return;
IsSelecting = false; //reset the value
//Display the rectangle
imgDynamic.Source = BitmapToImageSource(ImageCopy);
}
private void EdgeDetectionCbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
private void DetectBtn_Click(object sender, RoutedEventArgs e)
{
if (edgeDetectionCbox.SelectedItem.ToString().Equals("Canny"))
{
//Receive input from inputbox
CannyInputDialogue popup = new CannyInputDialogue();
popup.ShowDialog();
int tresh = int.Parse(popup.Tresh);
int treshLinking = int.Parse(popup.TreshLinking);
//Do canny
//Create grayscale
Image<Gray, byte> _imgCanny = new Image<Gray, byte>(_imgInput.Width, _imgInput.Height, new Gray(0)); //canny  with 0 intensity gray image
_imgCanny = _imgInput.Canny(tresh, treshLinking);
//Display the image because imgDynamic.Source cannot display image from emgucv directly
Bitmap display = _imgCanny.ToBitmap();
imgDynamic.Source = BitmapToImageSource(display);

}
else if (edgeDetectionCbox.SelectedItem.ToString().Equals("RobertCross"))
{
//Do robertcross
}
else if (edgeDetectionCbox.SelectedItem.ToString().Equals("Laplacian"))
{
//Do laplacian
LaplacianInputDialogue popup = new LaplacianInputDialogue();
popup.ShowDialog();
int apertureSize = int.Parse(popup.ApertureSize);
//Do grayscale
Image<Gray, byte> _imgGray = _imgInput.Convert<Gray, byte>(); //somehow it has to be converted(?)
//Do sobel
Image<Gray, float> _imgLaplacian = new Image<Gray, float>(_imgInput.Width, _imgInput.Height); //canny  with 0 intensity gray image
_imgLaplacian = _imgGray.Laplace(apertureSize);
//Display the image because imgDynamic.Source cannot display image from emgucv directly
Bitmap display = _imgLaplacian.ToBitmap();
imgDynamic.Source = BitmapToImageSource(display);
}
else if (edgeDetectionCbox.SelectedItem.ToString().Equals("Sobel"))
{
//Receive input from inputbox
SobelInputDialogue popup = new SobelInputDialogue();
popup.ShowDialog();
int xorder = int.Parse(popup.Xorder);
int yorder = int.Parse(popup.Yorder);
int apertureSize = int.Parse(popup.ApertureSize);
//Do grayscale
Image<Gray, byte> _imgGray = _imgInput.Convert<Gray, byte>(); //somehow it has to be converted(?)
//Do sobel
Image<Gray, float> _imgSobel = new Image<Gray, float>(_imgInput.Width, _imgInput.Height); //canny  with 0 intensity gray image
_imgSobel = _imgGray.Sobel(xorder, yorder, apertureSize);
//Display the image because imgDynamic.Source cannot display image from emgucv directly
Bitmap display = _imgSobel.ToBitmap();
imgDynamic.Source = BitmapToImageSource(display);
}

}
BitmapImage BitmapToImageSource(Bitmap bitmap)
{
using (MemoryStream memory = new MemoryStream())
{
bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Bmp);
memory.Position = 0;
BitmapImage bitmapimage = new BitmapImage();
bitmapimage.BeginInit();
bitmapimage.StreamSource = memory;
bitmapimage.CacheOption = BitmapCacheOption.OnLoad;
bitmapimage.EndInit();
return bitmapimage;
}
}
}

我尝试将 e.GetPosition(( 参数放入此参数或 imgDynamic,但它仍然有很大的差距。有什么解决方法吗?如果我的代码非常混乱,我很抱歉,因为我仍在尝试了解更多信息。

为了在图像上绘制一个选择矩形,您可以简单地在图像顶部有一个带有矩形几何的 Path 元素,如下所示:

<Canvas>
<Image Source="C:UsersPublicPicturesSample PicturesKoala.jpg"
MouseLeftButtonDown="ImageMouseLeftButtonDown"
MouseLeftButtonUp="ImageMouseLeftButtonUp"
MouseMove="ImageMouseMove"/>
<Path x:Name="selectionPath" Stroke="Magenta" StrokeThickness="2"/>
</Canvas>

使用这些事件处理程序:

private Point mousePos;
private void ImageMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var image = (Image)sender;
image.CaptureMouse();
mousePos = e.GetPosition(image);
selectionPath.Data = new RectangleGeometry(new Rect(mousePos, mousePos));
}
private void ImageMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var image = (Image)sender;
image.ReleaseMouseCapture();
selectionPath.Data = null;
}
private void ImageMouseMove(object sender, MouseEventArgs e)
{
var rect = selectionPath.Data as RectangleGeometry;
if (rect != null)
{
var image = (Image)sender;
rect.Rect = new Rect(mousePos, e.GetPosition(image));
}
}

最新更新