C#图形处理系列(一)——最简单第一步:逆反处理、二值处理
2012-03-04 16:31
183 查看
在本系列博文中,将介绍几种常见的图形处理算法。上文C#图片处理常见方法性能比较 中以彩色转灰色处理为例探讨了3中方法的性能,因此彩色转灰度处理就不再另做介绍。
DealType枚举定义了常见的图形处理方法。
IImageProcessable接口提供图形处理接口,所有图形处理类都实现了该接口。
ProcessBitmap(Bitmap bmp) 直接提取像素法处理图形,处理效率较低,适合处 理小图片。
UnsafeProcessBitmap(Bitmap bmp) 提供高效率的图形处理方法,以指针或内存拷贝法处理图形,不安全代码。
ImageDealFactory 图形处理工厂。
先从最简单的图形处理介绍起,最简单的要算逆反处理、灰度处理
、积木二值处理了。
g(i,j)=255-f(i,j)
逆反处理对黑白分量比较多的图片较明显,故截文字图。
处理效果如上图,有点像毛笔手绘的,如果没有很好的画家,还真说不定一些古装电视剧中的人物画像有可能是用二值法处理的哦。
二值处理法在验证码识别中也经常用到,往往先将验证码进行二值处理,这样验证码的颜色比较单一,处理起来容易些。
public enum DealType { 黑白处理, 逆反处理, 平滑处理, 霓虹处理, 浮雕处理, 雾化处理, 锐化处理, 二值处理, 马赛克处理, 油画处理 }
DealType枚举定义了常见的图形处理方法。
/// <summary> /// 具有图片处理功能的接口 /// </summary> public interface IImageProcessable { void ProcessBitmap(Bitmap bmp); unsafe void UnsafeProcessBitmap(Bitmap bmp); }
IImageProcessable接口提供图形处理接口,所有图形处理类都实现了该接口。
ProcessBitmap(Bitmap bmp) 直接提取像素法处理图形,处理效率较低,适合处 理小图片。
UnsafeProcessBitmap(Bitmap bmp) 提供高效率的图形处理方法,以指针或内存拷贝法处理图形,不安全代码。
public class ImageDealFactory { public static IImageProcessable CreateDealImage(DealType dealType) { IImageProcessable dealImage = null; switch (dealType) { case DealType.黑白处理: dealImage = new BlackWhiteImage(); break; case DealType.霓虹处理: dealImage = new NeonImage(); break; case DealType.逆反处理: dealImage = new RebelliousImage(); break; case DealType.平滑处理: dealImage = new SmoothImage(); break; case DealType.浮雕处理: dealImage = new ReliefImage(); break; case DealType.雾化处理: dealImage = new FogImage(); break; case DealType.锐化处理: dealImage = new SharpenImage(); break; case DealType.二值处理: dealImage = new TwoValueImage (); break; case DealType.马赛克处理: dealImage = new MosaicImage(); break; case DealType.油画处理: dealImage = new OilImage(); break; } return dealImage; } }
ImageDealFactory 图形处理工厂。
先从最简单的图形处理介绍起,最简单的要算逆反处理、灰度处理
、积木二值处理了。
逆反处理
逆反处理的原理很简单,用255减去该像素的RGB作为新的RGB值即可。g(i,j)=255-f(i,j)
/// <summary> /// 逆反处理 /// </summary> public class RebelliousImage : IImageProcessable { public void ProcessBitmap(System.Drawing.Bitmap bmp) { int width = bmp.Width; int height = bmp.Height; for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { Color c = bmp.GetPixel(i, j); int r = 255 - c.R; int g = 255 - c.G; int b = 255 - c.B; bmp.SetPixel(i, j, Color.FromArgb(r, g, b)); } } } #region IImageProcessable 成员 public unsafe void UnsafeProcessBitmap(Bitmap bmp) { int width = bmp.Width; int height = bmp.Height; Rectangle rect = new Rectangle(0, 0, width, height); BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); byte* ptr = (byte*)(bmpData.Scan0); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { ptr[0] = (byte)(255 - ptr[0]);//B ptr[1] = (byte)(255 - ptr[1]);//G ptr[2] = (byte)(255 - ptr[2]);//R ptr += 4; } ptr += bmpData.Stride - width * 4; } bmp.UnlockBits(bmpData); } #endregion }
逆反处理对黑白分量比较多的图片较明显,故截文字图。
二值处理
二值处理,顾名思义,将图片处理后就剩下二值了,0、255就是RGB取值的极限值,图片只剩下黑白二色,从上一篇C#图片处理常见方法性能比较 可知,二值处理为图像灰度彩色变黑白灰度处理的一个子集,只不过值就剩下0和255了,因此处理方法有些类似。进行加权或取平均值后进行极端化,若平均值大于等于128则255,否则0./// <summary> /// 二值处理 /// </summary> public class TwoValueImage:IImageProcessable { #region IImageProcessable 成员 public void ProcessBitmap(System.Drawing.Bitmap bmp) { int width = bmp.Width; int height = bmp.Height; for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { Color c = bmp.GetPixel(i, j); int iAvg = (c.R + c.G + c.B) / 3; int iPixel = 0; if (iAvg >= 128) { iPixel = 255; } else { iPixel = 0; } bmp.SetPixel(i, j, Color.FromArgb(iPixel, iPixel, iPixel)); } } } public unsafe void UnsafeProcessBitmap(System.Drawing.Bitmap bmp) { int width = bmp.Width; int height = bmp.Height; Rectangle rect=new Rectangle(0,0,width,height); BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); // byte* ptr =(byte*)bmpData.Scan0; //for (int i = 0; i < height; i++) //{ // for (int j = 0; j < width; j++) // { // int avg = (int)((ptr[0] + ptr[1] + ptr[2]) / 3); // if (avg >= 128) // { // avg = 255; // } // else // { // avg = 0; // } // ptr[0] = ptr[1] = ptr[2] = (byte)avg; // ptr += 4; // } // ptr += bmpData.Stride - bmpData.Width * 4; //} int byteCounts = bmpData.Stride * height; byte[] arr = new byte[byteCounts]; IntPtr p = bmpData.Scan0; Marshal.Copy(p, arr, 0, byteCounts); for (int i = 0; i < byteCounts; i += 4) { int avg = (int)((arr[i] + arr[i + 1] + arr[i + 2]) / 3); if (avg >= 128) { avg = 255; } else { avg = 0; } arr[i] = arr[i + 1] = arr[i + 2] = (byte)avg; } Marshal.Copy(arr, 0, p, byteCounts); bmp.UnlockBits(bmpData); } #endregion }
处理效果如上图,有点像毛笔手绘的,如果没有很好的画家,还真说不定一些古装电视剧中的人物画像有可能是用二值法处理的哦。
二值处理法在验证码识别中也经常用到,往往先将验证码进行二值处理,这样验证码的颜色比较单一,处理起来容易些。
相关文章推荐
- 图形图像处理之——实现图像子区域图像的简单提取
- 图形的简单处理代码(含注释)
- [Web Chart系列之一(续)]Web端图形绘制SVG,VML, HTML5 Canvas 简单实例
- 图形处理(三)简单拉普拉斯网格变形-Siggraph 2004
- 存储过程中的简单事务处理---SQLServer2005系列
- Android中简单的图形处理
- WP7开发系列——Windows Phone 7平台简单图像处理
- 图形处理(三)简单拉普拉斯网格变形-Siggraph 2004
- Android L(5.0)源码之图形与图像处理之简单图片——Bitmap
- 程序员吐血而死系列:VC+图形处理=聊斋志异?
- svg学习系列02-简单的svg图形和线条
- .NET基础示例系列之二十:对图片的几种简单处理
- 某图形处理软件简单分析
- 安卓第十五天笔记-图形图像一些简单处理
- Linux TCP server系列(1)-简单TCP服务器+多进程处理客户请求
- 【ACM-Steps1.2】简单字符串处理、简单数学题、进制转换系列8题(一)
- WorldWind学习系列三:简单功能分析——主窗体的键盘监听处理及拷贝和粘贴位置坐标功能
- WorldWind学习系列三:简单功能分析——主窗体的键盘监听处理及拷贝和粘贴位置坐标功能
- 安卓第十五天笔记-图形图像一些简单处理
- 缩放位图以及简单的图形处理