灰度圖像的腐蝕算法和細化算法(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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章