为主界面快捷工具栏添加图像处理命令接口:白底检测、黑底检测、灰度、锐化、增强,实现锐化和增强
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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="增强" />
|
||||
|
||||
Reference in New Issue
Block a user