1. 程式人生 > >[c#]圖片二值化初探

[c#]圖片二值化初探

0.序言

研究文字識別遇到二值化問題,看了看原理,覺得好玩,就試了試,沒有參考成熟的方法,完全是自學研究,由於用到了灰度閾值矩陣,就暫時叫做矩陣法二值化。基本步驟:讀取源圖片->生成灰度圖->計算灰度圖灰度閾值矩陣->利用灰度閾值矩陣生成二值化圖。

生成灰度圖: 生成灰度圖 圖片二值化: 二值化圖片

1.程式基本程式碼

1.1.圖片灰度化

public static unsafe Bitmap Img2Gray(Bitmap curBitmap)
{
    int width = curBitmap.Width;
    int height = curBitmap.Height;
    Bitmap back = new Bitmap(width, height);
    byte temp;
    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
    //這種速度最快
    BitmapData bmpData = curBitmap.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);//24位rgb顯示一個畫素,即一個畫素點3個位元組,每個位元組是BGR分量。Format32bppRgb是用4個位元組表示一個畫素
    byte* ptr = (byte*)(bmpData.Scan0);
    for (int j = 0; j < height; j++)
    {
		for (int i = 0; i < width; i++)
		{
			//ptr[2]為r值,ptr[1]為g值,ptr[0]為b值
			temp = (byte)(0.299 * ptr[2] + 0.587 * ptr[1] + 0.114 * ptr[0]);
			back.SetPixel(i, j, Color.FromArgb(temp, temp, temp));
			ptr += 3; //Format24bppRgb格式每個畫素佔3位元組
		}
		ptr += bmpData.Stride - bmpData.Width * 3;//每行讀取到最後“有用”資料時,跳過未使用空間XX
    }
    curBitmap.UnlockBits(bmpData);
    return back;
}

1.2.灰度閾值矩陣位置索引計算(Sensibility為全域性變數,為灰度閾值矩陣大小,值越大,閾值矩陣越大,圖片分割槽越多,但是速度越慢)

public int GetIndex(int location, int length)
{
    return location * Sensibility / length;
}

1.3.灰度圖二值化處理

public Bitmap Gray2Binaryzation(Bitmap GrayImg)
{
    int width = GrayImg.Width;
    int height = GrayImg.Height;
    Bitmap back = new Bitmap(width, height);
    
    //灰度矩陣初始化
    Int64[,] GrayScale = new Int64[Sensibility, Sensibility];
    for (int i = 0; i < Sensibility; i++)
    {
		for (int j = 0; j < Sensibility; j++)
		{
			GrayScale[i,j] = 0;
		}
    }

    //計算灰度矩陣閾值,17/20為閾值調整,取0.85時效果最好;
    for (int i = 0; i < width; i++)
    {
		for (int j = 0; j < height; j++)
		{
			GrayScale[GetIndex(i, width), GetIndex(j, height)] += GrayImg.GetPixel(i, j).R;
		}
    }
    for (int i = 0; i < Sensibility; i++)
    {
		for (int j = 0; j < Sensibility; j++)
		{
			GrayScale[i, j] = GrayScale[i, j] / width * Sensibility / height * Sensibility * 17 / 20;
		}
    }

    //二值化賦值,大於灰度矩陣閾值的描黑,否則描白。
    for (int i = 0; i < width; i++)
    {
		for (int j = 0; j < height; j++)
		{
			if (GrayImg.GetPixel(i, j).R >= GrayScale[GetIndex(i, width), GetIndex(j, height)])
				back.SetPixel(i, j, Color.FromArgb(255, 255, 255));
			else
				back.SetPixel(i, j, Color.FromArgb(0, 0, 0));
		}
    }
    return back;
}

2.下載地址