Files
XplorePlane/XP.ImageProcessing.Processors/图像变换/ThresholdProcessor.cs
T
2026-04-13 14:36:18 +08:00

106 lines
3.5 KiB
C#

// ============================================================================
// 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 Serilog;
using XP.ImageProcessing.Core;
namespace XP.ImageProcessing.Processors;
/// <summary>
/// 阈值分割算�
/// </summary>
public class ThresholdProcessor : ImageProcessorBase
{
private static readonly ILogger _logger = Log.ForContext<ThresholdProcessor>();
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<Gray, byte> Process(Image<Gray, byte> inputImage)
{
int minThreshold = GetParameter<int>("MinThreshold");
int maxThreshold = GetParameter<int>("MaxThreshold");
bool useOtsu = GetParameter<bool>("UseOtsu");
var result = new Image<Gray, byte>(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;
}
}