// ============================================================================
// Copyright © 2026 Hexagon Technology Center GmbH. All Rights Reserved.
// 文件名: SharpenProcessor.cs
// 描述: 锐化算子,用于增强图像边缘和细节
// 功能:
// - 拉普拉斯锐化
// - 非锐化掩蔽(Unsharp Masking)
// - 可调节锐化强度
// - 支持多种锐化核
// 算法: 拉普拉斯算子、非锐化掩蔽
// 作者: 李伟 wei.lw.li@hexagon.com
// ============================================================================
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using XP.ImageProcessing.Core;
using Serilog;
namespace XP.ImageProcessing.Processors;
///
/// 锐化算子
///
public class SharpenProcessor : ImageProcessorBase
{
private static readonly ILogger _logger = Log.ForContext();
public SharpenProcessor()
{
Name = LocalizationHelper.GetString("SharpenProcessor_Name");
Description = LocalizationHelper.GetString("SharpenProcessor_Description");
}
protected override void InitializeParameters()
{
Parameters.Add("Method", new ProcessorParameter(
"Method",
LocalizationHelper.GetString("SharpenProcessor_Method"),
typeof(string),
"Laplacian",
null,
null,
LocalizationHelper.GetString("SharpenProcessor_Method_Desc"),
new string[] { "Laplacian", "UnsharpMask" }));
Parameters.Add("Strength", new ProcessorParameter(
"Strength",
LocalizationHelper.GetString("SharpenProcessor_Strength"),
typeof(double),
1.0,
0.1,
5.0,
LocalizationHelper.GetString("SharpenProcessor_Strength_Desc")));
Parameters.Add("KernelSize", new ProcessorParameter(
"KernelSize",
LocalizationHelper.GetString("SharpenProcessor_KernelSize"),
typeof(int),
3,
1,
15,
LocalizationHelper.GetString("SharpenProcessor_KernelSize_Desc")));
_logger.Debug("InitializeParameters");
}
public override Image Process(Image inputImage)
{
string method = GetParameter("Method");
double strength = GetParameter("Strength");
int kernelSize = GetParameter("KernelSize");
if (kernelSize % 2 == 0) kernelSize++;
Image result;
if (method == "UnsharpMask")
{
result = ApplyUnsharpMask(inputImage, kernelSize, strength);
}
else // Laplacian
{
result = ApplyLaplacianSharpening(inputImage, strength);
}
_logger.Debug("Process: Method = {Method}, Strength = {Strength}, KernelSize = {KernelSize}",
method, strength, kernelSize);
return result;
}
private Image ApplyLaplacianSharpening(Image inputImage, double strength)
{
// 计算拉普拉斯算子
var laplacian = new Image(inputImage.Size);
CvInvoke.Laplacian(inputImage, laplacian, DepthType.Cv32F, 1);
// 转换为字节类型
var laplacianByte = laplacian.Convert();
// 将拉普拉斯结果加到原图上进行锐化
var floatImage = inputImage.Convert();
var sharpened = floatImage + laplacian * strength;
// 限制范围并转换回字节类型
var result = sharpened.Convert();
laplacian.Dispose();
laplacianByte.Dispose();
floatImage.Dispose();
sharpened.Dispose();
return result;
}
private Image ApplyUnsharpMask(Image inputImage, int kernelSize, double strength)
{
// 创建模糊图像
var blurred = new Image(inputImage.Size);
CvInvoke.GaussianBlur(inputImage, blurred,
new System.Drawing.Size(kernelSize, kernelSize), 0);
// 计算差异(细节)
var floatInput = inputImage.Convert();
var floatBlurred = blurred.Convert();
var detail = floatInput - floatBlurred;
// 将细节加回原图
var sharpened = floatInput + detail * strength;
// 转换回字节类型
var result = sharpened.Convert();
blurred.Dispose();
floatInput.Dispose();
floatBlurred.Dispose();
detail.Dispose();
sharpened.Dispose();
return result;
}
}