// ============================================================================ // Copyright © 2026 Hexagon Technology Center GmbH. All Rights Reserved. // 文件名: ThresholdProcessor.cs // 描述: 阈值分割算子,用于图像二值化处理 // 功能: // - 固定阈值二值化 // - Otsu自动阈值计算 // - 可调节阈值和最大值 // - 将灰度图像转换为二值图像 // 算法: 阈值分割、Otsu算法 // 作者: 李伟 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 ThresholdProcessor : ImageProcessorBase { private static readonly ILogger _logger = Log.ForContext(); public ThresholdProcessor() { Name = LocalizationHelper.GetString("ThresholdProcessor_Name"); Description = LocalizationHelper.GetString("ThresholdProcessor_Description"); } protected override void InitializeParameters() { Parameters.Add("MinThreshold", new ProcessorParameter( "MinThreshold", LocalizationHelper.GetString("ThresholdProcessor_MinThreshold"), typeof(int), 64, 0, 255, LocalizationHelper.GetString("ThresholdProcessor_MinThreshold_Desc"))); Parameters.Add("MaxThreshold", new ProcessorParameter( "MaxThreshold", LocalizationHelper.GetString("ThresholdProcessor_MaxThreshold"), typeof(int), 192, 0, 255, LocalizationHelper.GetString("ThresholdProcessor_MaxThreshold_Desc"))); Parameters.Add("UseOtsu", new ProcessorParameter( "UseOtsu", LocalizationHelper.GetString("ThresholdProcessor_UseOtsu"), typeof(bool), false, null, null, LocalizationHelper.GetString("ThresholdProcessor_UseOtsu_Desc"))); _logger.Debug("InitializeParameters"); } public override Image Process(Image inputImage) { int minThreshold = GetParameter("MinThreshold"); int maxThreshold = GetParameter("MaxThreshold"); bool useOtsu = GetParameter("UseOtsu"); var result = new Image(inputImage.Size); if (useOtsu) { // 使用Otsu算法 CvInvoke.Threshold(inputImage, result, minThreshold, 255, ThresholdType.Otsu); _logger.Debug("Process: UseOtsu = true"); } else { // 双阈值分割:介于MinThreshold和MaxThreshold之间的为前景(255),其他为背景(0) byte[,,] inputData = inputImage.Data; byte[,,] outputData = result.Data; int height = inputImage.Height; int width = inputImage.Width; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { byte pixelValue = inputData[y, x, 0]; outputData[y, x, 0] = (pixelValue >= minThreshold && pixelValue <= maxThreshold) ? (byte)255 : (byte)0; } } _logger.Debug("Process: MinThreshold = {MinThreshold}, MaxThreshold = {MaxThreshold}", minThreshold, maxThreshold); } return result; } }