106 lines
3.5 KiB
C#
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 XP.ImageProcessing.Core;
|
|
using Serilog;
|
|
|
|
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;
|
|
}
|
|
} |