• 灰度图像的腐蚀算法和细化算法(C#代码)


        最近做一些图像处理,需要将图像中的一些像素过滤一下,有网友给提了个名词:腐蚀算法。我不是学图像学的,乍一听,觉得很神奇。后来从网上收集了一些VC代码,研究了一下,发现其它也就是那么回事。尤其是腐蚀算法,我在以前的验证码图片去噪声的文章中提到过,只是那是我不知叫什么名词,就从用途出发,叫做“根据周边点数去噪”。腐蚀的原理也一样,就是根据当前点的周边点数(如3X3的,周边就有8个点)来修改当前点的状态的。 
        代码是我从VC代码中转译过来的,注释都沿用了原作者的文字(别说是剽窃,^_^)。唯一改进的地方是,原代码功能只能处理0和255的二值灰度(搞不懂为什么这样,对于250、128这样的都不行,还不如弄成二值灰度,别弄256灰度了),我将之改成了能根据0~255中任意灰度划界的256灰度图像!
        以下是C#代码:
      1        /// <summary>
      2        /// 该函数用于对图像进行腐蚀运算。结构元素为水平方向或垂直方向的三个点,
      3        /// 中间点位于原点;或者由用户自己定义3×3的结构元素。
      4        /// </summary>
      5        /// <param name="dgGrayValue">前后景临界值</param>
      6        /// <param name="nMode">腐蚀方式:0表示水平方向,1垂直方向,2自定义结构元素。</param>
      7        /// <param name="structure"> 自定义的3×3结构元素</param>

      8        public void ErosionPic(int dgGrayValue, int nMode, bool[,] structure)
      9        {
     10            int lWidth = bmpobj.Width;
     11            int lHeight = bmpobj.Height;
     12            Bitmap newBmp = new Bitmap(lWidth, lHeight);
     13
     14            int i, j, n, m;            //循环变量
     15            Color pixel;    //像素颜色值
     16
     17            if (nMode == 0)
     18            {
     19                //使用水平方向的结构元素进行腐蚀
     20                // 由于使用1×3的结构元素,为防止越界,所以不处理最左边和最右边
     21                // 的两列像素
     22                for (j = 0; j < lHeight; j++)
     23                {
     24                    for (i = 1; i < lWidth - 1; i++)
     25                    {
     26                        //目标图像中的当前点先赋成黑色
     27                        newBmp.SetPixel(i, j, Color.Black);
     28
     29                        //如果源图像中当前点自身或者左右有一个点不是黑色,
     30                        //则将目标图像中的当前点赋成白色
     31                        if (bmpobj.GetPixel(i - 1, j).R > dgGrayValue ||
     32                            bmpobj.GetPixel(i, j).R > dgGrayValue ||
     33                            bmpobj.GetPixel(i + 1, j).R > dgGrayValue)
     34                            newBmp.SetPixel(i, j, Color.White);
     35                    }

     36                }

     37            }

     38            else if (nMode == 1)
     39            {
     40                //使用垂真方向的结构元素进行腐蚀
     41                // 由于使用3×1的结构元素,为防止越界,所以不处理最上边和最下边
     42                // 的两行像素
     43                for (j = 1; j < lHeight - 1; j++)
     44                {
     45                    for (i = 0; i < lWidth; i++)
     46                    {
     47                        //目标图像中的当前点先赋成黑色
     48                        newBmp.SetPixel(i, j, Color.Black);
     49
     50                        //如果源图像中当前点自身或者左右有一个点不是黑色,
     51                        //则将目标图像中的当前点赋成白色
     52                        if (bmpobj.GetPixel(i, j - 1).R > dgGrayValue ||
     53                            bmpobj.GetPixel(i, j).R > dgGrayValue ||
     54                            bmpobj.GetPixel(i, j + 1).R > dgGrayValue)
     55                            newBmp.SetPixel(i, j, Color.White);
     56                    }

     57                }

     58            }

     59            else
     60            {
     61                if (structure.Length != 9)  //检查自定义结构
     62                    return;
     63                //使用自定义的结构元素进行腐蚀
     64                // 由于使用3×3的结构元素,为防止越界,所以不处理最左边和最右边
     65                // 的两列像素和最上边和最下边的两列像素
     66                for (j = 1; j < lHeight - 1; j++)
     67                {
     68                    for (i = 1; i < lWidth - 1; i++)
     69                    {
     70                        //目标图像中的当前点先赋成黑色
     71                        newBmp.SetPixel(i, j, Color.Black);
     72                        //如果原图像中对应结构元素中为黑色的那些点中有一个不是黑色,
     73                        //则将目标图像中的当前点赋成白色
     74                        for (m = 0; m < 3; m++)
     75                        {
     76                            for (n = 0; n < 3; n++)
     77                            {
     78                                if (!structure[m, n])
     79                                    continue;
     80                                if (bmpobj.GetPixel(i + m - 1, j + n - 1).R > dgGrayValue)
     81                                {
     82                                    newBmp.SetPixel(i, j, Color.White);
     83                                    break;
     84                                }

     85                            }

     86                        }

     87                    }

     88                }

     89            }

     90
     91            bmpobj = newBmp;
     92        }

     93
     94
     95        /// <summary>
     96        /// 该函数用于对图像进行细化运算。要求目标图像为灰度图像
     97        /// </summary>
     98        /// <param name="dgGrayValue"></param>

     99        public void ThiningPic(int dgGrayValue)
    100        {
    101            int lWidth = bmpobj.Width;
    102            int lHeight = bmpobj.Height;
    103         //   Bitmap newBmp = new Bitmap(lWidth, lHeight);
    104
    105            bool bModified;            //脏标记    
    106            int i, j, n, m;            //循环变量
    107            Color pixel;    //像素颜色值
    108
    109            //四个条件
    110            bool bCondition1;
    111            bool bCondition2;
    112            bool bCondition3;
    113            bool bCondition4;
    114
    115            int nCount;    //计数器    
    116            int[,] neighbour = new int[55];    //5×5相邻区域像素值
    117
    118
    119
    120            bModified = true;
    121            while (bModified)
    122            {
    123                bModified = false;
    124
    125                //由于使用5×5的结构元素,为防止越界,所以不处理外围的几行和几列像素
    126                for (j = 2; j < lHeight - 2; j++)
    127                {
    128                    for (i = 2; i < lWidth - 2; i++)
    129                    {
    130                        bCondition1 = false;
    131                        bCondition2 = false;
    132                        bCondition3 = false;
    133                        bCondition4 = false;
    134
    135                        if (bmpobj.GetPixel(i, j).R > dgGrayValue)  
    136                        {
    137                            if(bmpobj.GetPixel(i, j).R<255)
    138                                bmpobj.SetPixel(i, j, Color.White);
    139                            continue;
    140                        }

    141
    142                        //获得当前点相邻的5×5区域内像素值,白色用0代表,黑色用1代表
    143                        for (m = 0; m < 5; m++)
    144                        {
    145                            for (n = 0; n < 5; n++)
    146                            {
    147                                neighbour[m, n] = bmpobj.GetPixel(i + m - 2, j + n - 2).R < dgGrayValue ? 1 : 0;
    148                            }

    149                        }

    150
    151                        //逐个判断条件。
    152                        //判断2<=NZ(P1)<=6
    153                        nCount = neighbour[11+ neighbour[12+ neighbour[13]
    154                                + neighbour[21+ neighbour[23+
    155                                +neighbour[31+ neighbour[32+ neighbour[33];
    156                        if (nCount >= 2 && nCount <= 6)
    157                        {
    158                            bCondition1 = true;
    159                        }

    160
    161                        //判断Z0(P1)=1
    162                        nCount = 0;
    163                        if (neighbour[12== 0 && neighbour[11== 1)
    164                            nCount++;
    165                        if (neighbour[11== 0 && neighbour[21== 1)
    166                            nCount++;
    167                        if (neighbour[21== 0 && neighbour[31== 1)
    168                            nCount++;
    169                        if (neighbour[31== 0 && neighbour[32== 1)
    170                            nCount++;
    171                        if (neighbour[32== 0 && neighbour[33== 1)
    172                            nCount++;
    173                        if (neighbour[33== 0 && neighbour[23== 1)
    174                            nCount++;
    175                        if (neighbour[23== 0 && neighbour[13== 1)
    176                            nCount++;
    177                        if (neighbour[13== 0 && neighbour[12== 1)
    178                            nCount++;
    179                        if (nCount == 1)
    180                            bCondition2 = true;
    181
    182                        //判断P2*P4*P8=0 or Z0(p2)!=1
    183                        if (neighbour[12* neighbour[21* neighbour[23== 0)
    184                        {
    185                            bCondition3 = true;
    186                        }

    187                        else
    188                        {
    189                            nCount = 0;
    190                            if (neighbour[02== 0 && neighbour[01== 1)
    191                                nCount++;
    192                            if (neighbour[01== 0 && neighbour[11== 1)
    193                                nCount++;
    194                            if (neighbour[11== 0 && neighbour[21== 1)
    195                                nCount++;
    196                            if (neighbour[21== 0 && neighbour[22== 1)
    197                                nCount++;
    198                            if (neighbour[22== 0 && neighbour[23== 1)
    199                                nCount++;
    200                            if (neighbour[23== 0 && neighbour[13== 1)
    201                                nCount++;
    202                            if (neighbour[13== 0 && neighbour[03== 1)
    203                                nCount++;
    204                            if (neighbour[03== 0 && neighbour[02== 1)
    205                                nCount++;
    206                            if (nCount != 1)
    207                                bCondition3 = true;
    208                        }

    209
    210                        //判断P2*P4*P6=0 or Z0(p4)!=1
    211                        if (neighbour[12* neighbour[21* neighbour[32== 0)
    212                        {
    213                            bCondition4 = true;
    214                        }

    215                        else
    216                        {
    217                            nCount = 0;
    218                            if (neighbour[11== 0 && neighbour[10== 1)
    219                                nCount++;
    220                            if (neighbour[10== 0 && neighbour[20== 1)
    221                                nCount++;
    222                            if (neighbour[20== 0 && neighbour[30== 1)
    223                                nCount++;
    224                            if (neighbour[30== 0 && neighbour[31== 1)
    225                                nCount++;
    226                            if (neighbour[31== 0 && neighbour[32== 1)
    227                                nCount++;
    228                            if (neighbour[32== 0 && neighbour[22== 1)
    229                                nCount++;
    230                            if (neighbour[22== 0 && neighbour[12== 1)
    231                                nCount++;
    232                            if (neighbour[12== 0 && neighbour[11== 1)
    233                                nCount++;
    234                            if (nCount != 1)
    235                                bCondition4 = true;
    236                        }

    237
    238                        if (bCondition1 && bCondition2 && bCondition3 && bCondition4)
    239                        {
    240                            bmpobj.SetPixel(i, j, Color.White);
    241                            bModified = true;
    242                        }

    243                        else
    244                        {
    245                            bmpobj.SetPixel(i, j, Color.Black);
    246                        }

    247                    }

    248                }

    249            }

    250            // 复制细化后的图像
    251        //    bmpobj = newBmp;
    252        }

    253

  • 相关阅读:
    [古城子的房子] 贪心
    [小兔的棋盘] 组合数学
    [Triangle] Fibonacci+二分查找
    [Fibonacci] 矩阵快速幂
    [DP?]素数筛+Lucas定理+费马小定理
    react本地开发关闭eslint检查
    react 不同js文件里公用同一个变量
    js学习笔记
    node内存扩展,前端项目运行时报内存不足的错误
    Gitee码云通过WebHooks实现自动同步代码部署
  • 原文地址:https://www.cnblogs.com/yuanbao/p/1149923.html
Copyright © 2020-2023  润新知