南宁大型网站推广公司,wordpress mip提交,清廉桂林网站,可信网站认证必须做吗版权声明#xff1a;本文为博主原创文章#xff0c;转载请在显著位置标明本文出处以及作者网名#xff0c;未经作者允许不得用于商业目的。
17.3.4.1 矩阵基本概念
矩阵#xff08;Matrix#xff09;是一个按照长方阵列排列的复数或实数集合#xff0c;类似于数组。
由…版权声明本文为博主原创文章转载请在显著位置标明本文出处以及作者网名未经作者允许不得用于商业目的。
17.3.4.1 矩阵基本概念
矩阵Matrix是一个按照长方阵列排列的复数或实数集合类似于数组。
由于在图像处理时使用到矩阵的乘法这里只谈谈矩阵的乘法运算。
矩阵乘法运算公式 图17-56 矩阵乘法运算公式
在C#中矩阵使用了颜色的四个分量红色分量R、绿色分量G、蓝色分量B、透明度A。但光是依靠上述4个分量不足以完全实现矩阵变换所以再加上一个用来进行颜色增减的分量W而W始终等于255。
假设变换前的5个颜色分量为R、G、B、A、W
变换后的5个颜色分量为R’、G’、B’、A’、W’
乘以一个5×5的矩阵得到公式如下 图17-57 颜色矩阵乘法公式
R’、G’、B’、A’、W’对应的值分别为
R R*r1G*g1B*b1A*a1W*w1
G’ R*r2G*g2B*b2A*a2W*w2
B’ R*r3G*g3B*b3A*a3W*w3
A’ R*r4G*g4B*b4A*a4W*w4
W’ R*r5G*g5B*b5A*a5W*w5
在这个公式基础上先来看几组比较常见的变换
1、变换后颜色相同 图17-58 矩阵变换相同矩阵
具体计算过程
R R*1G*0B*0A*0W*0 R
G’ R*0G*1B*0A*0W*0 G
B’ R*0G*0B*1A*0W*0 B
A’ R*0G*0B*0A*1W*0 A
W’ R*0G*0B*0A*0W*1 W
2、仅保留红色分量 图17-59 矩阵变换保留红色分量
3、仅保留绿色分量 图17-60 矩阵变换保留绿色分量
4、仅保留蓝色分量 图17-61 矩阵变换保留蓝色分量
5、灰度变换平均值法参看第17.3.1.3节 图17-62 矩阵变换灰度平均值
R R*0.33G*0.33B*0.33A*0W*0
G’R*0.33G*0.33B*0.33A*0W*0
B’ R*0.33G*0.33B*0.33A*0W*0
A’ A
W’ 0
6、灰度变换指数加权法参看第17.3.1.3节 图17-63 矩阵变换灰度指数加权
R R*0.30G*0.59B*0.11
G’R*0.30G*0.59B*0.11
B’ R*0.30G*0.59B*0.11
A’ A
W’ 0
7、逆反参看第17.3.1.1节 图17-64 矩阵变换逆反
R R*-1G*0B*0A*0W*0 -R
G’R*0G*-1B*0A*0W*0-G
B’ R*0G*0B*-1A*0W*0 -B
A’ R*0G*0B*0A*1W*0 A
W’ R*0G*0B*0A*0W*0 0
在理想化的情况下以红色分量为例如果R10R逆反后为-R即-10。由于R是Byte范围是0-255因此R255-10245。但是实际情况下C#可以那样运算VB.Net不行-10由于小于0直接被转成了0同样其它两个分量G、B由于是负数都直接成了0。使用上面逆反矩阵的话得到的图像永远是一片白色的。
下面才是正确的逆反矩阵 图17-65 矩阵变换逆反修正
R R*-1G*0B*0A*0W*1 255-R
G’R*0G*-1B*0A*0W*1255-G
B’ R*0G*0B*-1A*0W*1 255-B
A’ R*0G*0B*0A*1W*0 A
W’ R*0G*0B*0A*0W*0 0 下一节我们将实战使用以上的矩阵公式。
17.3.4.2 ColorMatrix类
ColorMatrix颜色矩阵类是一个包含 RGBAW 空间坐标的 5 x 5 矩阵。ImageAttributes类的SetColorMatrix和SetColorMatrices方法通过使用ColorMatrix调整图像颜色。
ColorMatrix常用属性
ItemColorMatrix中位于指定的行和列的元素。
Matrix00Single单精度浮点数。 ColorMatrix 第 0行第 0 列的元素 注意同数组矩阵行列的起始从0开始。
Matrix01Single单精度浮点数。ColorMatrix 第 0行第 1 列的元素。
……
Matrix44Single单精度浮点数。ColorMatrix 第 4行第4 列的元素。
Matrix00-Matrix44的位置如下图 图17-66 ColorMatrix元素位置
ColorMatrix的构造函数包括两个版本的重载
1、public ColorMatrix()
2、public ColorMatrix( float[][] newColorMatrix )
第一种方法是声明一个ColorMatrix实例然后使对它的属性Matrix00-Matrix44赋值。
常用的是第二种定义并初始化一个二位数组然后用构造函数 ColorMatrix(Single()()) 直接初始化一个Matrix例如以下代码 float[][] imgMatrixElement { new float[] {1, 0, 0, 0, 0}, new float[] {0, 0, 0, 0, 0}, new float[] {0, 0, 0, 0, 0}, new float[] {0, 0, 0, 1, 0}, new float[] {0, 0, 0, 0, 0} } Dim imgMatrix As New ColorMatrix(imgMatrixElement)
当实例化一个ColorMatrix后并给它的各个元素赋值后就可以使用imageAttributes的SetColorMatrix方法为图像设置颜色矩阵例如
imageAttributes.SetColorMatrix(imgMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
上述代码使用的是SetColorMatrix方法的以下重载版本
public void SetColorMatrix( ColorMatrix newColorMatrix, ColorMatrixFlag mode, ColorAdjustType type )
参数说明
newColorMatrix要进行颜色调整的矩阵。grayMatrix这是一个ColorMatrixFlag 枚举包含以下成员
AltGrays仅调整灰色底纹。Default指定所有的颜色值包括灰色底纹都由同样的颜色调整矩阵来调整。SkipGrays指定调整所有颜色但不调整灰色底纹。 灰色底纹是指其红色、绿色和蓝色分量的值都相同的任何颜色。 通常情况下使用的是 ColorMatrixFlag.Default。
参数flags这是一个ColorAdjustType枚举包含以下成员
Any指定的类型的数目。BitmapBitmap 对象的颜色调整信息。BrushBrush 对象的颜色调整信息。Count指定的类型的数目。Default自身没有颜色调整信息的所有 GDI 对象所使用的颜色调整信息。PenPen 对象的颜色调整信息。Text文本的颜色调整信息。
通常情况对图像的颜色进行调整使用ColorAdjustType.Bitmap。
【例 17.57】【项目code17-035】使用矩阵灰度化图像。
本例中使用了第17.3.4.1节中灰度变换平均值法的矩阵。
窗体级变量、窗体载入、载入图片的代码请参看第17.3.1节【项目code17-031】。
主要代码如下 private void btnGray_Click(object sender, EventArgs e) { ImageAttributes imageAttributes new ImageAttributes(); DateTime timeStart, timeEnd; TimeSpan timeDiff; timeStart DateTime.Now; //灰度平均值法 float [][] imgMatrixElement { new float [] { 0.33f, 0.33f, 0.33f, 0, 0}, new float [] { 0.33f, 0.33f, 0.33f, 0, 0}, new float [] { 0.33f, 0.33f, 0.33f, 0, 0}, new float [] { 0, 0, 0, 1, 0}, new float [] { 0, 0, 0, 0, 0} }; ColorMatrix imgMatrix new ColorMatrix(imgMatrixElement); imageAttributes.SetColorMatrix(imgMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); Bitmap destImg new Bitmap(sourceImg.Width, sourceImg.Height); Graphics g Graphics.FromImage(destImg); g.DrawImage(sourceImg, new Rectangle(0, 0, sourceImg.Width, sourceImg.Height), 0, 0, sourceImg.Width, sourceImg.Height, GraphicsUnit.Pixel, imageAttributes); picDest.Image destImg; timeEnd DateTime.Now; timeDiff timeEnd - timeStart; lblByMatrix.Text timeDiff.TotalMilliseconds ms; }
运行结果如下图所示 图17-67 使用矩阵灰度化图像
从图17-57可以看到使用矩阵处理图像所耗费的时间约为340.12ms处理速度间于像素处理与内存处理使用矩阵的代码比使用内存的代码更简洁但是像素处理和内存处理更为灵活应该根据实际需要选择图像处理方式。
【例 17.58】【项目code17-036】矩阵综合运用。
窗体上放置25个TextBox名称从“txt00”到“txt44”分别对应矩阵属性Matrix00至Matrix44。放置1个ComboBox用于设置常见的矩阵值。
主要代码如下 Bitmap sourceImg; private void Form1_Load(object sender, EventArgs e) { picSource.SizeMode PictureBoxSizeMode.StretchImage; picDest.SizeMode PictureBoxSizeMode.StretchImage; cbMatrixType.DropDownStyle ComboBoxStyle.DropDownList; cbMatrixType.Items.Add(全部重置); cbMatrixType.Items.Add(保留红色分量); cbMatrixType.Items.Add(保留绿色分量); cbMatrixType.Items.Add(保留蓝色分量); cbMatrixType.Items.Add(灰度平均值); cbMatrixType.Items.Add(灰度指数加权); cbMatrixType.Items.Add(逆反); cbMatrixType.Text cbMatrixType.Items[0].ToString(); } private void btnLoad_Click(object sender, EventArgs e) { OpenFileDialog ofd new OpenFileDialog(); ofd.Filter 图片文件|*.jpg;*.png; if (ofd.ShowDialog() ! DialogResult.OK) return; sourceImg (Bitmap)Image.FromFile(ofd.FileName); picSource.Image sourceImg; } private void btnDraw_Click(object sender, EventArgs e) { ImageAttributes imageAttributes new ImageAttributes(); ColorMatrix imgMatrix new ColorMatrix(); TextBox txtControl; for (int i 0; i 5; i) { for (int j 0; j 5; j) { txtControl (TextBox)(this.Controls[txt i j]); //矩阵相当于是二维数组 imgMatrix[i, j] Single.Parse(txtControl.Text); } } imageAttributes.SetColorMatrix(imgMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); Bitmap destImg new Bitmap(sourceImg.Width, sourceImg.Height); Graphics g Graphics.FromImage(destImg); g.DrawImage(sourceImg, new Rectangle(0, 0, sourceImg.Width, sourceImg.Height), 0, 0, sourceImg.Width, sourceImg.Height, GraphicsUnit.Pixel, imageAttributes); picDest.Image destImg; } private void cbMatrixType_SelectedIndexChanged(object sender, EventArgs e) { setMatrixType(); } private void setMatrixType() { //重置矩阵的值 resetText(); switch(cbMatrixType.Text) { case 全部重置: //不处理 break; case 保留红色分量: txt00.Text 1; txt33.Text 1; break; case 保留绿色分量: txt11.Text 1; txt33.Text 1; break; case 保留蓝色分量: txt22.Text 1; txt33.Text 1; break; case 灰度平均值: txt00.Text 0.33; txt01.Text 0.33; txt02.Text 0.33; txt10.Text 0.33; txt11.Text 0.33; txt12.Text 0.33; txt20.Text 0.33; txt21.Text 0.33; txt22.Text 0.33; txt33.Text 1; break; case 灰度指数加权: txt00.Text 0.30; txt01.Text 0.30; txt02.Text 0.30; txt10.Text 0.59; txt11.Text 0.59; txt12.Text 0.59; txt20.Text 0.11; txt21.Text 0.11; txt22.Text 0.11; txt33.Text 1; break; case 逆反: txt00.Text -1; txt11.Text -1; txt22.Text -1; txt40.Text 1; txt41.Text 1; txt42.Text 1; txt33.Text 1; break; default: break; } } //将矩阵关联的文本框全部重置为0 private void resetText() { TextBox txtControl; for( int i 0;i5;i) { for(int j 0;j 5;j) { //强制类型转换为相应名称的控件 txtControl (TextBox)(this.Controls[txt i j]); txtControl.Text 0; } } }
运行结果如下图所示 图17-68 使用矩阵处理图像 学习更多vb.net知识请参看vb.net 教程 目录
学习更多C#知识请参看C#教程 目录