今天来讲讲上个星期遗留下来的东西:ColorMatrix。
9. Color Matrix
图像的本质是什么?对不同的人来说这是不同的东西。在计算机的世界中,啥东西都是数 据,图像也是一种数据。从自然界的光变成计算机的数据,需要通过采样和量化的处理。图 像在计算机中,其实是一个二维数组,从数学上来说,这其实是一个矩阵。图像中的每一个 点都是个四维向量,也就是(R,G,B,A), 在RGBA色彩空间中,我们可以使用一个矩阵对每一 个点(R,G,B,A)作矩阵乘法运算,这样就可以对图像色彩进行变换。这种做法其实是从三维空 间坐标系中的仿射变换类推过来的。具体关于仿射变换,可以参考 http://en.wikipedia.org/wiki/Affine_transformation对于仿射变换的介绍。
色彩矩阵就是这个用来对色彩作仿射变换的矩阵。这是一个5*5的矩阵,如图
其实和在空间中的仿射变换完全一样,可以实现缩放,旋转,平移等功能。我看到网上有 个人写了一篇深入浅出的文章"GDI+ ColorMatrix的完全揭秘与代码实现" http://blog.csdn.net/maozefa/archive/2008/09/08/2896752.aspx 写得不错,只是没有 理解到ColorMatrix应用的精髓。简单套用了一些什么颜色剪切,颜色旋转,颜色平移的概念 ,这些东西其实在三维空间中很好理解,但是在色彩空间中,就完全不是那么回事情了,什 么叫做颜色旋转60度呢? 这东西忽悠人很有用,只是看完了还是不知道怎么用,有兴趣的同 学可以去看看。我下面举几个例子,说明ColorMatrix的具体应用。
a.灰度化
灰度化是指去除图像的彩色信息,讲所有的色调归为0,所有的饱和度也归为零。这个世 界上有很多种不同的灰度化的算法,随便写个算法,弄篇paper搞个硕士毕业应该不成问题, 比如说所有的颜色替换成R' = G' = B' = (R+B+G)/3。有一种很通用的灰度化算法如下,这 其实是NTSC的色彩权重。
R'=B'=G' = 0.299*R + 0.587*G + 0.114*B
那如果我们要使用ColorMatrix, 可以用以下的矩阵:
// ColorMatrix elements
float[][] ptsArray =
{
new float[] {0.299f, 0.299f, 0.299f, 0, 0},
new float[] {0.518f, 0.518f, 0.518f, 0, 0},
new float[] {0.114f, 0.114f, 0.114f, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
};
再引用一下博客园里的这篇文章 http://www.cnblogs.com/sunbingzibo/archive/2008/09/11/1289260.html,如果用他的算 法,那么矩阵如下
// ColorMatrix elements
float[][] ptsArray =
{
new float[] {cr, cr, cr, 0, 0},
new float[] {cg, cg, cg, 0, 0},
new float[] {cb, cb, cb, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
};