// ============================================================================ // Copyright © 2026 Hexagon Technology Center GmbH. All Rights Reserved. // 文件? SobelEdgeProcessor.cs // 描述: Sobel边缘检测算子,用于检测图像边? // 功能: // - Sobel算子边缘检? // - 支持X方向、Y方向和组合检? // - 可调节核大小 // - 输出边缘强度? // 算法: Sobel算子 // 作? 李伟 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; /// /// Sobel边缘检测算? /// public class SobelEdgeProcessor : ImageProcessorBase { private static readonly ILogger _logger = Log.ForContext(); public SobelEdgeProcessor() { Name = LocalizationHelper.GetString("SobelEdgeProcessor_Name"); Description = LocalizationHelper.GetString("SobelEdgeProcessor_Description"); } protected override void InitializeParameters() { Parameters.Add("Direction", new ProcessorParameter( "Direction", LocalizationHelper.GetString("SobelEdgeProcessor_Direction"), typeof(string), "Both", null, null, LocalizationHelper.GetString("SobelEdgeProcessor_Direction_Desc"), new string[] { "Both", "Horizontal", "Vertical" })); Parameters.Add("KernelSize", new ProcessorParameter( "KernelSize", LocalizationHelper.GetString("SobelEdgeProcessor_KernelSize"), typeof(int), 3, 1, 7, LocalizationHelper.GetString("SobelEdgeProcessor_KernelSize_Desc"))); Parameters.Add("Scale", new ProcessorParameter( "Scale", LocalizationHelper.GetString("SobelEdgeProcessor_Scale"), typeof(double), 1.0, 0.1, 5.0, LocalizationHelper.GetString("SobelEdgeProcessor_Scale_Desc"))); _logger.Debug("InitializeParameters"); } public override Image Process(Image inputImage) { string direction = GetParameter("Direction"); int kernelSize = GetParameter("KernelSize"); double scale = GetParameter("Scale"); // 确保核大小为奇数 if (kernelSize % 2 == 0) kernelSize++; if (kernelSize > 7) kernelSize = 7; if (kernelSize < 1) kernelSize = 1; Image sobelX = new Image(inputImage.Size); Image sobelY = new Image(inputImage.Size); Image result = new Image(inputImage.Size); if (direction == "Horizontal" || direction == "Both") { // X方向(水平边缘) CvInvoke.Sobel(inputImage, sobelX, DepthType.Cv32F, 1, 0, kernelSize); } if (direction == "Vertical" || direction == "Both") { // Y方向(垂直边缘) CvInvoke.Sobel(inputImage, sobelY, DepthType.Cv32F, 0, 1, kernelSize); } if (direction == "Both") { // 计算梯度幅值:sqrt(Gx^2 + Gy^2) Image magnitude = new Image(inputImage.Size); // 手动计算幅? for (int y = 0; y < inputImage.Height; y++) { for (int x = 0; x < inputImage.Width; x++) { float gx = sobelX.Data[y, x, 0]; float gy = sobelY.Data[y, x, 0]; magnitude.Data[y, x, 0] = (float)Math.Sqrt(gx * gx + gy * gy); } } // 应用缩放并转换为字节类型 var scaled = magnitude * scale; result = scaled.Convert(); magnitude.Dispose(); scaled.Dispose(); } else if (direction == "Horizontal") { // 只使用X方向 CvInvoke.ConvertScaleAbs(sobelX, result, scale, 0); } else // Vertical { // 只使用Y方向 CvInvoke.ConvertScaleAbs(sobelY, result, scale, 0); } sobelX.Dispose(); sobelY.Dispose(); _logger.Debug("Process: Direction = {Direction}, KernelSize = {KernelSize}, Scale = {Scale}", direction, kernelSize, scale); return result; } }