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

C#圖像細化:Hilditch細化算法

編輯:C#入門知識

上理論:
Hilditch 細化算法的步驟為:

對圖像從左向右從上向下迭代每個像素,是為一個迭代周期。在每個迭代周期中,對於每一個像素p,如果它同時滿足6個條件,則標記它。在當前迭代周期結束時,則把所有標記的像素的值設為背景值。如果某次迭代周期中不存在標記點(即滿足6個條件的像素),則算法結束。假設背景值為0,前景值為1,則:

6個條件為:

(I):p 為1,即p不是背景;

(2):x1,x3,x5,x7不全部為1(否則把p標記刪除,圖像空心了);

(3):x1~x8 中,至少有2個為1(若只有1個為1,則是線段的端點。若沒有為1的,則為孤立點);

(4):p的8連通聯結數為1;

聯結數指在像素p的3*3鄰域中,和p連接的圖形分量的個數:

(5)假設x3已經標記刪除,那麼當x3為0時,p的8聯通聯結數為1;

(6)假設x5已經標記刪除,那麼當x5為0時,p的8聯通聯結數為1。


我上一個自己寫的代碼

 

[csharp]
/// <summary>  
        /// Hilditch細化算法  
        /// </summary>  
        /// <param name="input"></param>  
        /// <returns></returns>  
        private int[,] ThinnerHilditch(int[,] input) 
        { 
            int lWidth = input.GetLength(0); 
            int lHeight = input.GetLength(1); 
 
            bool IsModified = true; 
            int Counter = 1; 
            int[] nnb = new int[9]; 
            //去掉邊框像素  
            for (int i = 0; i < lWidth; i++) 
            { 
                input[i, 0] = 0; 
                input[i, lHeight - 1] = 0; 
            } 
            for (int j = 0; j < lHeight; j++) 
            { 
                input[0, j] = 0; 
                input[lWidth - 1, j] = 0; 
            } 
            do 
            { 
                Counter++; 
                IsModified = false; 
                int[,] nb = new int[3, 3]; 
                for (int i = 1; i < lWidth; i++) 
                { 
                    for (int j = 1; j < lHeight; j++) 
                    { 
                        //條件1必須為黑點  
                        if (input[i, j] != 1) 
                        { 
                            continue; 
                        } 
 
                        //取3*3領域  
                        for (int m = 0; m < 3; m++) 
                        { 
                            for (int n = 0; n < 3; n++) 
                            { 
                                nb[m, n] = input[i - 1 + m, j - 1 + n]; 
                            } 
                        } 
                        //復制  
                        nnb[0] = nb[2, 1]==1?0:1; 
                        nnb[1] = nb[2, 0]==1?0:1; 
                        nnb[2] = nb[1, 0]==1?0:1; 
                        nnb[3] = nb[0, 0]==1?0:1; 
                        nnb[4] = nb[0, 1]==1?0:1; 
                        nnb[5] = nb[0, 2]==1?0:1; 
                        nnb[6] = nb[1, 2]==1?0:1; 
                        nnb[7] = nb[2, 2]==1?0:1; 
 
                        // 條件2:p0,p2,p4,p6 不皆為前景點   
                        if (nnb[0] == 0 && nnb[2] == 0 && nnb[4] == 0 && nnb[6] == 0) 
                        { 
                            continue; 
                        } 
                        // 條件3: p0~p7至少兩個是前景點   
                        int iCount = 0; 
                        for (int ii = 0; ii < 8; ii++) 
                        { 
                            iCount += nnb[ii]; 
                        } 
                        if (iCount > 6) continue;  
                         
                        // 條件4:聯結數等於1   
                        if (DetectConnectivity(nnb) != 1) 
                        { 
                            continue; 
                        } 
                        // 條件5: 假設p2已標記刪除,則令p2為背景,不改變p的聯結數   
                        if (input[i, j - 1] == -1) 
                        { 
                            nnb[2] = 1; 
                            if (DetectConnectivity(nnb) != 1) 
                                continue; 
                            nnb[2] = 0; 
                        } 
                        // 條件6: 假設p4已標記刪除,則令p4為背景,不改變p的聯結數   
                        if (input[i, j + 1] == -1) 
                        { 
                            nnb[6] = 1; 
                            if (DetectConnectivity(nnb) != 1) 
                                continue; 
                            nnb[6] = 0; 
                        } 
 
                        input[i, j] = -1; 
                        IsModified = true; 
                    } 
                } 
                for (int i = 0; i < lWidth; i++) 
                { 
                    for (int j = 0; j < lHeight; j++) 
                    { 
                        if (input[i, j] == -1) 
                        { 
                            input[i, j] = 0; 
                        } 
                    } 
                } 
 
            } while (IsModified); 
 
            return input; 
        } 
