程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C# 驗證識別類

C# 驗證識別類

編輯:C#入門知識

[csharp] 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.Runtime.InteropServices; 
 
namespace 驗證碼處理 

    class VerifyCode 
    { 
        public Bitmap bmpobj; 
 
        public VerifyCode(Bitmap pic) 
        { 
            bmpobj = new Bitmap(pic);    //轉換為Format32bppRgb 
        } 
 
        /// <summary> 
        /// 根據RGB,計算灰度值 
        /// </summary> 
        /// <param name="posClr">Color值</param> 
        /// <returns>灰度值,整型</returns> 
        private int GetGrayNumColor(System.Drawing.Color posClr) 
        { 
            return (posClr.R * 19595 + posClr.G * 38469 + posClr.B * 7472) >> 16; 
        } 
 
        /// <summary> 
        /// 灰度轉換,逐點方式 
        /// </summary> 
        public void GrayByPixels() 
        { 
            for (int i = 0; i < bmpobj.Height; i++) 
            { 
                for (int j = 0; j < bmpobj.Width; j++) 
                { 
                    int tmpValue = GetGrayNumColor(bmpobj.GetPixel(j, i)); 
                    bmpobj.SetPixel(j, i, Color.FromArgb(tmpValue, tmpValue, tmpValue)); 
                } 
            } 
        } 
 
        /// <summary> 
        /// 去圖形邊框 
        /// </summary> 
        /// <param name="borderWidth"></param> 
        public void ClearPicBorder(int borderWidth) 
        { 
            for (int i = 0; i < bmpobj.Height; i++) 
            { 
                for (int j = 0; j < bmpobj.Width; j++) 
                { 
                    if (i < borderWidth || j < borderWidth || j > bmpobj.Width - 1 - borderWidth || i > bmpobj.Height - 1 - borderWidth) 
                        bmpobj.SetPixel(j, i, Color.FromArgb(255, 255, 255)); 
                } 
            } 
        } 
 
        /// <summary> 
        /// 灰度轉換,逐行方式 
        /// </summary> 
        public void GrayByLine() 
        { 
            Rectangle rec = new Rectangle(0, 0, bmpobj.Width, bmpobj.Height); 
            BitmapData bmpData = bmpobj.LockBits(rec, ImageLockMode.ReadWrite, bmpobj.PixelFormat);// PixelFormat.Format32bppPArgb); 
            //    bmpData.PixelFormat = PixelFormat.Format24bppRgb; 
            IntPtr scan0 = bmpData.Scan0; 
            int len = bmpobj.Width * bmpobj.Height; 
            int[] pixels = new int[len]; 
            Marshal.Copy(scan0, pixels, 0, len); 
 
            //對圖片進行處理 
            int GrayValue = 0; 
            for (int i = 0; i < len; i++) 
            { 
                GrayValue = GetGrayNumColor(Color.FromArgb(pixels[i])); 
                pixels[i] = (byte)(Color.FromArgb(GrayValue, GrayValue, GrayValue)).ToArgb();      //Color轉byte 
            } 
 
            bmpobj.UnlockBits(bmpData); 
 
            ////輸出 
            //GCHandle gch = GCHandle.Alloc(pixels, GCHandleType.Pinned); 
            //bmpOutput = new Bitmap(bmpobj.Width, bmpobj.Height, bmpData.Stride, bmpData.PixelFormat, gch.AddrOfPinnedObject()); 
            //gch.Free(); 
        } 
 
        /// <summary> 
        /// 得到有效圖形並調整為可平均分割的大小 
        /// </summary> 
        /// <param name="dgGrayValue">灰度背景分界值</param> 
        /// <param name="CharsCount">有效字符數</param> 
        /// <returns></returns> 
        public void GetPicValidByValue(int dgGrayValue, int CharsCount) 
        { 
            int posx1 = bmpobj.Width; int posy1 = bmpobj.Height; 
            int posx2 = 0; int posy2 = 0; 
            for (int i = 0; i < bmpobj.Height; i++)      //找有效區 
            { 
                for (int j = 0; j < bmpobj.Width; j++) 
                { 
                    int pixelValue = bmpobj.GetPixel(j, i).R; 
                    if (pixelValue < dgGrayValue)     //根據灰度值 
                    { 
                        if (posx1 > j) posx1 = j; 
                        if (posy1 > i) posy1 = i; 
 
                        if (posx2 < j) posx2 = j; 
                        if (posy2 < i) posy2 = i; 
                    }; 
                }; 
            }; 
            // 確保能整除 
            int Span = CharsCount - (posx2 - posx1 + 1) % CharsCount;   //可整除的差額數 
            if (Span < CharsCount) 
            { 
                int leftSpan = Span / 2;    //分配到左邊的空列 ,如span為單數,則右邊比左邊大1 
                if (posx1 > leftSpan) 
                    posx1 = posx1 - leftSpan; 
                if (posx2 + Span - leftSpan < bmpobj.Width) 
                    posx2 = posx2 + Span - leftSpan; 
            } 
            //復制新圖 
            Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1); 
            bmpobj = bmpobj.Clone(cloneRect, bmpobj.PixelFormat); 
        } 
         
        /// <summary> 
        /// 得到有效圖形,圖形為類變量 
        /// </summary> 
        /// <param name="dgGrayValue">灰度背景分界值</param> 
        /// <param name="CharsCount">有效字符數</param> 
        /// <returns></returns> 
        public void GetPicValidByValue(int dgGrayValue) 
        { 
            int posx1 = bmpobj.Width; int posy1 = bmpobj.Height; 
            int posx2 = 0; int posy2 = 0; 
            for (int i = 0; i < bmpobj.Height; i++)      //找有效區 
            { 
                for (int j = 0; j < bmpobj.Width; j++) 
                { 
                    int pixelValue = bmpobj.GetPixel(j, i).R; 
                    if (pixelValue < dgGrayValue)     //根據灰度值 
                    { 
                        if (posx1 > j) posx1 = j; 
                        if (posy1 > i) posy1 = i; 
 
                        if (posx2 < j) posx2 = j; 
                        if (posy2 < i) posy2 = i; 
                    }; 
                }; 
            }; 
            //復制新圖 
            Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1); 
            bmpobj = bmpobj.Clone(cloneRect, bmpobj.PixelFormat); 
        } 
 
        /// <summary> 
        /// 得到有效圖形,圖形由外面傳入 
        /// </summary> 
        /// <param name="dgGrayValue">灰度背景分界值</param> 
        /// <param name="CharsCount">有效字符數</param> 
        /// <returns></returns> 
        public Bitmap GetPicValidByValue(Bitmap singlepic, int dgGrayValue) 
        { 
            int posx1 = singlepic.Width; int posy1 = singlepic.Height; 
            int posx2 = 0; int posy2 = 0; 
            for (int i = 0; i < singlepic.Height; i++)      //找有效區 
            { 
                for (int j = 0; j < singlepic.Width; j++) 
                { 
                    int pixelValue = singlepic.GetPixel(j, i).R; 
                    if (pixelValue < dgGrayValue)     //根據灰度值 
                    { 
                        if (posx1 > j) posx1 = j; 
                        if (posy1 > i) posy1 = i; 
 
                        if (posx2 < j) posx2 = j; 
                        if (posy2 < i) posy2 = i; 
                    }; 
                }; 
            }; 
            //復制新圖 
            Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1); 
            return singlepic.Clone(cloneRect, singlepic.PixelFormat); 
        } 
         
        /// <summary> 
        /// 平均分割圖片 
        /// </summary> 
        /// <param name="RowNum">水平上分割數</param> 
        /// <param name="ColNum">垂直上分割數</param> 
        /// <returns>分割好的圖片數組</returns> 
        public Bitmap [] GetSplitPics(int RowNum,int ColNum) 
        { 
            if (RowNum == 0 || ColNum == 0) 
                return null; 
            int singW = bmpobj.Width / RowNum; 
            int singH = bmpobj.Height / ColNum; 
            Bitmap [] PicArray=new Bitmap[RowNum*ColNum]; 
 
            Rectangle cloneRect; 
            for (int i = 0; i < ColNum; i++)      //找有效區 
            { 
                for (int j = 0; j < RowNum; j++) 
                { 
                    cloneRect = new Rectangle(j*singW, i*singH, singW , singH); 
                    PicArray[i*RowNum+j]=bmpobj.Clone(cloneRect, bmpobj.PixelFormat);//復制小塊圖 
                } 
            } 
            return PicArray; 
        } 
 
        /// <summary> 
        /// 返回灰度圖片的點陣描述字串,1表示灰點,0表示背景 
        /// </summary> 
        /// <param name="singlepic">灰度圖</param> 
        /// <param name="dgGrayValue">背前景灰色界限</param> 
        /// <returns></returns> 
        public string GetSingleBmpCode(Bitmap singlepic, int dgGrayValue) 
        { 
            Color piexl; 
            string code = ""; 
            for (int posy = 0; posy < singlepic.Height; posy++) 
                for (int posx = 0; posx < singlepic.Width; posx++) 
                { 
                    piexl = singlepic.GetPixel(posx, posy); 
                    if (piexl.R < dgGrayValue)    // Color.Black ) 
                        code = code + "1"; 
                    else 
                        code = code + "0"; 
                } 
            return code; 
        } 
 
        /// <summary> 
        /// 得到灰度圖像前景背景的臨界值 最大類間方差法 
        /// </summary> 
        /// <returns>前景背景的臨界值</returns> 
        public int GetDgGrayValue() 
        { 
            int[] pixelNum = new int[256];           //圖象直方圖,共256個點 
            int n, n1, n2; 
            int total;                              //total為總和,累計值 
            double m1, m2, sum, csum, fmax, sb;     //sb為類間方差,fmax存儲最大方差值 
            int k, t, q; 
            int threshValue = 1;                      // 阈值 
            //生成直方圖 
            for (int i = 0; i < bmpobj.Width; i++) 
            { 
                for (int j = 0; j < bmpobj.Height; j++) 
                { 
                    //返回各個點的顏色,以RGB表示 
                    pixelNum[bmpobj.GetPixel(i, j).R]++;            //相應的直方圖加1 
                } 
            } 
            //直方圖平滑化 
            for (k = 0; k <= 255; k++) 
            { 
                total = 0; 
                for (t = -2; t <= 2; t++)              //與附近2個灰度做平滑化,t值應取較小的值 
                { 
                    q = k + t; 
                    if (q < 0)                     //越界處理 
                        q = 0; 
                    if (q > 255) 
                        q = 255; 
                    total = total + pixelNum[q];    //total為總和,累計值 
                } 
                pixelNum[k] = (int)((float)total / 5.0 + 0.5);    //平滑化,左邊2個+中間1個+右邊2個灰度,共5個,所以總和除以5,後面加0.5是用修正值 
            } 
            //求阈值 
            sum = csum = 0.0; 
            n = 0; 
            //計算總的圖象的點數和質量矩,為後面的計算做准備 
            for (k = 0; k <= 255; k++) 
            { 
                sum += (double)k * (double)pixelNum[k];     //x*f(x)質量矩,也就是每個灰度的值乘以其點數(歸一化後為概率),sum為其總和 
                n += pixelNum[k];                       //n為圖象總的點數,歸一化後就是累積概率 
            } 
 
            fmax = -1.0;                          //類間方差sb不可能為負,所以fmax初始值為-1不影響計算的進行 
            n1 = 0; 
            for (k = 0; k < 256; k++)                  //對每個灰度(從0到255)計算一次分割後的類間方差sb 
            { 
                n1 += pixelNum[k];                //n1為在當前阈值遍前景圖象的點數 
                if (n1 == 0) { continue; }            //沒有分出前景後景 
                n2 = n - n1;                        //n2為背景圖象的點數 
                if (n2 == 0) { break; }               //n2為0表示全部都是後景圖象,與n1=0情況類似,之後的遍歷不可能使前景點數增加,所以此時可以退出循環 
                csum += (double)k * pixelNum[k];    //前景的“灰度的值*其點數”的總和 
                m1 = csum / n1;                     //m1為前景的平均灰度 
                m2 = (sum - csum) / n2;               //m2為背景的平均灰度 
                sb = (double)n1 * (double)n2 * (m1 - m2) * (m1 - m2);   //sb為類間方差 
                if (sb > fmax)                  //如果算出的類間方差大於前一次算出的類間方差 
                { 
                    fmax = sb;                    //fmax始終為最大類間方差(otsu) 
                    threshValue = k;              //取最大類間方差時對應的灰度的k就是最佳阈值 
                } 
            } 
            return threshValue; 
        } 
 
        /// <summary> 
        ///  去掉雜點(適合雜點/雜線粗為1) 
        /// </summary> 
        /// <param name="dgGrayValue">背前景灰色界限</param> 
        /// <returns></returns> 
        public void ClearNoise(int dgGrayValue, int MaxNearPoints) 
        { 
            Color piexl; 
            int nearDots = 0; 
            //逐點判斷 
            for (int i = 0; i < bmpobj.Width; i++) 
                for (int j = 0; j < bmpobj.Height; j++) 
                { 
                    piexl = bmpobj.GetPixel(i, j); 
                    if (piexl.R < dgGrayValue) 
                    { 
                        nearDots = 0; 
                        //判斷周圍8個點是否全為空 
                        if (i == 0 || i == bmpobj.Width - 1 || j == 0 || j == bmpobj.Height - 1)  //邊框全去掉 
                        { 
                            bmpobj.SetPixel(i, j, Color.FromArgb(255, 255, 255)); 
                        } 
                        else 
                        { 
                            if (bmpobj.GetPixel(i - 1, j - 1).R < dgGrayValue) nearDots++; 
                            if (bmpobj.GetPixel(i, j - 1).R < dgGrayValue) nearDots++; 
                            if (bmpobj.GetPixel(i + 1, j - 1).R < dgGrayValue) nearDots++; 
                            if (bmpobj.GetPixel(i - 1, j).R < dgGrayValue) nearDots++; 
                            if (bmpobj.GetPixel(i + 1, j).R < dgGrayValue) nearDots++; 
                            if (bmpobj.GetPixel(i - 1, j + 1).R < dgGrayValue) nearDots++; 
                            if (bmpobj.GetPixel(i, j + 1).R < dgGrayValue) nearDots++; 
                            if (bmpobj.GetPixel(i + 1, j + 1).R < dgGrayValue) nearDots++; 
                        } 
 
                        if (nearDots < MaxNearPoints) 
                            bmpobj.SetPixel(i, j, Color.FromArgb(255, 255, 255));   //去掉單點 && 粗細小3鄰邊點 
                    } 
                    else  //背景 
                        bmpobj.SetPixel(i, j, Color.FromArgb(255, 255, 255)); 
                } 
        } 
 
        /// <summary> 
        /// 3×3中值濾波除雜 
        /// </summary> 
        /// <param name="dgGrayValue"></param> 
        public void ClearNoise(int dgGrayValue) 
        { 
            int x, y; 
            byte[] p = new byte[9]; //最小處理窗口3*3 
            byte s; 
            //byte[] lpTemp=new BYTE[nByteWidth*nHeight]; 
            int i, j; 
            //--!!!!!!!!!!!!!!下面開始窗口為3×3中值濾波!!!!!!!!!!!!!!!! 
            for (y = 1; y < bmpobj.Height - 1; y++) //--第一行和最後一行無法取窗口 
            { 
                for (x = 1; x < bmpobj.Width - 1; x++) 
                { 
                    //取9個點的值 
                    p[0] = bmpobj.GetPixel(x - 1, y - 1).R; 
                    p[1] = bmpobj.GetPixel(x, y - 1).R; 
                    p[2] = bmpobj.GetPixel(x + 1, y - 1).R; 
                    p[3] = bmpobj.GetPixel(x - 1, y).R; 
                    p[4] = bmpobj.GetPixel(x, y).R; 
                    p[5] = bmpobj.GetPixel(x + 1, y).R; 
                    p[6] = bmpobj.GetPixel(x - 1, y + 1).R; 
                    p[7] = bmpobj.GetPixel(x, y + 1).R; 
                    p[8] = bmpobj.GetPixel(x + 1, y + 1).R; 
                    //計算中值 
                    for (j = 0; j < 5; j++) 
                    { 
                        for (i = j + 1; i < 9; i++) 
                        { 
                            if (p[j] > p[i]) 
                            { 
                                s = p[j]; 
                                p[j] = p[i]; 
                                p[i] = s; 
                            } 
                        } 
                    } 
                    //      if (bmpobj.GetPixel(x, y).R < dgGrayValue) 
                    bmpobj.SetPixel(x, y, Color.FromArgb(p[4], p[4], p[4]));    //給有效值付中值 
                } 
            } 
        } 
 
        /// <summary> 
        /// 該函數用於對圖像進行腐蝕運算。結構元素為水平方向或垂直方向的三個點, 
        /// 中間點位於原點;或者由用戶自己定義3×3的結構元素。 
        /// </summary> 
        /// <param name="dgGrayValue">前後景臨界值</param> 
        /// <param name="nMode">腐蝕方式:0表示水平方向,1垂直方向,2自定義結構元素。</param> 
        /// <param name="structure"> 自定義的3×3結構元素</param> 
        public void ErosionPic(int dgGrayValue, int nMode, bool[,] structure) 
        { 
            int lWidth = bmpobj.Width; 
            int lHeight = bmpobj.Height; 
            Bitmap newBmp = new Bitmap(lWidth, lHeight); 
 
            int i, j, n, m;            //循環變量 
 
            if (nMode == 0) 
            { 
                //使用水平方向的結構元素進行腐蝕 
                // 由於使用1×3的結構元素,為防止越界,所以不處理最左邊和最右邊 
                // 的兩列像素 
                for (j = 0; j < lHeight; j++) 
                { 
                    for (i = 1; i < lWidth - 1; i++) 
                    { 
                        //目標圖像中的當前點先賦成黑色 
                        newBmp.SetPixel(i, j, Color.Black); 
 
                        //如果源圖像中當前點自身或者左右有一個點不是黑色, 
                        //則將目標圖像中的當前點賦成白色 
                        if (bmpobj.GetPixel(i - 1, j).R > dgGrayValue || 
                           bmpobj.GetPixel(i, j).R > dgGrayValue || 
                           bmpobj.GetPixel(i + 1, j).R > dgGrayValue) 
                            newBmp.SetPixel(i, j, Color.White); 
                    } 
                } 
            } 
            else if (nMode == 1) 
            { 
                //使用垂真方向的結構元素進行腐蝕 
                // 由於使用3×1的結構元素,為防止越界,所以不處理最上邊和最下邊 
                // 的兩行像素 
                for (j = 1; j < lHeight - 1; j++) 
                { 
                    for (i = 0; i < lWidth; i++) 
                    { 
                        //目標圖像中的當前點先賦成黑色 
                        newBmp.SetPixel(i, j, Color.Black); 
 
                        //如果源圖像中當前點自身或者左右有一個點不是黑色, 
                        //則將目標圖像中的當前點賦成白色 
                        if (bmpobj.GetPixel(i, j - 1).R > dgGrayValue || 
                           bmpobj.GetPixel(i, j).R > dgGrayValue || 
                            bmpobj.GetPixel(i, j + 1).R > dgGrayValue) 
                            newBmp.SetPixel(i, j, Color.White); 
                    } 
                } 
            } 
            else 
            { 
                if (structure.Length != 9)  //檢查自定義結構 
                    return; 
                //使用自定義的結構元素進行腐蝕 
                // 由於使用3×3的結構元素,為防止越界,所以不處理最左邊和最右邊 
                // 的兩列像素和最上邊和最下邊的兩列像素 
                for (j = 1; j < lHeight - 1; j++) 
                { 
                    for (i = 1; i < lWidth - 1; i++) 
                    { 
                        //目標圖像中的當前點先賦成黑色 
                        newBmp.SetPixel(i, j, Color.Black); 
                        //如果原圖像中對應結構元素中為黑色的那些點中有一個不是黑色, 
                        //則將目標圖像中的當前點賦成白色 
                        for (m = 0; m < 3; m++) 
                        { 
                            for (n = 0; n < 3; n++) 
                            { 
                                if (!structure[m, n]) 
                                    continue; 
                                if (bmpobj.GetPixel(i + m - 1, j + n - 1).R > dgGrayValue) 
                                { 
                                    newBmp.SetPixel(i, j, Color.White); 
                                    break; 
                                } 
                            } 
                        } 
                    } 
                } 
            } 
            bmpobj = newBmp; 
        } 
 
        /// <summary> 
        /// 該函數用於對圖像進行細化運算。要求目標圖像為灰度圖像 
        /// </summary> 
        /// <param name="dgGrayValue"></param> 
        public void ThiningPic(int dgGrayValue) 
        { 
            int lWidth = bmpobj.Width; 
            int lHeight = bmpobj.Height; 
            //   Bitmap newBmp = new Bitmap(lWidth, lHeight); 
 
            bool bModified;            //髒標記     
            int i, j, n, m;            //循環變量 
 
            //四個條件 
            bool bCondition1; 
            bool bCondition2; 
            bool bCondition3; 
            bool bCondition4; 
 
            int nCount;    //計數器     
            int[,] neighbour = new int[5, 5];    //5×5相鄰區域像素值 
 
 
 
            bModified = true; 
            while (bModified) 
            { 
                bModified = false; 
 
                //由於使用5×5的結構元素,為防止越界,所以不處理外圍的幾行和幾列像素 
                for (j = 2; j < lHeight - 2; j++) 
                { 
                    for (i = 2; i < lWidth - 2; i++) 
                    { 
                        bCondition1 = false; 
                        bCondition2 = false; 
                        bCondition3 = false; 
                        bCondition4 = false; 
 
                        if (bmpobj.GetPixel(i, j).R > dgGrayValue) 
                        { 
                            if (bmpobj.GetPixel(i, j).R < 255) 
                                bmpobj.SetPixel(i, j, Color.White); 
                            continue; 
                        } 
 
                        //獲得當前點相鄰的5×5區域內像素值,白色用0代表,黑色用1代表 
                        for (m = 0; m < 5; m++) 
                        { 
                            for (n = 0; n < 5; n++) 
                            { 
                                neighbour[m, n] = bmpobj.GetPixel(i + m - 2, j + n - 2).R < dgGrayValue ? 1 : 0; 
                            } 
                        } 
 
                        //逐個判斷條件。 
                        //判斷2<=NZ(P1)<=6 
                        nCount = neighbour[1, 1] + neighbour[1, 2] + neighbour[1, 3] 
                               + neighbour[2, 1] + neighbour[2, 3] + 
                                +neighbour[3, 1] + neighbour[3, 2] + neighbour[3, 3]; 
                        if (nCount >= 2 && nCount <= 6) 
                        { 
                            bCondition1 = true; 
                        } 
 
                        //判斷Z0(P1)=1 
                        nCount = 0; 
                        if (neighbour[1, 2] == 0 && neighbour[1, 1] == 1) 
                            nCount++; 
                        if (neighbour[1, 1] == 0 && neighbour[2, 1] == 1) 
                            nCount++; 
                        if (neighbour[2, 1] == 0 && neighbour[3, 1] == 1) 
                            nCount++; 
                        if (neighbour[3, 1] == 0 && neighbour[3, 2] == 1) 
                            nCount++; 
                        if (neighbour[3, 2] == 0 && neighbour[3, 3] == 1) 
                            nCount++; 
                        if (neighbour[3, 3] == 0 && neighbour[2, 3] == 1) 
                            nCount++; 
                        if (neighbour[2, 3] == 0 && neighbour[1, 3] == 1) 
                            nCount++; 
                        if (neighbour[1, 3] == 0 && neighbour[1, 2] == 1) 
                            nCount++; 
                        if (nCount == 1) 
                            bCondition2 = true; 
 
                        //判斷P2*P4*P8=0 or Z0(p2)!=1 
                        if (neighbour[1, 2] * neighbour[2, 1] * neighbour[2, 3] == 0) 
                        { 
                            bCondition3 = true; 
                        } 
                        else 
                        { 
                            nCount = 0; 
                            if (neighbour[0, 2] == 0 && neighbour[0, 1] == 1) 
                                nCount++; 
                            if (neighbour[0, 1] == 0 && neighbour[1, 1] == 1) 
                                nCount++; 
                            if (neighbour[1, 1] == 0 && neighbour[2, 1] == 1) 
                                nCount++; 
                            if (neighbour[2, 1] == 0 && neighbour[2, 2] == 1) 
                                nCount++; 
                            if (neighbour[2, 2] == 0 && neighbour[2, 3] == 1) 
                                nCount++; 
                            if (neighbour[2, 3] == 0 && neighbour[1, 3] == 1) 
                                nCount++; 
                            if (neighbour[1, 3] == 0 && neighbour[0, 3] == 1) 
                                nCount++; 
                            if (neighbour[0, 3] == 0 && neighbour[0, 2] == 1) 
                                nCount++; 
                            if (nCount != 1) 
                                bCondition3 = true; 
                        } 
 
                        //判斷P2*P4*P6=0 or Z0(p4)!=1 
                        if (neighbour[1, 2] * neighbour[2, 1] * neighbour[3, 2] == 0) 
                        { 
                            bCondition4 = true; 
                        } 
                        else 
                        { 
                            nCount = 0; 
                            if (neighbour[1, 1] == 0 && neighbour[1, 0] == 1) 
                                nCount++; 
                            if (neighbour[1, 0] == 0 && neighbour[2, 0] == 1) 
                                nCount++; 
                            if (neighbour[2, 0] == 0 && neighbour[3, 0] == 1) 
                                nCount++; 
                            if (neighbour[3, 0] == 0 && neighbour[3, 1] == 1) 
                                nCount++; 
                            if (neighbour[3, 1] == 0 && neighbour[3, 2] == 1) 
                                nCount++; 
                            if (neighbour[3, 2] == 0 && neighbour[2, 2] == 1) 
                                nCount++; 
                            if (neighbour[2, 2] == 0 && neighbour[1, 2] == 1) 
                                nCount++; 
                            if (neighbour[1, 2] == 0 && neighbour[1, 1] == 1) 
                                nCount++; 
                            if (nCount != 1) 
                                bCondition4 = true; 
                        } 
 
                        if (bCondition1 && bCondition2 && bCondition3 && bCondition4) 
                        { 
                            bmpobj.SetPixel(i, j, Color.White); 
                            bModified = true; 
                        } 
                        else 
                        { 
                            bmpobj.SetPixel(i, j, Color.Black); 
                        } 
                    } 
                } 
            } 
            // 復制細化後的圖像 
            //    bmpobj = newBmp; 
        } 
 
        /// <summary> 
        /// 銳化要啟用不安全代碼編譯 
        /// </summary> 
        /// <param name="val">銳化程度。取值[0,1]。值越大銳化程度越高</param> 
        /// <returns>銳化後的圖像</returns> 
        public void Sharpen(float val) 
        { 
            int w = bmpobj.Width; 
            int h = bmpobj.Height; 
            Bitmap bmpRtn = new Bitmap(w, h, PixelFormat.Format24bppRgb); 
            BitmapData srcData = bmpobj.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); 
            BitmapData dstData = bmpRtn.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); 
            unsafe 
            { 
                byte* pIn = (byte*)srcData.Scan0.ToPointer(); 
                byte* pOut = (byte*)dstData.Scan0.ToPointer(); 
                int stride = srcData.Stride; 
                byte* p; 
 
                for (int y = 0; y < h; y++) 
                { 
                    for (int x = 0; x < w; x++) 
                    { 
                        //取周圍9點的值。位於邊緣上的點不做改變。 
                        if (x == 0 || x == w - 1 || y == 0 || y == h - 1) 
                        { 
                            //不做 
                            pOut[0] = pIn[0]; 
                            pOut[1] = pIn[1]; 
                            pOut[2] = pIn[2]; 
                        } 
                        else 
                        { 
                            int r1, r2, r3, r4, r5, r6, r7, r8, r0; 
                            int g1, g2, g3, g4, g5, g6, g7, g8, g0; 
                            int b1, b2, b3, b4, b5, b6, b7, b8, b0; 
 
                            float vR, vG, vB; 
 
                            //左上 
                            p = pIn - stride - 3; 
                            r1 = p[2]; 
                            g1 = p[1]; 
                            b1 = p[0]; 
 
                            //正上 
                            p = pIn - stride; 
                            r2 = p[2]; 
                            g2 = p[1]; 
                            b2 = p[0]; 
 
                            //右上 
                            p = pIn - stride + 3; 
                            r3 = p[2]; 
                            g3 = p[1]; 
                            b3 = p[0]; 
 
                            //左側 
                            p = pIn - 3; 
                            r4 = p[2]; 
                            g4 = p[1]; 
                            b4 = p[0]; 
 
                            //右側 
                            p = pIn + 3; 
                            r5 = p[2]; 
                            g5 = p[1]; 
                            b5 = p[0]; 
 
                            //右下 
                            p = pIn + stride - 3; 
                            r6 = p[2]; 
                            g6 = p[1]; 
                            b6 = p[0]; 
 
                            //正下 
                            p = pIn + stride; 
                            r7 = p[2]; 
                            g7 = p[1]; 
                            b7 = p[0]; 
 
                            //右下 
                            p = pIn + stride + 3; 
                            r8 = p[2]; 
                            g8 = p[1]; 
                            b8 = p[0]; 
 
                            //自己 
                            p = pIn; 
                            r0 = p[2]; 
                            g0 = p[1]; 
                            b0 = p[0]; 
 
                            vR = (float)r0 - (float)(r1 + r2 + r3 + r4 + r5 + r6 + r7 + r8) / 8; 
                            vG = (float)g0 - (float)(g1 + g2 + g3 + g4 + g5 + g6 + g7 + g8) / 8; 
                            vB = (float)b0 - (float)(b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8) / 8; 
 
                            vR = r0 + vR * val; 
                            vG = g0 + vG * val; 
                            vB = b0 + vB * val; 
 
                            if (vR > 0) 
                            { 
                                vR = Math.Min(255, vR); 
                            } 
                            else 
                            { 
                                vR = Math.Max(0, vR); 
                            } 
 
                            if (vG > 0) 
                            { 
                                vG = Math.Min(255, vG); 
                            } 
                            else 
                            { 
                                vG = Math.Max(0, vG); 
                            } 
 
                            if (vB > 0) 
                            { 
                                vB = Math.Min(255, vB); 
                            } 
                            else 
                            { 
                                vB = Math.Max(0, vB); 
                            } 
 
                            pOut[0] = (byte)vB; 
                            pOut[1] = (byte)vG; 
                            pOut[2] = (byte)vR; 
                        } 
                        pIn += 3; 
                        pOut += 3; 
                    }// end of x 
                    pIn += srcData.Stride - w * 3; 
                    pOut += srcData.Stride - w * 3; 
                } // end of y 
            } 
            bmpobj.UnlockBits(srcData); 
            bmpRtn.UnlockBits(dstData); 
            bmpobj = bmpRtn; 
        } 
 
        /// <summary> 
        /// 圖片二值化 
        /// </summary> 
        /// <param name="hsb"></param> 
        public void BitmapTo1Bpp(Double hsb) 
        { 
            int w = bmpobj.Width; 
            int h = bmpobj.Height; 
            Bitmap bmp = new Bitmap(w, h, PixelFormat.Format1bppIndexed); 
            BitmapData data = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed); 
            for (int y = 0; y < h; y++) 
            { 
                byte[] scan = new byte[(w + 7) / 8]; 
                for (int x = 0; x < w; x++) 
                { 
                    Color c = bmpobj.GetPixel(x, y); 
                    if (c.GetBrightness() >= hsb) scan[x / 8] |= (byte)(0x80 >> (x % 8)); 
                } 
                Marshal.Copy(scan, 0, (IntPtr)((int)data.Scan0 + data.Stride * y), scan.Length); 
            } 
            bmp.UnlockBits(data); 
            bmpobj = bmp; 
        } 
    } 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved