// ============================================================================ // Copyright © 2026 Hexagon Technology Center GmbH. All Rights Reserved. // 文件名: HorizontalEdgeProcessor.cs // 描述: 水平边缘检测算子,专门用于检测水平方向的边缘 // 功能: // - 检测水平边缘 // - 支持Prewitt和Sobel算子 // - 可调节检测灵敏度 // - 适用于检测水平线条和纹理 // 算法: Prewitt/Sobel水平算子 // 作者: 李伟 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 HorizontalEdgeProcessor : ImageProcessorBase { private static readonly ILogger _logger = Log.ForContext(); public HorizontalEdgeProcessor() { Name = LocalizationHelper.GetString("HorizontalEdgeProcessor_Name"); Description = LocalizationHelper.GetString("HorizontalEdgeProcessor_Description"); } protected override void InitializeParameters() { Parameters.Add("Method", new ProcessorParameter( "Method", LocalizationHelper.GetString("HorizontalEdgeProcessor_Method"), typeof(string), "Sobel", null, null, LocalizationHelper.GetString("HorizontalEdgeProcessor_Method_Desc"), new string[] { "Sobel", "Prewitt", "Simple" })); Parameters.Add("Sensitivity", new ProcessorParameter( "Sensitivity", LocalizationHelper.GetString("HorizontalEdgeProcessor_Sensitivity"), typeof(double), 1.0, 0.1, 5.0, LocalizationHelper.GetString("HorizontalEdgeProcessor_Sensitivity_Desc"))); Parameters.Add("Threshold", new ProcessorParameter( "Threshold", LocalizationHelper.GetString("HorizontalEdgeProcessor_Threshold"), typeof(int), 20, 0, 255, LocalizationHelper.GetString("HorizontalEdgeProcessor_Threshold_Desc"))); _logger.Debug("InitializeParameters"); } public override Image Process(Image inputImage) { string method = GetParameter("Method"); double sensitivity = GetParameter("Sensitivity"); int threshold = GetParameter("Threshold"); Image result; if (method == "Sobel") { result = ApplySobel(inputImage, sensitivity, threshold); } else if (method == "Prewitt") { result = ApplyPrewitt(inputImage, sensitivity, threshold); } else // Simple { result = ApplySimple(inputImage, sensitivity, threshold); } _logger.Debug("Process: Method = {Method}, Sensitivity = {Sensitivity}, Threshold = {Threshold}", method, sensitivity, threshold); return result; } private Image ApplySobel(Image inputImage, double sensitivity, int threshold) { // 使用Sobel算子检测水平边缘(Y方向导数) Image sobelY = new Image(inputImage.Size); CvInvoke.Sobel(inputImage, sobelY, DepthType.Cv32F, 0, 1, 3); // 转换为绝对值并应用灵敏度 Image result = new Image(inputImage.Size); CvInvoke.ConvertScaleAbs(sobelY, result, sensitivity, 0); // 应用阈值 if (threshold > 0) { CvInvoke.Threshold(result, result, threshold, 255, ThresholdType.Binary); CvInvoke.Threshold(result, result, 0, 255, ThresholdType.ToZero); } sobelY.Dispose(); return result; } private Image ApplyPrewitt(Image inputImage, double sensitivity, int threshold) { // Prewitt水平算子 // [ 1 1 1] // [ 0 0 0] // [-1 -1 -1] int width = inputImage.Width; int height = inputImage.Height; byte[,,] inputData = inputImage.Data; Image result = new Image(width, height); byte[,,] outputData = result.Data; for (int y = 1; y < height - 1; y++) { for (int x = 1; x < width - 1; x++) { int sum = 0; // 上行 sum += inputData[y - 1, x - 1, 0]; sum += inputData[y - 1, x, 0]; sum += inputData[y - 1, x + 1, 0]; // 下行 sum -= inputData[y + 1, x - 1, 0]; sum -= inputData[y + 1, x, 0]; sum -= inputData[y + 1, x + 1, 0]; // 取绝对值并应用灵敏度 int value = (int)(Math.Abs(sum) * sensitivity); // 应用阈值 if (value > threshold) { outputData[y, x, 0] = (byte)Math.Min(255, value); } else { outputData[y, x, 0] = 0; } } } return result; } private Image ApplySimple(Image inputImage, double sensitivity, int threshold) { // 简单差分算子 // [ 1 1 1] // [ 0 0 0] // [-1 -1 -1] // 但权重更简单 int width = inputImage.Width; int height = inputImage.Height; byte[,,] inputData = inputImage.Data; Image result = new Image(width, height); byte[,,] outputData = result.Data; for (int y = 1; y < height - 1; y++) { for (int x = 0; x < width; x++) { // 简单的上下差分 int diff = inputData[y - 1, x, 0] - inputData[y + 1, x, 0]; int value = (int)(Math.Abs(diff) * sensitivity); // 应用阈值 if (value > threshold) { outputData[y, x, 0] = (byte)Math.Min(255, value); } else { outputData[y, x, 0] = 0; } } } return result; } }