C#图形处理系列(一)——最简单第一步:逆反处理、二值处理
在本系列博文中,將介紹幾種常見(jiàn)的圖形處理算法。上文C#圖片處理常見(jiàn)方法性能比較 中以彩色轉(zhuǎn)灰色處理為例探討了3中方法的性能,因此彩色轉(zhuǎn)灰度處理就不再另做介紹。
public enum DealType{
黑白處理,
逆反處理,
平滑處理,
霓虹處理,
浮雕處理,
霧化處理,
銳化處理,
二值處理,
馬賽克處理,
油畫(huà)處理
}
DealType枚舉定義了常見(jiàn)的圖形處理方法。
/// <summary>/// 具有圖片處理功能的接口
/// </summary>
public interface IImageProcessable
{
void ProcessBitmap(Bitmap bmp);
unsafe void UnsafeProcessBitmap(Bitmap bmp);
}
IImageProcessable接口提供圖形處理接口,所有圖形處理類都實(shí)現(xiàn)了該接口。
ProcessBitmap(Bitmap bmp) 直接提取像素法處理圖形,處理效率較低,適合處 理小圖片。
UnsafeProcessBitmap(Bitmap bmp)? 提供高效率的圖形處理方法,以指針或內(nèi)存拷貝法處理圖形,不安全代碼。
?
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.油畫(huà)處理:
dealImage = new OilImage();
break;
}
return dealImage;
}
}
ImageDealFactory 圖形處理工廠。
先從最簡(jiǎn)單的圖形處理介紹起,最簡(jiǎn)單的要算逆反處理、灰度處理
、積木二值處理了。
?
逆反處理
逆反處理的原理很簡(jiǎn)單,用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
}
?
?
逆反處理對(duì)黑白分量比較多的圖片較明顯,故截文字圖。
?
二值處理
二值處理,顧名思義,將圖片處理后就剩下二值了,0、255就是RGB取值的極限值,圖片只剩下黑白二色,從上一篇C#圖片處理常見(jiàn)方法性能比較 可知,二值處理為圖像灰度彩色變黑白灰度處理的一個(gè)子集,只不過(guò)值就剩下0和255了,因此處理方法有些類似。進(jìn)行加權(quán)或取平均值后進(jìn)行極端化,若平均值大于等于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
}
?
處理效果如上圖,有點(diǎn)像毛筆手繪的,如果沒(méi)有很好的畫(huà)家,還真說(shuō)不定一些古裝電視劇中的人物畫(huà)像有可能是用二值法處理的哦。
二值處理法在驗(yàn)證碼識(shí)別中也經(jīng)常用到,往往先將驗(yàn)證碼進(jìn)行二值處理,這樣驗(yàn)證碼的顏色比較單一,處理起來(lái)容易些。
轉(zhuǎn)載于:https://www.cnblogs.com/sndnnlfhvk/archive/2012/03/04/2379344.html
總結(jié)
以上是生活随笔為你收集整理的C#图形处理系列(一)——最简单第一步:逆反处理、二值处理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【转】Eclipse Code Reco
- 下一篇: XAF Study Recources