【发布时间】:2025-12-05 03:35:01
【问题描述】:
我正在开发一个用于自动增强扫描的 35 毫米幻灯片的例程。我正在寻找一种很好的算法来增加对比度和消除偏色。该算法必须是完全自动化的,因为需要处理数千张图像。这些是直接来自扫描仪的几个示例图像,仅针对网络进行了裁剪和缩小:
我正在使用 AForge.NET 库并尝试了 HistogramEqualization 和 ContrastStretch 过滤器。 HistogramEqualization 有利于最大化局部对比度,但总体上不会产生令人满意的结果。 ContrastStretch 更好,但由于它单独拉伸每个色带的直方图,因此有时会产生强烈的色偏:
为了减少颜色偏移,我使用ImageStatistics 和LevelsLinear 类自己创建了一个UniformContrastStretch 过滤器。这对所有色带使用相同的范围,以降低对比度为代价保留颜色。
ImageStatistics stats = new ImageStatistics(image);
int min = Math.Min(Math.Min(stats.Red.Min, stats.Green.Min), stats.Blue.Min);
int max = Math.Max(Math.Max(stats.Red.Max, stats.Green.Max), stats.Blue.Max);
LevelsLinear levelsLinear = new LevelsLinear();
levelsLinear.Input = new IntRange(min, max);
Bitmap stretched = levelsLinear.Apply(image);
虽然图像仍然很蓝,所以我创建了一个ColorCorrection 过滤器,它首先计算图像的平均亮度。然后为每个颜色通道计算伽马校正值,以便每个颜色通道的平均值等于平均亮度。均匀对比度拉伸图像的平均值为R=70 G=64 B=93,平均亮度为(70 + 64 + 93) / 3 = 76。伽马值计算为R=1.09 G=1.18 B=0.80,结果非常中性,图像的平均值为R=76 G=76 B=76,正如预期的那样:
现在,解决真正的问题...我想将图像的平均颜色校正为灰色有点过于激烈,并且会使某些图像看起来很暗淡,例如第二个示例(第一张图片是均匀拉伸的,下一张是相同的图片颜色校正):
在照片编辑程序中手动执行颜色校正的一种方法是对已知中性色(白色/灰色/黑色)的颜色进行采样,然后将图像的其余部分调整为该颜色。但由于这个程序必须是完全自动的,所以这不是一种选择。
我想我可以为我的ColorCorrection 滤镜添加一个强度设置,这样强度为 0.5 会将平均值移动到平均亮度的一半距离。但另一方面,有些图像可能在没有任何颜色校正的情况下表现最佳。
对于更好的算法有什么想法吗?或者一些方法来检测图像是否有偏色或只是有很多颜色,比如第二个样本?
【问题讨论】:
-
如果图像最亮的部分(没有剪裁)是中性色,您可能不需要应用颜色校正。这会捕捉到你的船形象。
-
@MarkRansom,这是个好主意。我肯定会排除在所有通道(255、255、255)中被剪裁的颜色,但您认为排除仅在一个通道中被剪裁的颜色(如(244、249、255)是个好主意吗?
-
如果其他通道在适当的范围内,则仅在一个通道中被裁剪的颜色将是色偏的良好证据。想象一张玫瑰的照片,它可以很容易地夹在红色通道上,但相比之下其他通道仍然会很暗。其他通道需要足够高才能被视为接近白色,但要足够低以表明有色偏。
-
是的,当然,这是有道理的。也使编码更容易。 :-)
-
我将从 Gasparini 和 Schettini 的“使用简单图像统计的数码照片色彩平衡”开始(如果您有访问权限,请访问 sciencedirect.com/science/article/pii/S0031320304000068,否则可以找到质量较低的版本使用搜索引擎),不一定是新的,但更强大。与任何论文一样,它还快速描述了相关研究和与该问题相关的问题。
标签: c# image algorithm image-processing aforge