图像处理:亮度与对比度的调整

图像处理领域,调整图像的亮度和对比度是常见的需求之一。本文将探讨几种在C#中实现这一功能的方法,并对比它们的性能。

在开始图像处理之前,从未考虑过使用图像滤镜。然而,随着项目需求的增加,意识到这是一个必须掌握的技能。决定从调整亮度和对比度开始,这是一个相对基础但非常重要的图像处理步骤。

目标

目标是保持开放的心态和坚持不懈的态度。即使有像AForge这样强大的工具,往往可以通过少量的努力,编写出更好、更简单、更快的解决方案。

对于更高级的成员来说,注意到“不安全模式”非常受欢迎,但很多时候其实没有必要使用它——可以通过简单的封送处理或其他方式来实现相同的效果。

最重要的目标是将C++中的QColorMatrix翻译成C#。在进行这项研究时,没有发现比使用QColorMatrix更好的图像过滤方法。这个主题非常高级;虽然代码本身非常简单且易于阅读,但数学部分相对复杂。除非解释ColorMatrix的工作原理,否则无法解释代码。但这并非本文的目标。如果数学水平足够高,并且理解矩阵乘法和旋转,可以很容易地理解并跟随代码。如果数学水平不够,可以直接按照下面的例子使用它——它是有效的。

方法1

初步搜索带找到了这篇文章:。它使用了AForge库。懒得去找源代码。使用Refractory获取控制亮度和对比度的对象要容易得多——这就是如何创建AForgeFilter对象的。

不喜欢AForge方法的三件事:

  • 不安全模式,可能有业务需求不使用不安全模式。
  • 在看来,有时可能想要同时应用亮度和对比度滤镜。使用AForge,无法做到这一点。
  • 根据后续研究,它太慢了。

很容易解决了第一个问题——只需使用封送处理代替不安全模式。附带的演示显示了处理图像需要多长时间。无法注意到封送处理比不安全模式慢,那么为什么要使用不安全模式呢?

方法2

不幸的是,没有保留发现第二种方法算法的链接。(OtherFilter对象)。它比AForge简单得多,而且速度更快。

方法3

并不完全满意。有一个ColorMatrix对象。必须有一种方法可以使用它进行图像过滤。接下来看到的这篇文章是:。幸运的是,同样精通C++和C#

QColorMatrix几乎是原始C++ QColorMatrix的直接翻译。它有多快?应用四个滤镜和Gamma大约比第二种方法快2倍,比AForge快7倍……

方法4

如果有人还没有被说服不要使用GetPixel/SetColor方法(OtherFilterSlow对象)——看看它有多慢:大约慢10倍。还想使用它吗?

使用代码

请注意:如果要使用AForgeFilter对象,需要检查AForge社区。不知道他们的许可证是什么,代码只是从aforge.dll的反射。否则,代码的使用如下所述。

C# Bitmap pSource = global::WindowsFormsApplication14.Properties.Resources.untitled; AForgeFilter pFilterBrightness = new AForgeFilter(); pFilterBrightness.AdjustValue = (double)TrackBarBrightness1.Value / 1000; Bitmap pBitmapBrightness = pFilterBrightness.Apply(pSource); C# Bitmap pSource = global::WindowsFormsApplication14.Properties.Resources.untitled; AForgeFilter pFilterContrast = new AForgeFilter(); pFilterContrast.Factor = (double)TrackBarContrast1.Value / 1000; Bitmap pBitmapBrightness = pFilterContrast.Apply(pSource); C# Bitmap pSource = global::WindowsFormsApplication14.Properties.Resources.untitled; AForgeFilter pFilterBrightness = new AForgeFilter(); pFilterBrightness.AdjustValue = (double)TrackBarBrightness1.Value / 1000; Bitmap pBitmapBrightness = checkBoxSafe.Checked ? pFilterBrightness.ApplySafe(pSource) : pFilterBrightness.Apply(pSource); AForgeFilter pFilterContrast = new AForgeFilter(); pFilterContrast.Factor = (double)TrackBarContrast1.Value / 1000; Bitmap pBitmapContrast = checkBoxSafe.Checked ? pFilterContrast.ApplySafe(pBitmapBrightness) : pFilterContrast.Apply(pBitmapBrightness); C# Bitmap pSource = global::WindowsFormsApplication14.Properties.Resources.untitled; Bitmap pBitmap = pSource.Clone(new Rectangle(0, 0, pSource.Width, pSource.Height), pSource.PixelFormat); new Brightness().Adjust(pBitmap, TrackBarBrightness2.Value); C# Bitmap pSource = global::WindowsFormsApplication14.Properties.Resources.untitled; Bitmap pBitmap = pSource.Clone(new Rectangle(0, 0, pSource.Width, pSource.Height), pSource.PixelFormat); Contrast().Adjust(pBitmap, TrackBarContrast2.Value); C# Bitmap pSource = global::WindowsFormsApplication14.Properties.Resources.untitled; Bitmap pBitmap = pSource.Clone(new Rectangle(0, 0, pSource.Width, pSource.Height), pSource.PixelFormat); new BrightnessContrast().Adjust(pBitmap, TrackBarBrightness2.Value, TrackBarContrast2.Value); C# QColorMatrix pQColorMatrix = new QColorMatrix(); pQColorMatrix.ScaleColors(TrackBarContrast3.Value * 0.05f, QColorMatrix.MatrixOrder.MatrixOrderPrepend); pQColorMatrix.TranslateColors(TrackBarBrightness3.Value * 0.05f, QColorMatrix.MatrixOrder.MatrixOrderAppend); pQColorMatrix.SetSaturation(TrackBarSaturation3.Value * 0.05f, QColorMatrix.MatrixOrder.MatrixOrderAppend); pQColorMatrix.RotateHue(TrackBarHue3.Value * 4.0f); Bitmap pSource = global::WindowsFormsApplication14.Properties.Resources.untitled; Bitmap pResult = pQColorMatrix.Adjust(pSource, TrackBarGamma3.Value * 0.05f);
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485