为主界面快捷工具栏添加图像处理命令接口:白底检测、黑底检测、灰度、锐化、增强,实现锐化和增强

This commit is contained in:
李伟
2026-05-08 11:07:27 +08:00
parent d3f06aed8b
commit 7cf16ecdbc
2 changed files with 167 additions and 1 deletions
+162 -1
View File
@@ -10,7 +10,10 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Emgu.CV;
using Emgu.CV.Structure;
using XplorePlane.Events;
using XplorePlane.Services.MainViewport;
using XplorePlane.Services.Storage;
@@ -116,6 +119,13 @@ namespace XplorePlane.ViewModels
// 辅助线命令
public DelegateCommand ToggleCrosshairCommand { get; }
// 图像处理命令
public DelegateCommand WhiteBackgroundDetectionCommand { get; }
public DelegateCommand BlackBackgroundDetectionCommand { get; }
public DelegateCommand GrayscaleCommand { get; }
public DelegateCommand SharpenCommand { get; }
public DelegateCommand EnhanceCommand { get; }
// 设置命令
public DelegateCommand OpenLanguageSwitcherCommand { get; }
@@ -301,6 +311,13 @@ namespace XplorePlane.ViewModels
ToggleCrosshairCommand = new DelegateCommand(() =>
_eventAggregator.GetEvent<ToggleCrosshairEvent>().Publish());
// 图像处理命令
WhiteBackgroundDetectionCommand = new DelegateCommand(ExecuteWhiteBackgroundDetection);
BlackBackgroundDetectionCommand = new DelegateCommand(ExecuteBlackBackgroundDetection);
GrayscaleCommand = new DelegateCommand(ExecuteGrayscale);
SharpenCommand = new DelegateCommand(ExecuteSharpen);
EnhanceCommand = new DelegateCommand(ExecuteEnhance);
AxisResetCommand = new DelegateCommand(ExecuteAxisReset);
OpenDoorCommand = new DelegateCommand(ExecuteOpenDoor);
CloseDoorCommand = new DelegateCommand(ExecuteCloseDoor);
@@ -761,7 +778,7 @@ namespace XplorePlane.ViewModels
if (viewportVm?.ImageSource != null) return true;
}
catch { }
HexMessageBox.Show("Please load an image first", MessageBoxButton.OK, MessageBoxImage.Information);
HexMessageBox.Show("Please load an image first!", MessageBoxButton.OK, MessageBoxImage.Information);
return false;
}
@@ -862,6 +879,150 @@ namespace XplorePlane.ViewModels
_bubbleMeasurePanel.Show();
}
private void ExecuteWhiteBackgroundDetection()
{
if (!CheckImageLoaded()) return;
_logger.Info("White background detection triggered.");
// TODO: 实现白底检测逻辑
}
private void ExecuteBlackBackgroundDetection()
{
if (!CheckImageLoaded()) return;
_logger.Info("Black background detection triggered.");
// TODO: 实现黑底检测逻辑
}
private void ExecuteGrayscale()
{
if (!CheckImageLoaded()) return;
_logger.Info("Grayscale conversion triggered.");
// TODO: 实现灰度转换逻辑
}
private void ExecuteSharpen()
{
if (!CheckImageLoaded()) return;
_logger.Info("Sharpen triggered.");
try
{
var viewportVm = _containerProvider.Resolve<ViewportPanelViewModel>();
var imageSource = viewportVm?.ImageSource as BitmapSource;
if (imageSource == null) return;
var inputImage = BitmapSourceToImage(imageSource);
if (inputImage == null) return;
var processor = new XP.ImageProcessing.Processors.SharpenProcessor();
processor.SetParameter("Method", "UnsharpMask");
processor.SetParameter("Strength", 0.2);
processor.SetParameter("KernelSize", 3);
var result = processor.Process(inputImage);
var resultBitmap = ImageToBitmapSource(result);
_mainViewportService.SetManualImage(resultBitmap, "Sharpen");
inputImage.Dispose();
result.Dispose();
_logger.Info("Sharpen completed.");
}
catch (Exception ex)
{
_logger.Error(ex, "Sharpen failed.");
HexMessageBox.Show($"Sharpen failed: {ex.Message}", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void ExecuteEnhance()
{
if (!CheckImageLoaded()) return;
_logger.Info("Enhance triggered.");
try
{
var viewportVm = _containerProvider.Resolve<ViewportPanelViewModel>();
var imageSource = viewportVm?.ImageSource as BitmapSource;
if (imageSource == null) return;
var inputImage = BitmapSourceToImage(imageSource);
if (inputImage == null) return;
var processor = new XP.ImageProcessing.Processors.HistogramEqualizationProcessor();
var result = processor.Process(inputImage);
var resultBitmap = ImageToBitmapSource(result);
_mainViewportService.SetManualImage(resultBitmap, "Enhance");
inputImage.Dispose();
result.Dispose();
_logger.Info("Enhance completed.");
}
catch (Exception ex)
{
_logger.Error(ex, "Enhance failed.");
HexMessageBox.Show($"Enhance failed: {ex.Message}", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private Image<Gray, byte>? BitmapSourceToImage(BitmapSource bitmapSource)
{
// 转换为可用的图像格式
BitmapSource source = bitmapSource;
// 如果不是 Gray8 格式,转换为 Gray8
if (bitmapSource.Format != PixelFormats.Gray8)
{
source = new FormatConvertedBitmap(bitmapSource, PixelFormats.Gray8, null, 0);
}
// 获取原始像素数据
int width = source.PixelWidth;
int height = source.PixelHeight;
int stride = width; // Gray8 每个像素 1 字节
byte[] pixels = new byte[width * height];
source.CopyPixels(pixels, stride, 0);
// 创建 Emgu CV Image
var image = new Image<Gray, byte>(width, height);
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
image.Data[y, x, 0] = pixels[y * stride + x];
}
}
return image;
}
private BitmapSource ImageToBitmapSource(Image<Gray, byte> image)
{
int width = image.Width;
int height = image.Height;
int stride = width;
byte[] pixels = new byte[width * height];
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
pixels[y * stride + x] = image.Data[y, x, 0];
}
}
var bitmapSource = BitmapSource.Create(
width, height, 96, 96,
PixelFormats.Gray8, null, pixels, stride);
bitmapSource.Freeze();
return bitmapSource;
}
private void ExecuteOpenLanguageSwitcher()
{
try
+5
View File
@@ -167,6 +167,7 @@
Text="辅助线" />
<telerik:RadRibbonButton
telerik:ScreenTip.Title="白底检测"
Command="{Binding WhiteBackgroundDetectionCommand}"
Size="Medium"
SmallImage="/Assets/Icons/film-darken.png"
Text="白底检测" />
@@ -174,11 +175,13 @@
<StackPanel>
<telerik:RadRibbonButton
telerik:ScreenTip.Title="灰度"
Command="{Binding GrayscaleCommand}"
Size="Medium"
SmallImage="/Assets/Icons/film-darken.png"
Text="灰度" />
<telerik:RadRibbonButton
telerik:ScreenTip.Title="黑底检测"
Command="{Binding BlackBackgroundDetectionCommand}"
Size="Medium"
SmallImage="/Assets/Icons/film-darken.png"
Text="黑底检测" />
@@ -186,11 +189,13 @@
<StackPanel>
<telerik:RadRibbonButton
telerik:ScreenTip.Title="锐化"
Command="{Binding SharpenCommand}"
Size="Medium"
SmallImage="/Assets/Icons/sharpen.png"
Text="锐化" />
<telerik:RadRibbonButton
telerik:ScreenTip.Title="增强"
Command="{Binding EnhanceCommand}"
Size="Medium"
SmallImage="/Assets/Icons/dynamic-range.png"
Text="增强" />