GDI+ 在Delphi程序的应用 -- ColorMatrix与图像灰度化

图像由彩色转化为灰度的过程叫灰度化,也叫去色。
彩色图像灰度化的原理很简单,就是按某种计算方法将图像各像素的R、G、B分量取成同样的值即可。计算方法有几种:
1、每个像素R、G、B各分量的值为该象素R、G、B的平均值;
2、每个像素R、G、B各分量的值为该象素R、G、B中最大值;
3、按YUV颜色空间原理,每个像素R、G、B各分量的值为:Y = 0.3R + 0.59G + 0.11B。
在Delphi程序的具体应用中,一般是对图像各像素点逐点取值、计算和修改等过程实现的,很繁琐,而且效率不高。
使用GDI+,通过对ColorMatrix矩阵数组进行适当设置,可以很很轻松的搞定。下面是个按YUV颜色空间原理对彩色图像灰度化的Delphi过程:

implementation

usesGdiplus,GdipTypes;

// 彩色图像灰度化
procedureGrayImage(Image:TGpImage);
const
ColorMatrix:TColorMatrix
=
((
0.3 , 0.3 , 0.3 , 0.0 , 0.0 ), // Red
( 0.59 , 0.59 , 0.59 , 0.0 , 0.0 ), // Green
( 0.11 , 0.11 , 0.11 , 0.0 , 0.0 ), // Blue
( 0.0 , 0.0 , 0.0 , 1.0 , 0.0 ), // Alpha
( 0.0 , 0.0 , 0.0 , 0.0 , 1.0 ));
var
Tmp:TGpImage;
attr:TGpImageAttributes;
g:TGpGraphics;
begin
Tmp:
= Image.Clone;
g:
= TGpGraphics.Create(Image);
attr:
= TGpImageAttributes.Create;
try
attr.SetColorMatrix(ColorMatrix);
g.DrawImage(Tmp,GpRect(
0 , 0 ,Image.Width,Image.Height),
0 , 0 ,Tmp.Width,Tmp.Height,utPixel,attr);
finally
g.Free;
attr.Free;
Tmp.Free;
end;
end;
// 测试
procedureTForm1.Button1Click(Sender:TObject);
var
Image:TGpImage;
g:TGpGraphics;
begin
Image:
= TGpImage.Create( ' ..media41001.jpg ' );
GrayImage(Image);
g:
= TGpGraphics.Create(Handle,False);
g.DrawImage(Image,
10 , 10 );
g.Free;
image.Free;
end;

可以看出,过程中的实现代码相当简单,主要是try ... finally之间2句的代码,而起关键作用的就是这个ColorMatrix。

对于ColorMatrix,有关资料是这样的介绍的:

GDI+ 提供用于存储和操作图像的 ImageBitmap 类。ImageBitmap 对象将每个像素的颜色都存储为 32 位的数:红色、绿色、蓝色和 alpha 各占 8 位。这四个分量的值都是 0 到 255,其中 0 表示没有亮度,255 表示最大亮度。alpha 分量指定颜色的透明度:0 表示完全透明,255 表示完全不透明。

颜色矢量采用 4 元组形式(红色、绿色、蓝色、alpha)。例如,颜色矢量 (0, 255, 0, 255) 表示一种没有红色和蓝色但绿色达到最大亮度的不透明颜色。
表示颜色的另一种惯例是用数字 1 表示亮度达到最大。使用这种惯例,上一段中描述的颜色将用 (0, 1, 0, 1) 表示。GDI+ 在进行颜色变换时使用以 1 表示最大亮度的惯例。
可通过用 4×4 矩阵乘以这些颜色矢量将线性变换(旋转和缩放等)应用到颜色矢量中。但是,您不能使用 4×4 矩阵进行平移(非线性)。如果在每个颜色矢量中再添加一个虚拟的第 5 坐标(例如,数字 1),则可使用 5×5 矩阵应用任何组合形式的线性变换和平移。由线性变换组成的后跟平移的变换称为仿射变换。
从原理上说,ColorMatrix并不难理解,主要通过矩阵运算对颜色矢量进行线性或非线性的转换,以达到对图像的各种数字处理的目的。我在网上看到有很多人对于矩阵中的虚拟位不理解,而解答的的人可能心里明白,却也总是说的不彻不透,有时还把人越说越糊涂,似乎这个概念只可意会,不可言传。其实上面的解答已经很明确的,4*4矩阵只能进行颜色的线性变换,而不能进行非线性变换和平移,这就相当4把椅子坐了4个人,无法相互移位,如果加一把空椅,就可方便的实现移位了,这把空椅就是虚拟位!如果还不明白,可以看一下《大唐双龙传》,估计很多人都看过,这个虚拟位就是小说中所谓的“遁去的一”!^_^
从实际应用看,要真正熟练运用ColorMatrix却也并非那么简单,必须同时具备较好的数学和计算机图形学知识以及较高水平的编程能力,才能做到随心所欲的运用。本人由于各方面都很差,所以至今也没有完全搞明白它的一些具体运用(比如昨天发的文章《GDI+ 在Delphi程序的应用 -- 调整图像亮度》,对于图像亮度调整,我知道可以用ColorMatrix来实现,而不必逐点计算,但试验了几次,确实能够调整,但总是不很理想)。
后记:使用ColorMatrix确实能够调整图象亮度,见《 GDI+ 在Delphi程序的应用 -- ColorMatrix与图像亮度 》,(2007.11.17)

你可能感兴趣的:(GDI+ 在Delphi程序的应用 -- ColorMatrix与图像灰度化)