65.9K
CodeProject 正在变化。 阅读更多。
Home

图像滤镜

starIconstarIconstarIconstarIconstarIcon

5.00/5 (16投票s)

2009年9月30日

CPOL

3分钟阅读

viewsIcon

70104

downloadIcon

6377

应用图像滤镜的不同方法。

Demo

背景

在使用 GDI 的大约 20 年里,我从来不需要做图像滤镜。"如果不是现在,那又是什么时候?"我决定从亮度和对比度开始。经过相对广泛的研究,我想出了三种合理的方法,并且既然我已经做了,我决定检查 GetPixel / SetPixel 的速度——它真的像大家说的那么慢吗?

目标

  1. 为了保持开放的心态和坚持 - 即使使用像 AForge 这样强大的工具,你通常也可以自己编写更好、更简单、更快的解决方案,而且只需相对较少的努力。
  2. 对于更高级的成员:在我看来 - 由于一些奇怪的原因,不安全模式非常流行。通常情况下,没有必要使用它 - 你可以通过简单的封送处理或其他方法来实现相同的目的。
  3. 最重要的是 – 将 QColorMatrix 从 C++ 翻译为 C#。在进行这项研究时 – 与使用 QColorMatrix 方法相比,我没有看到更好的图像过滤方法。这个主题非常高级;虽然代码本身非常简单且可读性很强,但数学相对复杂。除非我解释 ColorMatrix 的工作原理,否则我无法解释代码。但这**不是**本文的目标。如果您的数学水平足够高,并且您了解矩阵乘法和旋转,您可以很容易地理解和遵循代码。如果你的数学水平不够高,你可以像下面这样使用它 - 它有效 :)。

方法 1

首先,我的搜索把我带到了这篇文章:C# 中的图像处理实验室。它使用 AForge 库。我懒得寻找源代码。对我来说,使用 Refractory 并获取控制亮度和合同的对象要容易得多——这就是创建 AForgeFilter 对象的方式。关于 AForge 的方式,我有三点不喜欢的地方

  1. 不安全模式,您可能有业务需求不允许使用不安全模式。
  2. 在我看来:有时你可能想要同时应用亮度和对比度滤镜。使用 AForge,你不能这样做。
  3. 正如我的后续研究表明,它太慢了。

我非常容易地解决了第一个问题——只需使用封送处理而不是不安全模式。附件中的演示展示了处理图像需要多长时间。我无法注意到封送处理比不安全模式慢,那么为什么要使用不安全模式呢?

方法 2

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

方法 3

我并不完全满意。有一个 ColorMatrix 对象。一定有一种方法可以使用它进行图像过滤。我看到的下一篇文章是:玩转 ColorMatrix 作者:Sjaak Priester。幸运的是,我同样精通 C++ 和 C#。QColorMatrix 或多或少是原始 C++ QColorMatrix 的直接翻译。它有多快?应用四个滤镜和 Gamma 比第二种方法快 ~2 倍,比 AForge 快 ~7 倍……

方法 4

如果还有人没有被说服不要使用 GetPixel / SetPixel 方法 (OtherFilterSlow 对象) – 请看看它有多慢:~慢 10 倍。仍然想使用它吗?

使用代码

请注意:如果您要使用 AForgeFilter 对象,您需要与 AForge 社区核实。我不知道他们的许可证是什么,我的代码只是从 aforge.dll 重新构造的。否则,代码的使用方式如下所述。要调整亮度

Bitmap pSource = global::WindowsFormsApplication14.Properties.Resources.untitled; 
AForgeFilter pFilterBrightness = new AForgeFilter();
pFilterBrightness.AdjustValue = (double)TrackBarBrightness1.Value / 1000;
Bitmap pBitmapBrightness = pFilterBrightness.Apply(pSource);

要调整对比度

Bitmap pSource = global::WindowsFormsApplication14.Properties.Resources.untitled; 
AForgeFilter pFilterContrast= new AForgeFilter();
pFilterContrast.Factor = (double)TrackBarContrast1.Value / 1000;
Bitmap pBitmapBrightness = pFilterContrast.Apply(pSource);

在该示例中,我想比较安全模式和不安全模式,并同时更改亮度和对比度。这是代码

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);

对于第二种方法

亮度

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);

对比度

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);

亮度和对比度

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);

第三种方法允许您更改四个滤镜和伽马

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);
© . All rights reserved.