181 lines
5.6 KiB
C#
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;
|
|
}
|
|
} |