/// <summary>
        /// Hilditch細化算法 www.2cto.com
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private int[,] ThinnerHilditch(int[,] input)
        {
            int lWidth = input.GetLength(0);
            int lHeight = input.GetLength(1);

            bool IsModified = true;
            int Counter = 1;
            int[] nnb = new int[9];
            //去掉邊框像素
            for (int i = 0; i < lWidth; i++)
            {
                input[i, 0] = 0;
                input[i, lHeight - 1] = 0;
            }
            for (int j = 0; j < lHeight; j++)
            {
                input[0, j] = 0;
                input[lWidth - 1, j] = 0;
            }
            do
            {
                Counter++;
                IsModified = false;
                int[,] nb = new int[3, 3];
                for (int i = 1; i < lWidth; i++)
                {
                    for (int j = 1; j < lHeight; j++)
                    {
                        //條件1必須為黑點
                        if (input[i, j] != 1)
                        {
                            continue;
                        }

                        //取3*3領域
                        for (int m = 0; m < 3; m++)
                        {
                            for (int n = 0; n < 3; n++)
                            {
                                nb[m, n] = input[i - 1 + m, j - 1 + n];
                            }
                        }
                        //復制
                        nnb[0] = nb[2, 1]==1?0:1;
                        nnb[1] = nb[2, 0]==1?0:1;
                        nnb[2] = nb[1, 0]==1?0:1;
                        nnb[3] = nb[0, 0]==1?0:1;
                        nnb[4] = nb[0, 1]==1?0:1;
                        nnb[5] = nb[0, 2]==1?0:1;
                        nnb[6] = nb[1, 2]==1?0:1;
                        nnb[7] = nb[2, 2]==1?0:1;

                        // 條件2:p0,p2,p4,p6 不皆為前景點
                        if (nnb[0] == 0 && nnb[2] == 0 && nnb[4] == 0 && nnb[6] == 0)
                        {
                            continue;
                        }
                        // 條件3: p0~p7至少兩個是前景點
                        int iCount = 0;
                        for (int ii = 0; ii < 8; ii++)
                        {
                            iCount += nnb[ii];
                        }
                        if (iCount > 6) continue;
                       
                        // 條件4:聯結數等於1
                        if (DetectConnectivity(nnb) != 1)
                        {
                            continue;
                        }
                        // 條件5: 假設p2已標記刪除,則令p2為背景,不改變p的聯結數
                        if (input[i, j - 1] == -1)
                        {
                            nnb[2] = 1;
                            if (DetectConnectivity(nnb) != 1)
                                continue;
                            nnb[2] = 0;
                        }
                        // 條件6: 假設p4已標記刪除,則令p4為背景,不改變p的聯結數
                        if (input[i, j + 1] == -1)
                        {
                            nnb[6] = 1;
                            if (DetectConnectivity(nnb) != 1)
                                continue;
                            nnb[6] = 0;
                        }

                        input[i, j] = -1;
                        IsModified = true;
                    }
                }
                for (int i = 0; i < lWidth; i++)
                {
                    for (int j = 0; j < lHeight; j++)
                    {
                        if (input[i, j] == -1)
                        {
                            input[i, j] = 0;
                        }
                    }
                }

            } while (IsModified);

            return input;
        }
希望對大家有用。


摘自  aofengdaxia
 

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