// ============================================================================ // Copyright © 2026 Hexagon Technology Center GmbH. All Rights Reserved. // 文件名: ImageProcessorBase.cs // 描述: 8位图像处理算子基类,定义图像处理算子的通用接口和行为 // 功能: // - 定义算子的基本属性(名称、描述) // - 参数管理(设置、获取、验证) // - ROI(感兴趣区域)处理支持 // - 输出数据管理(用于传递额外信息如轮廓等) // - 为所有8位图像处理算子提供统一的基础框架 // 设计模式: 模板方法模式 // 作者: 李伟 wei.lw.li@hexagon.com // ============================================================================ using Emgu.CV; using Emgu.CV.Structure; using Emgu.CV.Util; namespace ImageProcessing.Core; /// /// 图像处理算子基类 /// public abstract class ImageProcessorBase { /// 算子名称 public string Name { get; protected set; } = string.Empty; /// 算子描述 public string Description { get; protected set; } = string.Empty; /// 参数字典 protected Dictionary Parameters { get; set; } /// 输出数据(用于传递额外信息如轮廓等) public Dictionary OutputData { get; protected set; } /// ROI区域 public System.Drawing.Rectangle? ROI { get; set; } /// 多边形ROI点集 public System.Drawing.Point[]? PolygonROIPoints { get; set; } protected ImageProcessorBase() { Parameters = new Dictionary(); OutputData = new Dictionary(); InitializeParameters(); } /// /// 初始化算子参数(子类实现) /// protected abstract void InitializeParameters(); /// /// 执行图像处理(子类实现) /// public abstract Image Process(Image inputImage); /// /// 执行图像处理(带矩形ROI支持) /// public Image ProcessWithROI(Image inputImage) { if (ROI.HasValue && ROI.Value != System.Drawing.Rectangle.Empty) { inputImage.ROI = ROI.Value; var roiImage = inputImage.Copy(); inputImage.ROI = System.Drawing.Rectangle.Empty; var processedROI = Process(roiImage); // 将 ROI 偏移量保存到输出数据中,供轮廓绘制等使用 OutputData["ROIOffset"] = new System.Drawing.Point(ROI.Value.X, ROI.Value.Y); var result = inputImage.Clone(); result.ROI = ROI.Value; processedROI.CopyTo(result); result.ROI = System.Drawing.Rectangle.Empty; roiImage.Dispose(); processedROI.Dispose(); return result; } return Process(inputImage); } /// /// 执行图像处理(带多边形ROI掩码支持) /// public Image ProcessWithPolygonROI(Image inputImage) { if (PolygonROIPoints == null || PolygonROIPoints.Length < 3) { return Process(inputImage); } // 创建掩码 var mask = new Image(inputImage.Width, inputImage.Height); mask.SetValue(new Gray(0)); // 绘制多边形掩码(白色表示ROI区域) using (var vop = new VectorOfPoint(PolygonROIPoints)) { using (var vvop = new VectorOfVectorOfPoint(vop)) { CvInvoke.DrawContours(mask, vvop, 0, new MCvScalar(255), -1); } } // 处理整个图像 var processedImage = Process(inputImage); // 创建结果图像 var result = inputImage.Clone(); // 使用掩码:ROI内使用处理后的像素,ROI外保持原始像素 for (int y = 0; y < inputImage.Height; y++) { for (int x = 0; x < inputImage.Width; x++) { if (mask.Data[y, x, 0] > 0) // 在ROI内 { result.Data[y, x, 0] = processedImage.Data[y, x, 0]; } } } // 保存ROI信息 OutputData["ROIMask"] = mask; OutputData["PolygonPoints"] = PolygonROIPoints; OutputData["ROIOffset"] = System.Drawing.Point.Empty; processedImage.Dispose(); return result; } /// /// 获取所有参数列表 /// public List GetParameters() { return new List(Parameters.Values); } /// /// 设置参数值 /// public void SetParameter(string name, object value) { if (Parameters.ContainsKey(name)) { Parameters[name].Value = value; } else { throw new ArgumentException($"参数 {name} 不存在"); } } /// /// 获取参数值 /// public T GetParameter(string name) { if (Parameters.ContainsKey(name)) { return (T)Convert.ChangeType(Parameters[name].Value, typeof(T))!; } throw new ArgumentException($"参数 {name} 不存在"); } /// /// 获取单个参数 /// public ProcessorParameter? GetParameterInfo(string name) { return Parameters.ContainsKey(name) ? Parameters[name] : null; } }