// ============================================================================ // 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 Serilog; using XP.ImageProcessing.Core; 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; } }