141 lines
4.5 KiB
C#
141 lines
4.5 KiB
C#
// ============================================================================
|
||
// 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;
|
||
|
||
/// <summary>
|
||
/// 锐化算子
|
||
/// </summary>
|
||
public class SharpenProcessor : ImageProcessorBase
|
||
{
|
||
private static readonly ILogger _logger = Log.ForContext<SharpenProcessor>();
|
||
|
||
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<Gray, byte> Process(Image<Gray, byte> inputImage)
|
||
{
|
||
string method = GetParameter<string>("Method");
|
||
double strength = GetParameter<double>("Strength");
|
||
int kernelSize = GetParameter<int>("KernelSize");
|
||
|
||
if (kernelSize % 2 == 0) kernelSize++;
|
||
|
||
Image<Gray, byte> 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<Gray, byte> ApplyLaplacianSharpening(Image<Gray, byte> inputImage, double strength)
|
||
{
|
||
// 计算拉普拉斯算子
|
||
var laplacian = new Image<Gray, float>(inputImage.Size);
|
||
CvInvoke.Laplacian(inputImage, laplacian, DepthType.Cv32F, 1);
|
||
|
||
// 转换为字节类型
|
||
var laplacianByte = laplacian.Convert<Gray, byte>();
|
||
|
||
// 将拉普拉斯结果加到原图上进行锐化
|
||
var floatImage = inputImage.Convert<Gray, float>();
|
||
var sharpened = floatImage + laplacian * strength;
|
||
|
||
// 限制范围并转换回字节类型
|
||
var result = sharpened.Convert<Gray, byte>();
|
||
|
||
laplacian.Dispose();
|
||
laplacianByte.Dispose();
|
||
floatImage.Dispose();
|
||
sharpened.Dispose();
|
||
|
||
return result;
|
||
}
|
||
|
||
private Image<Gray, byte> ApplyUnsharpMask(Image<Gray, byte> inputImage, int kernelSize, double strength)
|
||
{
|
||
// 创建模糊图像
|
||
var blurred = new Image<Gray, byte>(inputImage.Size);
|
||
CvInvoke.GaussianBlur(inputImage, blurred,
|
||
new System.Drawing.Size(kernelSize, kernelSize), 0);
|
||
|
||
// 计算差异(细节)
|
||
var floatInput = inputImage.Convert<Gray, float>();
|
||
var floatBlurred = blurred.Convert<Gray, float>();
|
||
var detail = floatInput - floatBlurred;
|
||
|
||
// 将细节加回原图
|
||
var sharpened = floatInput + detail * strength;
|
||
|
||
// 转换回字节类型
|
||
var result = sharpened.Convert<Gray, byte>();
|
||
|
||
blurred.Dispose();
|
||
floatInput.Dispose();
|
||
floatBlurred.Dispose();
|
||
detail.Dispose();
|
||
sharpened.Dispose();
|
||
|
||
return result;
|
||
}
|
||
} |