规范类名及命名空间名称
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
// ============================================================================
|
||||
// Copyright © 2026 Hexagon Technology Center GmbH. All Rights Reserved.
|
||||
// 文件� HistogramEqualizationProcessor.cs
|
||||
// æ��è¿°: 直方图å�‡è¡¡åŒ–ç®—å�,用于增强图åƒ�对比度
|
||||
// 功能:
|
||||
// - 全局直方图�衡化
|
||||
// - 自适应直方图�衡化(CLAHE�
|
||||
// - �制对比度增�
|
||||
// - 改善图�的整体对比度
|
||||
// 算法: 直方图�衡化�CLAHE
|
||||
// 作� �伟 wei.lw.li@hexagon.com
|
||||
// ============================================================================
|
||||
|
||||
using Emgu.CV;
|
||||
using Emgu.CV.Structure;
|
||||
using Serilog;
|
||||
using XP.ImageProcessing.Core;
|
||||
|
||||
namespace XP.ImageProcessing.Processors;
|
||||
|
||||
/// <summary>
|
||||
/// 直方图å�‡è¡¡åŒ–ç®—å�
|
||||
/// </summary>
|
||||
public class HistogramEqualizationProcessor : ImageProcessorBase
|
||||
{
|
||||
private static readonly ILogger _logger = Log.ForContext<HistogramEqualizationProcessor>();
|
||||
|
||||
public HistogramEqualizationProcessor()
|
||||
{
|
||||
Name = LocalizationHelper.GetString("HistogramEqualizationProcessor_Name");
|
||||
Description = LocalizationHelper.GetString("HistogramEqualizationProcessor_Description");
|
||||
}
|
||||
|
||||
protected override void InitializeParameters()
|
||||
{
|
||||
Parameters.Add("Method", new ProcessorParameter(
|
||||
"Method",
|
||||
LocalizationHelper.GetString("HistogramEqualizationProcessor_Method"),
|
||||
typeof(string),
|
||||
"Global",
|
||||
null,
|
||||
null,
|
||||
LocalizationHelper.GetString("HistogramEqualizationProcessor_Method_Desc"),
|
||||
new string[] { "Global", "CLAHE" }));
|
||||
|
||||
Parameters.Add("ClipLimit", new ProcessorParameter(
|
||||
"ClipLimit",
|
||||
LocalizationHelper.GetString("HistogramEqualizationProcessor_ClipLimit"),
|
||||
typeof(double),
|
||||
2.0,
|
||||
1.0,
|
||||
10.0,
|
||||
LocalizationHelper.GetString("HistogramEqualizationProcessor_ClipLimit_Desc")));
|
||||
|
||||
Parameters.Add("TileSize", new ProcessorParameter(
|
||||
"TileSize",
|
||||
LocalizationHelper.GetString("HistogramEqualizationProcessor_TileSize"),
|
||||
typeof(int),
|
||||
8,
|
||||
4,
|
||||
32,
|
||||
LocalizationHelper.GetString("HistogramEqualizationProcessor_TileSize_Desc")));
|
||||
_logger.Debug("InitializeParameters");
|
||||
}
|
||||
|
||||
public override Image<Gray, byte> Process(Image<Gray, byte> inputImage)
|
||||
{
|
||||
string method = GetParameter<string>("Method");
|
||||
double clipLimit = GetParameter<double>("ClipLimit");
|
||||
int tileSize = GetParameter<int>("TileSize");
|
||||
|
||||
Image<Gray, byte> result;
|
||||
|
||||
if (method == "CLAHE")
|
||||
{
|
||||
result = ApplyCLAHE(inputImage, clipLimit, tileSize);
|
||||
}
|
||||
else // Global
|
||||
{
|
||||
result = new Image<Gray, byte>(inputImage.Size);
|
||||
CvInvoke.EqualizeHist(inputImage, result);
|
||||
}
|
||||
|
||||
_logger.Debug("Process: Method = {Method}, ClipLimit = {ClipLimit}, TileSize = {TileSize}",
|
||||
method, clipLimit, tileSize);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Image<Gray, byte> ApplyCLAHE(Image<Gray, byte> inputImage, double clipLimit, int tileSize)
|
||||
{
|
||||
int width = inputImage.Width;
|
||||
int height = inputImage.Height;
|
||||
|
||||
int tilesX = (width + tileSize - 1) / tileSize;
|
||||
int tilesY = (height + tileSize - 1) / tileSize;
|
||||
|
||||
var result = new Image<Gray, byte>(width, height);
|
||||
|
||||
// 对�个tile进行直方图�衡化
|
||||
for (int ty = 0; ty < tilesY; ty++)
|
||||
{
|
||||
for (int tx = 0; tx < tilesX; tx++)
|
||||
{
|
||||
int x = tx * tileSize;
|
||||
int y = ty * tileSize;
|
||||
int w = Math.Min(tileSize, width - x);
|
||||
int h = Math.Min(tileSize, height - y);
|
||||
|
||||
var roi = new System.Drawing.Rectangle(x, y, w, h);
|
||||
inputImage.ROI = roi;
|
||||
var tile = inputImage.Copy();
|
||||
inputImage.ROI = System.Drawing.Rectangle.Empty;
|
||||
|
||||
// 应用直方图�衡化
|
||||
var equalizedTile = new Image<Gray, byte>(tile.Size);
|
||||
CvInvoke.EqualizeHist(tile, equalizedTile);
|
||||
|
||||
// 应用�制(简化版本)
|
||||
var floatTile = tile.Convert<Gray, float>();
|
||||
var floatEqualized = equalizedTile.Convert<Gray, float>();
|
||||
var diff = floatEqualized - floatTile;
|
||||
var limited = floatTile + diff * Math.Min(clipLimit / 10.0, 1.0);
|
||||
var limitedByte = limited.Convert<Gray, byte>();
|
||||
|
||||
// �制到结果图�
|
||||
result.ROI = roi;
|
||||
limitedByte.CopyTo(result);
|
||||
result.ROI = System.Drawing.Rectangle.Empty;
|
||||
|
||||
tile.Dispose();
|
||||
equalizedTile.Dispose();
|
||||
floatTile.Dispose();
|
||||
floatEqualized.Dispose();
|
||||
diff.Dispose();
|
||||
limited.Dispose();
|
||||
limitedByte.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user