熱線電話:0755-23712116
郵箱:contact@shuangyi-tech.com
地址:深圳市寶安區(qū)沙井街道后亭茅洲山工業(yè)園工業(yè)大廈全至科技創(chuàng)新園科創(chuàng)大廈2層2A
細(xì)化技術(shù):把一個(gè)平面區(qū)域簡化成圖的結(jié)構(gòu)形狀表示法
骨架:一種細(xì)化結(jié)構(gòu),它是目標(biāo)的重要拓?fù)涿枋?,具有非常廣泛的應(yīng)用。在圖像識(shí)別或數(shù)據(jù)壓縮時(shí),經(jīng)常用細(xì)化結(jié)構(gòu)。
例如:在識(shí)別字符之前,往往要先對(duì)字符作細(xì)化處理,求出字符的細(xì)化結(jié)構(gòu)。
細(xì)化的作用:目的將圖像的骨架提取出來的同時(shí),保持圖像細(xì)小部分的連通性,對(duì)被處理的圖像進(jìn)行細(xì)化有助于突出形狀特點(diǎn)和減少冗余信息量。
細(xì)化算法:采取逐次去除邊界的方法進(jìn)行的,不能破化圖像的連通性。
通常選擇一組結(jié)構(gòu)元素對(duì),不斷在這些結(jié)構(gòu)對(duì)中循環(huán),如果所得結(jié)果不再變化,則終止迭代過程,隨著迭代的進(jìn)行,集合也不斷細(xì)化。
結(jié)構(gòu)對(duì)的選擇:僅受結(jié)構(gòu)元素不相交的限制(不同的結(jié)構(gòu)對(duì)),事實(shí)上,我們可以使用同一個(gè)結(jié)構(gòu)對(duì),即在不斷重復(fù)的迭代細(xì)化過程使用同一個(gè)結(jié)構(gòu)對(duì)。
細(xì)化滿足的條件:
1.在細(xì)化的過程中,圖像應(yīng)該有規(guī)律地縮小;
2.在圖像逐步縮小的過程中,應(yīng)當(dāng)使圖像的連通性質(zhì)保持不變。
我們對(duì)一副二值圖像進(jìn)行骨架提取,就是刪除不需要的輪廓點(diǎn),只保留其骨架點(diǎn)。假設(shè)一個(gè)像素點(diǎn),我們定義該點(diǎn)為p1,則它的八鄰域點(diǎn)p2->p9位置如下圖所示,該算法考慮p1點(diǎn)鄰域的實(shí)際情況,以便決定是否刪除p1點(diǎn)。假設(shè)我們處理的為二值圖像,背景為黑色,值為0,要細(xì)化的前景物體像素值為1。
算法的描述如下。
首先復(fù)制源圖像到目地圖像,然后建立一個(gè)臨時(shí)圖像,接著執(zhí)行下面操作:
1. 把目地圖像復(fù)制給臨時(shí)圖像,對(duì)臨時(shí)圖像進(jìn)行一次掃描,對(duì)于不為0的點(diǎn),如果滿足以下四個(gè)條件,則在目地圖像中刪除該點(diǎn)(就是設(shè)置該像素為0),這里p2,…,p9是對(duì)應(yīng)位置的像素灰度值(其為1或者0)。
a. 2<= p2+p3+p4+p5+p6+p7+p8+p9<=6
大于等于2會(huì)保證p1點(diǎn)不是端點(diǎn)或孤立點(diǎn),因?yàn)閯h除端點(diǎn)和孤立點(diǎn)是不合理的,小于等于6保證p1點(diǎn)是一個(gè)邊界點(diǎn),而不是一個(gè)內(nèi)部點(diǎn)。等于0時(shí)候,周圍沒有等于1的像素,所以p1為孤立點(diǎn),等于1的時(shí)候,周圍只有1個(gè)灰度等于1的像素,所以是端點(diǎn)(注:端點(diǎn)是周圍有且只能有1個(gè)值為1的像素)。
b. p2->p9的排列順序中,01模式的數(shù)量為1,比如下面的圖中,有p2p3 => 01, p6p7=>01,所以該像素01模式的數(shù)量為2。
之所以要01模式數(shù)量為1,是要保證刪除當(dāng)前像素點(diǎn)后的連通性。比如下面的圖中,01模式數(shù)量大于1,如果刪除當(dāng)前點(diǎn)p1,則連通性不能保證。
c. P2*p4*p6 = 0
d. p4*p6*p8 = 0
在第一次子迭代中,只是移去東南的邊界點(diǎn),而不考慮西北的邊界點(diǎn),注意p4,p6出現(xiàn)了2次,就是說它們有一個(gè)為0,則c,d就滿足。
2. 接下來,把目地圖像再次復(fù)制到臨時(shí)圖像,接著對(duì)臨時(shí)圖像進(jìn)行一次掃描,如果不為0的點(diǎn)它的八鄰域滿足以下4個(gè)條件,則在目地圖像中刪除該點(diǎn)(就是設(shè)置該像素為0)
a. 2<= p2+p3+p4+p5+p6+p7+p8+p9<=6
b. p2->p9的排列順序中,01模式的數(shù)量(這里假設(shè)二值圖非零值為1)為1。
c. p2*p4*p8 = 0
d. p2*p6*p8 = 0
第二次迭代則相反,會(huì)移去西北的邊界點(diǎn),注意p2,p8出現(xiàn)了2次,就是說它們有一個(gè)為0,則c,d就滿足。
執(zhí)行完上面兩個(gè)步驟后,就完成了一次細(xì)化算法,我們可以多次迭代執(zhí)行上述過程,得到最終的骨架圖。
1.首先對(duì)圖像進(jìn)行二值化,白色為255,黑色為0。
2.設(shè)置一個(gè)3*3的領(lǐng)域S模板。
3.S模板中各個(gè)位置上的取值取決于模板所對(duì)應(yīng)圖像中不同位置的像素,如果S模板某一個(gè)位置上所對(duì)應(yīng)的像素值為白,模板上該位置賦為0,否則賦為1。
4.循環(huán)所有的前景像素點(diǎn),對(duì)符合如下條件的像素點(diǎn)標(biāo)記為刪除:
5.循環(huán)所有的前景像素點(diǎn),對(duì)符合如下條件的像素點(diǎn)標(biāo)記為刪除:
6.如果沒有滿足的點(diǎn),則結(jié)束細(xì)化過程。
下面:
Image_Use為目標(biāo)圖像:高120,長180,處理時(shí)不考慮邊界(四邊)
//背景為黑色,值為0,要細(xì)化的前景物體像素值為1。 int temp[3][3]; int count = 0,flinsh_flag = 0; while(1){ flinsh_flag = 0; for(int i = 1;i<120-1;i++) { for(int j = 1;j<180-1;j++) { if(Image_Use[i][j] == 255) continue; //第一步初始化模板 memset(temp, 0, sizeof(temp)); count = 0; //第二步根據(jù)模板所對(duì)應(yīng)的像素點(diǎn),對(duì)模板進(jìn)行賦值 //如果S模板某一個(gè)位置上所對(duì)應(yīng)的像素值為白,模板上該位置賦為0,否則賦為1 if(Image_Use[i][j-1] == 0) temp[1][0] = 1; if(Image_Use[i][j+1] == 0) temp[1][2] = 1; if(Image_Use[i-1][j-1] == 0) temp[0][0] = 1; if(Image_Use[i-1][j+1] == 0) temp[0][2] = 1; if(Image_Use[i-1][j] == 0) temp[0][1] = 1; if(Image_Use[i+1][j-1] == 0) temp[2][0] = 1; if(Image_Use[i+1][j+1] == 0) temp[2][2] = 1; if(Image_Use[i+1][j] == 0) temp[2][1] = 1; // for(int x = 0;x<3;x++) for(int y = 0;y<3;y++) { if(x == 1 && y == 1) continue; if(temp[x][y] == 1) count ++; } if(count>=2&&count<=6) { int ap = 0; if (temp[0][1] == 0 && temp[0][2] == 1) ++ap; if (temp[0][2] == 0 && temp[1][2] == 1) ++ap; if (temp[1][2] == 0 && temp[2][2] == 1) ++ap; if (temp[2][2] == 0 && temp[2][1] == 1) ++ap; if (temp[2][1] == 0 && temp[2][0] == 1) ++ap; if (temp[2][0] == 0 && temp[1][0] == 1) ++ap; if (temp[1][0] == 0 && temp[0][0] == 1) ++ap; if (temp[0][0] == 0 && temp[0][1] == 1) ++ap; if(ap == 1&&((temp[0][1]*temp[1][2]*temp[2][1])== 0)&&((temp[1][2]*temp[2][1]*temp[1][0])== 0)) { Image_Use[i][j] = 255; flinsh_flag ++; } } } } if(flinsh_flag == 0) { break; } flinsh_flag = 0; for(int i = 1;i<120-1;i++) { for(int j = 1;j<180-1;j++) { if(Image_Use[i][j] == 255) continue; //第一步初始化模板 memset(temp, 0, sizeof(temp)); count = 0; //第二步根據(jù)模板所對(duì)應(yīng)的像素點(diǎn),對(duì)模板進(jìn)行賦值 //如果S模板某一個(gè)位置上所對(duì)應(yīng)的像素值為白,模板上該位置賦為0,否則賦為1 if(Image_Use[i][j-1] == 0) temp[1][0] = 1; if(Image_Use[i][j+1] == 0) temp[1][2] = 1; if(Image_Use[i-1][j-1] == 0) temp[0][0] = 1; if(Image_Use[i-1][j+1] == 0) temp[0][2] = 1; if(Image_Use[i-1][j] == 0) temp[0][1] = 1; if(Image_Use[i+1][j-1] == 0) temp[2][0] = 1; if(Image_Use[i+1][j+1] == 0) temp[2][2] = 1; if(Image_Use[i+1][j] == 0) temp[2][1] = 1; // for(int x = 0;x<3;x++) for(int y = 0;y<3;y++) { if(x == 1 && y == 1) continue; if(temp[x][y] == 1) count ++; } if(count>=2&&count<=6) { int ap = 0; if (temp[0][1] == 0 && temp[0][2] == 1) ++ap; if (temp[0][2] == 0 && temp[1][2] == 1) ++ap; if (temp[1][2] == 0 && temp[2][2] == 1) ++ap; if (temp[2][2] == 0 && temp[2][1] == 1) ++ap; if (temp[2][1] == 0 && temp[2][0] == 1) ++ap; if (temp[2][0] == 0 && temp[1][0] == 1) ++ap; if (temp[1][0] == 0 && temp[0][0] == 1) ++ap; if (temp[0][0] == 0 && temp[0][1] == 1) ++ap; if(ap == 1&&((temp[0][1]*temp[1][2]*temp[1][0])== 0)&&((temp[0][1]*temp[2][1]*temp[1][0]) == 0)) { Image_Use[i][j] = 255; flinsh_flag++; } } } } if(flinsh_flag == 0) { break; } }
粗化處理可以對(duì)圖像的二值化補(bǔ)集進(jìn)行細(xì)化后得到。