收集的基本圖像處理

using System;
using System.Collections.Generic;
using System.Drawing;

namespace WindowsFormsApplication1
{
    public class ImageProcess
    {
        Image m_Source;

        public ImageProcess(Image img)
        {
            m_Source = img;
        }

        public Image GetSingleColor()
        {
            Bitmap rT = new Bitmap(m_Source.Width, m_Source.Height);
            Bitmap old = (Bitmap)m_Source;
            Color pixel;

            int Width = old.Width,Height = old.Height,r,g,b,Result;
            for (int x = 0; x < Width; x++)
                for (int y = 0; y < Height; y++)
                {
                    pixel = old.GetPixel(x, y);
                    r = pixel.R;
                    g = pixel.G;
                    b = pixel.B;
                    //加權平均值法                                     
                    Result = ((int)(0.7 * r) + (int)(0.2 * g) + (int)(0.1 * b));
                    ////最大值法                                     
                    //Result = r > g ? r : g;
                    //Result = Result > b ? Result : b;
                    ////平均值法                                     
                    //Result = ((r + g + b) / 3);
                    rT.SetPixel(x, y, Color.FromArgb(Result, Result, Result));
                }

            return rT;
        }

        public Image GetPartCut(int left, int top, int width, int heigh)
        {
            Bitmap rT = new Bitmap(width, heigh);
            using (Graphics g = Graphics.FromImage(rT))
            {
                g.DrawImage(m_Source, new Point(-left, -top));
            }

            return rT;
        }

        /// <summary>
        /// 替換連通的顏色,一般用於替換背景色。
        /// 低效函數,未優化
        /// </summary>
        public Image ReplaceColor(Point select,Color newColor,int CheckRange)
        {
            Bitmap rT = (Bitmap)m_Source;
            byte[,] arr = new byte[rT.Width, rT.Height];

            int nowX = select.X,nowY = select.Y;
            Color targetColor = rT.GetPixel(nowX, nowY);
            ResetmatrixPoint(nowX, nowY, arr, rT, newColor);
            CheckPoint(nowX, nowY, arr, rT, newColor,targetColor, CheckRange);

            return rT;
        }

        void ResetmatrixPoint(int x, int y, byte[,] state, Bitmap t, Color toSet)
        {
            t.SetPixel(x, y, toSet);
            state[x, y] = 10;
            //state 0-未計算  10-已改變顏色  20-需要檢測 30-已檢測並否定
            int xsmall = x - 1;
            int xbigger = x + 1;
            int ysmall = y - 1;
            int ybigger = y + 1;

            if (xsmall > 0)
            {
                if (ysmall > 0 && state[xsmall, ysmall] == 0)
                    state[xsmall, ysmall] = 20;
                if (state[xsmall, y] == 0)
                    state[xsmall, y] = 20;
                if (ybigger < t.Height && state[xsmall, ybigger] == 0)
                    state[xsmall, ybigger] = 20;
            }
            if (ysmall > 0 && state[x, ysmall] == 0)
                state[x, ysmall] = 20;
            if (ybigger < t.Height && state[x, ybigger] == 0)
                state[x, ybigger] = 20;
            if (xbigger < t.Width)
            {
                if (ysmall > 0 && state[xbigger, ysmall] == 0)
                    state[xbigger, ysmall] = 20;
                if (state[xbigger, y] == 0)
                    state[xbigger, y] = 20;
                if (ybigger < t.Height && state[xbigger, ybigger] == 0)
                    state[xbigger, ybigger] = 20;
            }
        }

        void CheckPoint(int x,int y,byte[,] state, Bitmap t, Color toSet,Color toCMP,int arrang)
        {
            int doCount = 1;
            while (doCount > 0)
            {
                doCount = 0;
                for (int i = 0; i < t.Width; i++)
                    for (int j = 0; j < t.Height; j++)
                    {
                        if (state[i, j] == 20)
                        {
                            Color cmpColor = t.GetPixel(i, j);
                            if (ColorComp(cmpColor, toCMP) < arrang)
                            {
                                doCount++;
                                int na =toSet.A + (cmpColor.A - toCMP.A);
                                int nb=toSet.B + (cmpColor.B - toCMP.B);
                                int ng =toSet.G + (cmpColor.G - toCMP.G);
                                na = Math.Min(na,255);
                                na = Math.Max(na,0);
                                nb = Math.Min(nb,255);
                                nb = Math.Max(nb,0);
                                ng = Math.Min(ng,255);
                                ng = Math.Max(ng,0);
                                cmpColor = Color.FromArgb(na, nb, ng);
                                ResetmatrixPoint(i, j, state, t, cmpColor);
                            }
                            else
                                state[i,j] = 30;
                        }
                    }
            }
        }

        

        int ColorComp(Color a,Color b)
        {
            //通過HSV比較兩個子RGB的色差
            //比較兩個RGB的色差
            int absR = a.R - b.R;
            int absG = a.G - b.G;
            int absB = a.B - b.B;
            int rT = (int)Math.Sqrt(absR * absR + absG * absG + absB * absB);
            return rT;
        }

        /// <summary>
        /// 該函數用於對圖像進行腐蝕運算。結構元素爲水平方向或垂直方向的三個點,
        /// 中間點位於原點;或者由用戶自己定義3×3的結構元素。
        /// </summary>
        /// <param name="dgGrayValue">前後景臨界值</param>
        /// <param name="nMode">腐蝕方式:0表示水平方向,1垂直方向,2自定義結構元素。</param>
        /// <param name="structure"> 自定義的3×3結構元素</param>
        public Image ErosionPic(int dgGrayValue, int nMode, bool[,] structure)
        {
            Bitmap m_New = (Bitmap)m_Source;
            int lWidth = m_New.Width;
            int lHeight = m_New.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 (m_New.GetPixel(i - 1, j).R > dgGrayValue ||
                            m_New.GetPixel(i, j).R > dgGrayValue ||
                            m_New.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 (m_New.GetPixel(i, j - 1).R > dgGrayValue ||
                            m_New.GetPixel(i, j).R > dgGrayValue ||
                            m_New.GetPixel(i, j + 1).R > dgGrayValue)
                            newBmp.SetPixel(i, j, Color.White);
                    }
                }
            }
            else
            {
                if (structure.Length != 9)  //檢查自定義結構
                    return null;
                //使用自定義的結構元素進行腐蝕
                // 由於使用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 (m_New.GetPixel(i + m - 1, j + n - 1).R > dgGrayValue)
                                {
                                    newBmp.SetPixel(i, j, Color.White);
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            return newBmp;
        }


        /// <summary>
        /// 該函數用於對圖像進行細化運算。要求目標圖像爲灰度圖像
        /// </summary>
        /// <param name="dgGrayValue"></param>
        public Image ThiningPic(int dgGrayValue)
        {
            Bitmap m_New = (Bitmap)m_Source;
            int lWidth = m_New.Width;
            int lHeight = m_New.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 (m_New.GetPixel(i, j).R > dgGrayValue)  
                        {
                            if(m_New.GetPixel(i, j).R<255)
                                m_New.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] = m_New.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)
                        {
                            m_New.SetPixel(i, j, Color.White);
                            bModified = true;
                        }
                        else
                        {
                            m_New.SetPixel(i, j, Color.Black);
                        }
                    }
                }
            }

            return m_New;
        }

    }
}

發佈了42 篇原創文章 · 獲贊 7 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章