Files
XplorePlane/ImageProcessing.Core/ImageProcessorBase.cs
T
2026-04-13 13:41:40 +08:00

181 lines
5.6 KiB
C#

// ============================================================================
// 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;
/// <summary>
/// 图像处理算子基类
/// </summary>
public abstract class ImageProcessorBase
{
/// <summary>算子名称</summary>
public string Name { get; protected set; } = string.Empty;
/// <summary>算子描述</summary>
public string Description { get; protected set; } = string.Empty;
/// <summary>参数字典</summary>
protected Dictionary<string, ProcessorParameter> Parameters { get; set; }
/// <summary>输出数据(用于传递额外信息如轮廓等)</summary>
public Dictionary<string, object> OutputData { get; protected set; }
/// <summary>ROI区域</summary>
public System.Drawing.Rectangle? ROI { get; set; }
/// <summary>多边形ROI点集</summary>
public System.Drawing.Point[]? PolygonROIPoints { get; set; }
protected ImageProcessorBase()
{
Parameters = new Dictionary<string, ProcessorParameter>();
OutputData = new Dictionary<string, object>();
InitializeParameters();
}
/// <summary>
/// 初始化算子参数(子类实现)
/// </summary>
protected abstract void InitializeParameters();
/// <summary>
/// 执行图像处理(子类实现)
/// </summary>
public abstract Image<Gray, byte> Process(Image<Gray, byte> inputImage);
/// <summary>
/// 执行图像处理(带矩形ROI支持)
/// </summary>
public Image<Gray, byte> ProcessWithROI(Image<Gray, byte> 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);
}
/// <summary>
/// 执行图像处理(带多边形ROI掩码支持)
/// </summary>
public Image<Gray, byte> ProcessWithPolygonROI(Image<Gray, byte> inputImage)
{
if (PolygonROIPoints == null || PolygonROIPoints.Length < 3)
{
return Process(inputImage);
}
// 创建掩码
var mask = new Image<Gray, byte>(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;
}
/// <summary>
/// 获取所有参数列表
/// </summary>
public List<ProcessorParameter> GetParameters()
{
return new List<ProcessorParameter>(Parameters.Values);
}
/// <summary>
/// 设置参数值
/// </summary>
public void SetParameter(string name, object value)
{
if (Parameters.ContainsKey(name))
{
Parameters[name].Value = value;
}
else
{
throw new ArgumentException($"参数 {name} 不存在");
}
}
/// <summary>
/// 获取参数值
/// </summary>
public T GetParameter<T>(string name)
{
if (Parameters.ContainsKey(name))
{
return (T)Convert.ChangeType(Parameters[name].Value, typeof(T))!;
}
throw new ArgumentException($"参数 {name} 不存在");
}
/// <summary>
/// 获取单个参数
/// </summary>
public ProcessorParameter? GetParameterInfo(string name)
{
return Parameters.ContainsKey(name) ? Parameters[name] : null;
}
}