收集的基本图像处理

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;
        }

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值