7768c086ea
高级参数标记:Contrast(Contrast,Brightness,UseCLAHE,ClipLimit)、 Gamma(Gain)、Sharpen(Method,KernelSize)、Emboss(BlendRatio,GrayOffset)、 HistogramEq(Method,TileSize)、HDR(Method,Saturation,SigmaSpace,SigmaColor,Bias)、 Hierarchical(BaseGain,ClipLimit)、Retinex(Method,Sigma1/2/3,Offset)、 Rotate(ExpandCanvas,BackgroundValue,Interpolation) 默认值优化(适配平面CT DR图像): - Sharpen: Laplacian→UnsharpMask(对噪声更温和) - HistogramEq: Global→CLAHE(局部对比度更优) - Contrast: AutoContrast默认开启
102 lines
3.7 KiB
C#
102 lines
3.7 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>
|
||
/// 锐化算子(支持 8 位和 16 位灰度图像)
|
||
/// </summary>
|
||
public class SharpenProcessor<TDepth> : ImageProcessorBase<TDepth>
|
||
where TDepth : struct, IComparable
|
||
{
|
||
private static readonly ILogger _logger = Log.ForContext<SharpenProcessor<TDepth>>();
|
||
|
||
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),
|
||
"UnsharpMask",
|
||
null,
|
||
null,
|
||
LocalizationHelper.GetString("SharpenProcessor_Method_Desc"),
|
||
new string[] { "Laplacian", "UnsharpMask" }) { IsAdvanced = true });
|
||
|
||
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")) { IsAdvanced = true });
|
||
_logger.Debug("InitializeParameters");
|
||
}
|
||
|
||
public override Image<Gray, TDepth> Process(Image<Gray, TDepth> inputImage)
|
||
{
|
||
string method = GetParameter<string>("Method");
|
||
double strength = GetParameter<double>("Strength");
|
||
int kernelSize = GetParameter<int>("KernelSize");
|
||
if (kernelSize % 2 == 0) kernelSize++;
|
||
|
||
var floatInput = inputImage.Convert<Gray, float>();
|
||
Image<Gray, float> sharpened;
|
||
|
||
if (method == "UnsharpMask")
|
||
{
|
||
var blurred = new Image<Gray, float>(inputImage.Size);
|
||
CvInvoke.GaussianBlur(floatInput, blurred, new System.Drawing.Size(kernelSize, kernelSize), 0);
|
||
var detail = floatInput - blurred;
|
||
sharpened = floatInput + detail * strength;
|
||
blurred.Dispose();
|
||
detail.Dispose();
|
||
}
|
||
else // Laplacian
|
||
{
|
||
var laplacian = new Image<Gray, float>(inputImage.Size);
|
||
CvInvoke.Laplacian(inputImage, laplacian, DepthType.Cv32F, 1);
|
||
sharpened = floatInput + laplacian * strength;
|
||
laplacian.Dispose();
|
||
}
|
||
|
||
floatInput.Dispose();
|
||
var result = PixelDepthHelper.FromFloatImage<TDepth>(sharpened);
|
||
sharpened.Dispose();
|
||
|
||
_logger.Debug("Process: Method={M}, Strength={S}, KernelSize={K}", method, strength, kernelSize);
|
||
return result;
|
||
}
|
||
} |