Files
XplorePlane/XP.ImageProcessing.Processors/边缘检测/KirschEdgeProcessor.cs
T
2026-04-13 14:36:18 +08:00

133 lines
4.4 KiB
C#

// ============================================================================
// Copyright 穢 2026 Hexagon Technology Center GmbH. All Rights Reserved.
// ? KirschEdgeProcessor.cs
// 讛膩: Kirsch颲寧瘚讠摮琜瘚见㦛讛器蝻?
// :
// - Kirsch蝞堒颲寧瘚?
// - 8銝芣䲮𤑳颲寧瘚?
// - 颲枏枂憭批摨娍䲮𤑳颲寧
// - 撖孵臁憯唳笔漲雿?
// 蝞埈: Kirsch蝞堒嚗?璅⊥踎嚗?
// 雿𡏭? 𦒘 wei.lw.li@hexagon.com
// ============================================================================
using Emgu.CV;
using Emgu.CV.Structure;
using Serilog;
using XP.ImageProcessing.Core;
namespace XP.ImageProcessing.Processors;
/// <summary>
/// Kirsch颲寧瘚讠摮?
/// </summary>
public class KirschEdgeProcessor : ImageProcessorBase
{
private static readonly ILogger _logger = Log.ForContext<KirschEdgeProcessor>();
// Kirsch蝞堒?銝芣䲮烐芋?
private static readonly int[][,] KirschKernels = new int[8][,]
{
// N
new int[,] { { 5, 5, 5 }, { -3, 0, -3 }, { -3, -3, -3 } },
// NW
new int[,] { { 5, 5, -3 }, { 5, 0, -3 }, { -3, -3, -3 } },
// W
new int[,] { { 5, -3, -3 }, { 5, 0, -3 }, { 5, -3, -3 } },
// SW
new int[,] { { -3, -3, -3 }, { 5, 0, -3 }, { 5, 5, -3 } },
// S
new int[,] { { -3, -3, -3 }, { -3, 0, -3 }, { 5, 5, 5 } },
// SE
new int[,] { { -3, -3, -3 }, { -3, 0, 5 }, { -3, 5, 5 } },
// E
new int[,] { { -3, -3, 5 }, { -3, 0, 5 }, { -3, -3, 5 } },
// NE
new int[,] { { -3, 5, 5 }, { -3, 0, 5 }, { -3, -3, -3 } }
};
public KirschEdgeProcessor()
{
Name = LocalizationHelper.GetString("KirschEdgeProcessor_Name");
Description = LocalizationHelper.GetString("KirschEdgeProcessor_Description");
}
protected override void InitializeParameters()
{
Parameters.Add("Threshold", new ProcessorParameter(
"Threshold",
LocalizationHelper.GetString("KirschEdgeProcessor_Threshold"),
typeof(int),
100,
0,
1000,
LocalizationHelper.GetString("KirschEdgeProcessor_Threshold_Desc")));
Parameters.Add("Scale", new ProcessorParameter(
"Scale",
LocalizationHelper.GetString("KirschEdgeProcessor_Scale"),
typeof(double),
1.0,
0.1,
5.0,
LocalizationHelper.GetString("KirschEdgeProcessor_Scale_Desc")));
_logger.Debug("InitializeParameters");
}
public override Image<Gray, byte> Process(Image<Gray, byte> inputImage)
{
int threshold = GetParameter<int>("Threshold");
double scale = GetParameter<double>("Scale");
int width = inputImage.Width;
int height = inputImage.Height;
byte[,,] inputData = inputImage.Data;
Image<Gray, byte> result = new Image<Gray, byte>(width, height);
byte[,,] outputData = result.Data;
// 撖寞銝芸蝝惩?銝枝irsch璅⊥踎嚗憭批摨?
for (int y = 1; y < height - 1; y++)
{
for (int x = 1; x < width - 1; x++)
{
int maxResponse = 0;
// 撖?銝芣䲮怨恣蝞?
for (int k = 0; k < 8; k++)
{
int sum = 0;
for (int ky = 0; ky < 3; ky++)
{
for (int kx = 0; kx < 3; kx++)
{
int pixelValue = inputData[y + ky - 1, x + kx - 1, 0];
sum += pixelValue * KirschKernels[k][ky, kx];
}
}
// 𣇉撖孵?
sum = Math.Abs(sum);
if (sum > maxResponse)
{
maxResponse = sum;
}
}
// 摨𠉛鍂蝻拇𦆮
if (maxResponse > threshold)
{
int value = (int)(maxResponse * scale);
outputData[y, x, 0] = (byte)Math.Min(255, Math.Max(0, value));
}
else
{
outputData[y, x, 0] = 0;
}
}
}
_logger.Debug("Process: Threshold = {Threshold}, Scale = {Scale}", threshold, scale);
return result;
}
}