細化算法C++
来源:互联网 发布:加盟淘宝店 编辑:程序博客网 时间:2024/05/01 00:57
- 收斂性;
- 保證細化後細線的連通性
- 保持原圖的基本形狀
- 減少筆畫相交處的畸變
- 細化結果是原圖像的中心線
- 細化的快速性和迭代次數少
依據是否使用迭代運算可以分為兩類:
- 非迭代算法
- 一次即產生骨架,如基於距離變換的方法。游程長度編碼細化等。
- 迭代算法
即重復刪除圖像邊緣滿足一定條件的像素,最終得到單像素寬帶骨架。
迭代方法依據其檢查像素的方法又可以再分成
- 串行算法
是否刪除像素在每次迭代的執行中是固定順序的,它不僅取決於前次迭代的結果,也取決於本次迭代中已處理過像素點分布情況.
- 並行算法
像素點刪除與否與像素值圖像中的順序無關,僅取決於前次迭代的結果
細化算法:
- Burning
Algorithm
使用迭代的方法去除圖像的邊界,
- Zhang並行快速細化算法
模板:
p3 p2 p9
p4
p5 p6 p7
1.
2.
3.
4.
其中,Z0(p1)是以p2,p3,...p8,p9為序時,這些點的值從0->1變化的次數
被判定為刪除的點暫不刪除,但要加以記錄。
等所有邊界點都被判斷完後,再一起將所有標記了的點刪除,接下來進入第二階段的刪除步驟。
1.
2.
3.
4.
同第一步一樣,判定要刪除的點只是加以記錄而暫不刪除,等待最後同時刪除
對一副圖像反復執行第一步與第二步的算法步驟,知道都沒有可刪除的點為止
我的zhang細化代碼如下:
// p3 p2 p1//**********使用zhang並行快速算法進行細化 p4 p p0// p5 p6 p7void ZhangThinning(int w,int h,BYTE *imgBuf){ int neighbor[8]; BYTE *mark=new BYTE[w*h]; memset(mark,0,w*h); BOOL loop=TRUE; int x,y,k; int markNum=0; while(loop) { loop=FALSE; //第一步 markNum=0; for(y=1;y<<span style="line-height: 28px; color: rgb(1, 0, 1);">h-1;y++) { for(x=1;x<<span style="line-height: 28px; color: rgb(1, 0, 1);">w-1;x++) { //條件1:p必須是前景點 if(imgBuf[y*w+x]==0 ) continue; neighbor[0]= imgBuf[y*w+x+1] ; neighbor[1]= imgBuf[(y-1)*w+x+1]; neighbor[2]= imgBuf[(y-1)*w+x]; neighbor[3]= imgBuf[(y-1)*w+x-1]; neighbor[4]= imgBuf[y*w+x-1]; neighbor[5]= imgBuf[(y+1)*w+x-1]; neighbor[6]= imgBuf[(y+1)*w+x]; neighbor[7]= imgBuf[(y+1)*w+x+1]; //條件2:2<=N(p)<=6 int np=(neighbor[0]+neighbor[1]+neighbor[2]+neighbor[3]+neighbor[4]+neighbor[5]+neighbor[6]+neighbor[7])/255; if(np<2 || np>6) continue; //條件3:S(p)=1 int sp=0; for(int i=1;i<8;i++) { if(neighbor[i]-neighbor[i-1]==255) sp++; } if(neighbor[0]-neighbor[7]==255) sp++; if(sp!=1) continue; //條件4:p2*p0*p6=0 if(neighbor[2]&neighbor[0]&neighbor[6]!=0) continue; //條件5:p0*p6*p4=0 if(neighbor[0]&neighbor[6]&neighbor[4]!=0) continue; //標記刪除 mark[w*y+x]=1; markNum++; loop=TRUE; } } //將標記刪除的點置為背景色 if(markNum>0) { for(y=0;y<<span style="line-height: 28px; color: rgb(1, 0, 1);">h;y++) { for(x=0;x<<span style="line-height: 28px; color: rgb(1, 0, 1);">w;x++) { k=y*w+x; if(mark[k]==1) { imgBuf[k]=0; } } } } //第二步 markNum=0; for(y=1;y<<span style="line-height: 28px; color: rgb(1, 0, 1);">h-1;y++) { for(x=1;x<<span style="line-height: 28px; color: rgb(1, 0, 1);">w-1;x++) { //條件1:p必須是前景點 if(imgBuf[y*w+x]==0 ) continue; neighbor[0]= imgBuf[y*w+x+1] ; neighbor[1]= imgBuf[(y-1)*w+x+1]; neighbor[2]= imgBuf[(y-1)*w+x]; neighbor[3]= imgBuf[(y-1)*w+x-1]; neighbor[4]= imgBuf[y*w+x-1]; neighbor[5]= imgBuf[(y+1)*w+x-1]; neighbor[6]= imgBuf[(y+1)*w+x]; neighbor[7]= imgBuf[(y+1)*w+x+1]; //條件2:<=N(p)<=6 int np=(neighbor[0]+neighbor[1]+neighbor[2]+neighbor[3]+neighbor[4]+neighbor[5]+neighbor[6]+neighbor[7])/255; if(np<2 || np>6) continue; //條件3:S(p)=1 int sp=0; for(int i=1;i<8;i++) { if(neighbor[i]-neighbor[i-1]==255) sp++; } if(neighbor[0]-neighbor[7]==255) sp++; if(sp!=1) continue; //條件4:p2*p0*p4==0 if(neighbor[2]&neighbor[0]&neighbor[4]!=0) continue; //條件5:p2*p6*p4==0 if(neighbor[2]&neighbor[6]&neighbor[4]!=0) continue; //標記刪除 mark[w*y+x]=1; markNum++; loop=TRUE; } } //將標記刪除的點置為背景色 for(y=0;y<<span style="line-height: 28px; color: rgb(1, 0, 1);">h;y++) { for(x=0;x<<span style="line-height: 28px; color: rgb(1, 0, 1);">w;x++) { k=y*w+x; if(mark[k]==1) { imgBuf[k]=0; } } } } }
判斷一個點是否能去掉,
(1)內部點不能刪除;
(2)孤立點不能刪除;
(3)直線端點不能刪除;
(4)如果P是邊界點,去掉P後,如果連通分量不增加,則P可以刪除。
- Hilditch、Pavlidis、Rosenfeld細化算法
這類算法則是在程序中直接運算,根據運算結果來判定是否可以刪除點的算法,差別在於不同算法的判定條件不同。
Hilditch算法使用於二值圖像,比較普通,是一般的算法;
Pavlidis算法通過並行和串行混合處理來實現,用位運算進行特定模式的匹配,所得的骨架是8連接的,使用於0-1二值圖像;
Rosenfeld算法是一種並行細化算法,所得的骨架形態是8-連接的,使用於0-1二值圖像。
(後兩種算法的效果要更好一些,但是處理某些圖像時效果一般,第一種算法使用性強些。)
- 索引表細化算法
經過預處理後得到待細化的圖像是0、1二值圖像。像素值為1的是需要細化的部分,像素值為0的是背景區域。基於索引表的算法就是依據一定的判斷依據,所做出的一張表,然後根據魔鬼要細化的點的八個鄰域的情況查詢,若表中元素是1,若表中元素是1,則刪除該點(改為背景),若是0則保留。因為一個像素的8個鄰域共有256中可能情況,因此,索引表的大小一般為256。
1 8
2 16 128
4 32 256
也就是2的不同冪次,0,1,2,3。。。 8次冪
那麼,某種狀態數值就是加權值的和。
比如,
下面一種鄰域組合:
0 1 0
1 1 0
0 0 1
它的值=2+8+16+256=282
這樣的話,我們通過一個數值,就可以表達一種3乘3鄰域的一種空間分布狀態。
- C算法
- C算法
- 算法 C
- C 算法
- C++--算法
- [C++] [算法] KMP算法
- [C/C++]洗牌算法
- [C/C++] 常用算法
- c语言经典算法算法
- 算法:二分查找算法(c++)
- 【C++】【啊哈!算法】Dijkstra算法
- 算法大全(c,c++)
- 算法大全(C,C++)
- 懂c/c++/java/算法
- 排序算法实现(C/C++)
- C/C++“大数相加算法”
- 排序算法汇总(C/C++)
- [C/C++] 算法提高 质因数
- 程序不接客人推荐没从铝扣板儿的费用斗
- jquery中html()、text()、val()的区别
- 本年末ier妈那边的文件和从V领可贝尔阿Q
- Leetcode: Construct Binary Tree from Inorder and Postorder Traversal
- Zhang二值圖像細化算法
- 細化算法C++
- piwik subdomains and outlink
- Hilditch 細化算法
- R语言 - wiki
- Gabor濾波小結整理
- 远程控制软件编程第二天
- USACO All Latin Squares 解题报告
- 排序
- 排序算法之快速排序笔记