天天看點

改進zhang方法圖像細化(單像素)

本文主要實作實作了和講解圖像細化算法,引用論文 “牟少敏,杜海洋,蘇平,查緒恒,陳光藝.一種改進的快速并行細化算法[J].微電子學與計算機,2013,(第1期)” ,免費下載下傳位址點選打開連結(直接在http://www.ucdrs.superlib.net/中搜尋也可)。

zhang的算法是經典的細化算法,具有速度快、保持細化後 曲線的連通性和無毛刺産生等優點,但它細化後的結果不能保證曲線紋路為單一像素,細化不徹底。

先介紹幾個基本概念:

1.目标點和背景點:目标點指像素值為1的點,與此對應,背景點像素值為0.

2.8鄰域:如圖所示,設有任意像素點 P,P的8鄰點即以P為中心的 3×3 區域中除了 P 點以外的P2到P的8個點。

改進zhang方法圖像細化(單像素)
改進zhang方法圖像細化(單像素)

3.邊界點:屬于目标點,且其8領域中至少有一個為背景點。

4.端點:屬于邊界點,且其8領域中至少有一個為目标點。

Zhang快速并行細化算法執行過程對邊界點進行如下操作:

改進zhang方法圖像細化(單像素)
改進zhang方法圖像細化(單像素)
改進zhang方法圖像細化(單像素)
改進zhang方法圖像細化(單像素)

經過細化後的圖像并非是單像素的。

改進zhang方法圖像細化(單像素)
改進zhang方法圖像細化(單像素)

牟少敏,杜海洋等提出了對zhang算法的改進,以實作單像素化。

經過分析 Zhang 算法 的原理和細化後的圖像 ,發現導緻細化後紋路非單一像素原 因是因為部分該删除的點由于不滿足 Zhang 細化算法删除條件 1.2S (P ) 一1 而被遺漏掉 ,将這些點分為三類. 如圖 3~圖 5 所 示

改進zhang方法圖像細化(單像素)
改進zhang方法圖像細化(單像素)
改進zhang方法圖像細化(單像素)
改進zhang方法圖像細化(單像素)
改進zhang方法圖像細化(單像素)

為了易于識别和計算這類點,将8領域點進行二進制編碼,從P2到P9進行二進制編碼,如下如所示

改進zhang方法圖像細化(單像素)
改進zhang方法圖像細化(單像素)

對所有遺漏目标點的8領域進行編碼,并轉為十進制,第一類點轉化結果為65、5、20和80,第二類點轉化結果為:13、97、22、208、67、88、52和133,第三類點轉化結果為141、99、54和216。

在掃描過程中上述16種目标點不能全部删除,否則會出現斷點。适當選取删除點,已達到最好的細化結果。實驗發現删除以下組合中的10個點最為良好。第一類4種全部删除,編碼組合為{65,5,20,80},第二類中選擇4種删除,編碼組合為{13,22,52,133},第三類種删除2個,編碼組合為{141,54},總的删除點集合為{65,5,20,80,13,22,52,133,141,54}

改進後的算法描述如下

改進zhang方法圖像細化(單像素)
改進zhang方法圖像細化(單像素)
改進zhang方法圖像細化(單像素)

實作代碼如下:

void zhang_thinimage_improve(Mat &srcimage)//單通道、二值化後的圖像  
{  
    vector<Point> deletelist1;  
    int Zhangmude[9];  
    int nl = srcimage.rows;  
    int nc = srcimage.cols;  
    while (true)  
    {  
        for (int j = 1; j<(nl - 1); j++)  
        {  
            uchar* data_last = srcimage.ptr<uchar>(j - 1);  
            uchar* data = srcimage.ptr<uchar>(j);  
            uchar* data_next = srcimage.ptr<uchar>(j + 1);  
            for (int i = 1; i<(nc - 1); i++)  
            {  
                if (data[i] == 255)  
                {  
                    Zhangmude[0] = 1;  
                    if (data_last[i] == 255) Zhangmude[1] = 1;  
                    else  Zhangmude[1] = 0;  
                    if (data_last[i + 1] == 255) Zhangmude[2] = 1;  
                    else  Zhangmude[2] = 0;  
                    if (data[i + 1] == 255) Zhangmude[3] = 1;  
                    else  Zhangmude[3] = 0;  
                    if (data_next[i + 1] == 255) Zhangmude[4] = 1;  
                    else  Zhangmude[4] = 0;  
                    if (data_next[i] == 255) Zhangmude[5] = 1;  
                    else  Zhangmude[5] = 0;  
                    if (data_next[i - 1] == 255) Zhangmude[6] = 1;  
                    else  Zhangmude[6] = 0;  
                    if (data[i - 1] == 255) Zhangmude[7] = 1;  
                    else  Zhangmude[7] = 0;  
                    if (data_last[i - 1] == 255) Zhangmude[8] = 1;  
                    else  Zhangmude[8] = 0;  
                    int whitepointtotal = 0;  
                    for (int k = 1; k < 9; k++)  
                    {  
						//得到1的個數
                        whitepointtotal = whitepointtotal + Zhangmude[k];  
                    }  
                    if ((whitepointtotal >= 2) && (whitepointtotal <= 6))  
                    {  
						//得到01的個數
                        int ap = 0;  
                        if ((Zhangmude[1] == 0) && (Zhangmude[2] == 1)) ap++;  
                        if ((Zhangmude[2] == 0) && (Zhangmude[3] == 1)) ap++;  
                        if ((Zhangmude[3] == 0) && (Zhangmude[4] == 1)) ap++;  
                        if ((Zhangmude[4] == 0) && (Zhangmude[5] == 1)) ap++;  
                        if ((Zhangmude[5] == 0) && (Zhangmude[6] == 1)) ap++;  
                        if ((Zhangmude[6] == 0) && (Zhangmude[7] == 1)) ap++;  
                        if ((Zhangmude[7] == 0) && (Zhangmude[8] == 1)) ap++;  
                        if ((Zhangmude[8] == 0) && (Zhangmude[1] == 1)) ap++;  
			//計算bp
			int bp=0;
			bp+=Zhangmude[1];
			bp+=Zhangmude[2]<<1;
			bp+=Zhangmude[3]<<2;
			bp+=Zhangmude[4]<<3;
			bp+=Zhangmude[5]<<4;
			bp+=Zhangmude[6]<<5;
			bp+=Zhangmude[7]<<6;
			bp+=Zhangmude[8]<<7;

                        if (ap == 1||bp==65||bp==5||bp==20||bp==80||bp==13||bp==22||bp==52||bp==133||bp==141||bp==54)  
                        {  
                            if ((Zhangmude[1] * Zhangmude[7] * Zhangmude[5] == 0) && (Zhangmude[3] * Zhangmude[5] * Zhangmude[7] == 0))  
                            {  
                                deletelist1.push_back(Point(i, j));  //滿足條件,去除該點
                            }  
                        }  
                    }  
                }  
            }  
        }  
        if (deletelist1.size() == 0) break;  
        for (size_t i = 0; i < deletelist1.size(); i++)  
        {  
            Point tem;  
            tem = deletelist1[i];  
            uchar* data = srcimage.ptr<uchar>(tem.y);  
            data[tem.x] = 0;  
        }  
        deletelist1.clear();  
  
		
        for (int j = 1; j<(nl - 1); j++)  
        {  
            uchar* data_last = srcimage.ptr<uchar>(j - 1);  
            uchar* data = srcimage.ptr<uchar>(j);  
            uchar* data_next = srcimage.ptr<uchar>(j + 1);  
            for (int i = 1; i<(nc - 1); i++)  
            {  
                if (data[i] == 255)  
                {  
                    Zhangmude[0] = 1;  
                    if (data_last[i] == 255) Zhangmude[1] = 1;  
                    else  Zhangmude[1] = 0;  
                    if (data_last[i + 1] == 255) Zhangmude[2] = 1;  
                    else  Zhangmude[2] = 0;  
                    if (data[i + 1] == 255) Zhangmude[3] = 1;  
                    else  Zhangmude[3] = 0;  
                    if (data_next[i + 1] == 255) Zhangmude[4] = 1;  
                    else  Zhangmude[4] = 0;  
                    if (data_next[i] == 255) Zhangmude[5] = 1;  
                    else  Zhangmude[5] = 0;  
                    if (data_next[i - 1] == 255) Zhangmude[6] = 1;  
                    else  Zhangmude[6] = 0;  
                    if (data[i - 1] == 255) Zhangmude[7] = 1;  
                    else  Zhangmude[7] = 0;  
                    if (data_last[i - 1] == 255) Zhangmude[8] = 1;  
                    else  Zhangmude[8] = 0;  
                    int whitepointtotal = 0;  
                    for (int k = 1; k < 9; k++)  
                    {  
                        whitepointtotal = whitepointtotal + Zhangmude[k];  
                    }  
                    if ((whitepointtotal >= 2) && (whitepointtotal <= 6))  
                    {  
                        int ap = 0;  
                        if ((Zhangmude[1] == 0) && (Zhangmude[2] == 1)) ap++;  
                        if ((Zhangmude[2] == 0) && (Zhangmude[3] == 1)) ap++;  
                        if ((Zhangmude[3] == 0) && (Zhangmude[4] == 1)) ap++;  
                        if ((Zhangmude[4] == 0) && (Zhangmude[5] == 1)) ap++;  
                        if ((Zhangmude[5] == 0) && (Zhangmude[6] == 1)) ap++;  
                        if ((Zhangmude[6] == 0) && (Zhangmude[7] == 1)) ap++;  
                        if ((Zhangmude[7] == 0) && (Zhangmude[8] == 1)) ap++;  
                        if ((Zhangmude[8] == 0) && (Zhangmude[1] == 1)) ap++;  
			int bp=0;
			bp+=Zhangmude[1];
			bp+=Zhangmude[2]<<1;
			bp+=Zhangmude[3]<<2;
			bp+=Zhangmude[4]<<3;
			bp+=Zhangmude[5]<<4;
			bp+=Zhangmude[6]<<5;
			bp+=Zhangmude[7]<<6;
			bp+=Zhangmude[8]<<7;				
                        if (ap == 1||bp==65||bp==5||bp==20||bp==80||bp==13||bp==22||bp==52||bp==133||bp==141||bp==54)  
                        {  
                            if ((Zhangmude[1] * Zhangmude[3] * Zhangmude[5] == 0) && (Zhangmude[3] * Zhangmude[1] * Zhangmude[7] == 0))  
                            {  
                                deletelist1.push_back(Point(i, j));  
                            }  
                        }  
                    }  
                }  
            }  
        }  
        if (deletelist1.size() == 0) break;  
        for (size_t i = 0; i < deletelist1.size(); i++)  
        {  
            Point tem;  
            tem = deletelist1[i];  
            uchar* data = srcimage.ptr<uchar>(tem.y);  
            data[tem.x] = 0;  
        }  
        deletelist1.clear(); 
    }  
}
           

zhang方法

改進zhang方法圖像細化(單像素)

改進方法

改進zhang方法圖像細化(單像素)

改進方法剔除的點

改進zhang方法圖像細化(單像素)

如有對論文作者造成侵權,請與我聯系删除

繼續閱讀