鏈碼 |
|
wayne_di
一般會員 發表:5 回覆:3 積分:1 註冊:2008-04-11 發送簡訊給我 |
[code cpp] 請在此區域輸入程式碼 int x,Chain_i,Chain_j,check; //記錄存儲位置 起始位置 上一點 現在位置 int exit,run; //離開迴圈的旗標 和 是否有直行過的旗標 int buf[90][46]; //記路標過的點位置 x=0;exit=0;run=0;check=0; //初始值設定 Memo3->Lines->Clear(); TXT5 = ""; //將buf裡面全部放一 當有記錄過的位置 則轉變成0 故只要buf[][]==0的地方就不要執行 for(int i=0;i<90;i ) for(int j=0;j<46;j ) buf[i][j]=255; /* i-1,j-1 | i-1,j | i-1,j 1 7 | 0 | 1 ----------------------- --------- i ,j-1 | i ,j | i ,j 1 6 | | 2 ----------------------- --------- i 1,j-1 | i 1,j | i 1,j 1 5 | 4 | 3 */ for(int i=1;i<89 && exit!=1;i ) //exit=1十 表示已執行完輪廓編碼 { for(int j=1;j<45 && exit!=1;j ) { if(Wayne.bgr[i][j]==0)//找到陣列的第一個黑點 { Chain_i=i; Chain_j=j; buf[Chain_i][Chain_j]=0; int position=0; //position=0 為由0 開 始 的 順 時 針 方 向 收 尋 //position=1 為由4開始的順時針方向收尋 //找到點 且確認八方有黑點 這樣才能繼續下去 while(~((Wayne.bgr[Chain_i-1][Chain_j-1]!=0) && (Wayne.bgr[Chain_i-1][Chain_j]!=0) && (Wayne.bgr[Chain_i-1][Chain_j 1]!=0) && (Wayne.bgr[Chain_i][Chain_j-1]!=0) && (Wayne.bgr[Chain_i][Chain_j 1]!=0) && (Wayne.bgr[Chain_i 1][Chain_j-1]!=0) && (Wayne.bgr[Chain_i 1][Chain_j]!=0) && (Wayne.bgr[Chain_i 1][Chain_j 1]!=0)) && check==0) //check=0 表示已經無下一點可編碼 { run=1; //編碼規則 1.找出下一點的方向 2.不能是上一點 3.確認是否繞一圈 if(position==0){ if(Wayne.bgr[Chain_i-1][Chain_j]==0 && buf[Chain_i-1][Chain_j]==255 ) //上 0 { Wayne.chaincode[x]=0; //記錄編碼 buf[Chain_i][Chain_j]=0; //標記以編碼的位置 x ; Chain_i=Chain_i-1; //以下一個方向當起點 Chain_j=Chain_j; position=0; //還是以0開始的順時針編碼 } else if(Wayne.bgr[Chain_i-1][Chain_j 1]==0 && buf[Chain_i-1][Chain_j 1]==255 ) //右上 1 { Wayne.chaincode[x]=1; buf[Chain_i][Chain_j]=0; x ; Chain_i=Chain_i-1; Chain_j=Chain_j 1; position=0; } else if(Wayne.bgr[Chain_i][Chain_j 1]==0 && buf[Chain_i][Chain_j 1]==255 ) //右 2 { Wayne.chaincode[x]=2; buf[Chain_i][Chain_j]=0; x ; Chain_i=Chain_i; Chain_j=Chain_j 1; position=0; } else if(Wayne.bgr[Chain_i 1][Chain_j 1]==0 && buf[Chain_i 1][Chain_j 1]==255 ) //右下 3 { Wayne.chaincode[x]=3; buf[Chain_i][Chain_j]=0; x ; Chain_i=Chain_i 1; Chain_j=Chain_j 1; position=0; } else if(Wayne.bgr[Chain_i 1][Chain_j]==0 && buf[Chain_i 1][Chain_j]==255 ) //下 4 { Wayne.chaincode[x]=4; buf[Chain_i][Chain_j]=0; x ; Chain_i=Chain_i 1; Chain_j=Chain_j; position=1; } else if(Wayne.bgr[Chain_i 1][Chain_j-1]==0 && buf[Chain_i 1][Chain_j-1]==255 ) //左下 5 { Wayne.chaincode[x]=5; buf[Chain_i][Chain_j]=0; x ; Chain_i=Chain_i 1; Chain_j=Chain_j-1; position=1; } else if(Wayne.bgr[Chain_i][Chain_j-1]==0 && buf[Chain_i][Chain_j-1]==255 ) //左 6 { Wayne.chaincode[x]=6; buf[Chain_i][Chain_j]=0; x ; Chain_i=Chain_i; Chain_j=Chain_j-1; position=1; } else if(Wayne.bgr[Chain_i-1][Chain_j-1]==0 && buf[Chain_i-1][Chain_j-1]==255 ) //右上 7 { Wayne.chaincode[x]=7; buf[Chain_i][Chain_j]=0; x ; Chain_i=Chain_i-1; Chain_j=Chain_j-1; position=1; } else check=1; } else{ if(Wayne.bgr[Chain_i 1][Chain_j]==0 && buf[Chain_i 1][Chain_j]==255 ) //下 4 { Wayne.chaincode[x]=4; buf[Chain_i][Chain_j]=0; x ; Chain_i=Chain_i 1; Chain_j=Chain_j; position=1; } else if(Wayne.bgr[Chain_i 1][Chain_j-1]==0 && buf[Chain_i 1][Chain_j-1]==255 ) //左下 5 { Wayne.chaincode[x]=5; buf[Chain_i][Chain_j]=0; x ; Chain_i=Chain_i 1; Chain_j=Chain_j-1; position=1; } else if(Wayne.bgr[Chain_i][Chain_j-1]==0 && buf[Chain_i][Chain_j-1]==255 ) //左 6 { Wayne.chaincode[x]=6; buf[Chain_i][Chain_j]=0; x ; Chain_i=Chain_i; Chain_j=Chain_j-1; position=1; } else if(Wayne.bgr[Chain_i-1][Chain_j-1]==0 && buf[Chain_i-1][Chain_j-1]==255 ) //右上 7 { Wayne.chaincode[x]=7; buf[Chain_i][Chain_j]=0; x ; Chain_i=Chain_i-1; Chain_j=Chain_j-1; position=1; } else if(Wayne.bgr[Chain_i-1][Chain_j]==0 && buf[Chain_i-1][Chain_j]==255 ) //上 0 { Wayne.chaincode[x]=0; buf[Chain_i][Chain_j]=0; x ; Chain_i=Chain_i-1; Chain_j=Chain_j; position=0; } else if(Wayne.bgr[Chain_i-1][Chain_j 1]==0 && buf[Chain_i-1][Chain_j 1]==255 ) //右上 1 { Wayne.chaincode[x]=1; buf[Chain_i][Chain_j]=0; x ; Chain_i=Chain_i-1; Chain_j=Chain_j 1; position=0; } else if(Wayne.bgr[Chain_i][Chain_j 1]==0 && buf[Chain_i][Chain_j 1]==255 ) //右 2 { Wayne.chaincode[x]=2; buf[Chain_i][Chain_j]=0; x ; Chain_i=Chain_i; Chain_j=Chain_j 1; position=0; } else if(Wayne.bgr[Chain_i 1][Chain_j 1]==0 && buf[Chain_i 1][Chain_j 1]==255 ) //右下 3 { Wayne.chaincode[x]=3; buf[Chain_i][Chain_j]=0; x ; Chain_i=Chain_i 1; Chain_j=Chain_j 1; position=0; } else check=1; } } if(run==1) exit=1; } } } [/code] 回覆這篇 http://delphi.ktop.com.tw/board.php?cid=168&fid=912&tid=93755 因為在那邊我不會貼檔案,所以在這回覆。 之前因為覺得寫得很差寫很冗長才沒放上來分享。 我這附上鏈碼執行檔以及1~9的數字圖片 執行步驟如下: 1. 開啟一張圖片檔 2. 選擇二值化門檻值(有拉BAR) 3. 圖片處理→擷取輪廓 4. 圖片處理→反白 5. 圖片處理→細化 6. 編碼(右下方) 7. 路徑結果在MEMO3顯示 以及右上方的IMAGE 以上只有鏈碼是自己撰寫,其他圖片處理皆參考該討論區修改而得。
------
/*Inch by inch, it's a cinch*\ |
careychen
尊榮會員 發表:41 回覆:580 積分:959 註冊:2004-03-03 發送簡訊給我 |
|
wayne_di
一般會員 發表:5 回覆:3 積分:1 註冊:2008-04-11 發送簡訊給我 |
其實對於鏈碼(chaincode)真正的用途我也不是很明瞭,是在某本書中看到
覺得它可以用來描述圖形或文字的邊緣形狀, 或許可以當作圖片的特徵向量才試著寫寫看用用看, 但之後對我的作業好像沒太大得幫助就是了。 圖片中有四相跟八相依照自己需求去定義要使用哪一種來作方向的編號, 再將輸入圖片的點群資料可以將多pixel變成一格來看(ex: 3x3 5x5 7x7)當成一個pixel, 可降低圖形複雜度,再依照選擇的定義方向去編號即可得到該圖形的鏈碼, 但是圖形有大有小會影響鏈碼的長度,所以可以再多考慮彎曲特徵進去, 就是將有變化的轉角處定義一新的號碼,而沒變化的轉角處不定義號碼, 這樣就不會受圖片忽大忽小影響特徵, 但是還是有而外的缺點,比如說圖形旋轉那特徵就會不一樣了。 講的不是很好,但我知道的大概是這樣, 其實這篇主要是回覆我之前問問題然後解決後將檔案分享用。
------
/*Inch by inch, it's a cinch*\ |
careychen
尊榮會員 發表:41 回覆:580 積分:959 註冊:2004-03-03 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |