全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:3236
推到 Plurk!
推到 Facebook!

請幫我看看我寫的K-means分群法錯誤在哪裡

尚未結案
chemichemi
一般會員


發表:5
回覆:5
積分:2
註冊:2005-03-19

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-08-21 09:34:28 IP:61.231.xxx.xxx 未訂閱
根據我的了解 K-means分群法的處理方法應該如下: 1.先從一群資料裡隨機選出K個資料點當作代表點。(這裡我固定分成3群,另外,資料點不在這些資料裡應該也是可以處理) 2.針對代表點以外的其他資料點,與代表點作距離計算。 (距離計算我是用每個pixel的rgb(rx,bx,gx)值跟三個代表點的rgb(r0y,r0b,g0y) (r1y,r1b,g1y) (r2y,r2b,g2y)值分別作計算,距離的算式為Distance0=[(rx-r0y)^2+(gx-g0y)^2+(bx-b0y)^2)]整個再開根號 Distance1=[(rx-r1y)^2+(gx-g1y)^2+(bx-b1y)^2)]整個再開根號 Distance2=[(rx-r2y)^2+(gx-g2y)^2+(bx-b2y)^2)]整個再開根號 3.將各個資料點分配給距離計算值最小的代表點,資料被分成K群。 4.把每群裡每個資料點分別加總之後除以該群資料點的總數,得到新的代表點。   這裡要把分在同一群的pixel的r,g,b值分別相加後,除以該群的pixel總數即可得到新的群中心 5.重複2、3、4步驟,直到所求代表點與前一次計算出來的代表點相同之後即停止計算,得到最後的代表點,並將資料分成K群。    各位幫我看看我的程式 問題應該是出在底下的紅字部分 因為分群要比較3個代表點哪一個跟要計算的點最靠近 但是我似乎沒有考慮到"等於"的狀況 也就是可能某個點計算的時候 會發生與第1群還有第2群的距離相等 這時候我的程式似乎就會發生錯誤 請有經驗的各位幫我看看吧 謝謝      do{        for(x=0;x<9;x ) oldgroup[x]=newgroup[x]; for(z=0;z<640*480*3;z=z 3) { distance[0]=(newgroup[0]-img[z])^2 (newgroup[1]-img[z 1])^2 (newgroup[2]-img[z 2])^2; distance[1]=(newgroup[3]-img[z])^2 (newgroup[4]-img[z 1])^2 (newgroup[5]-img[z 2])^2; distance[2]=(newgroup[6]-img[z])^2 (newgroup[7]-img[z 1])^2 (newgroup[8]-img[z 2])^2; if(distance[0]<=distance[1] && distance[0]<=distance[2]) { label[y]=0; Groupcount[0]=Groupcount[0] 1; Group0RGB[0]=Group0RGB[0] img[z]; Group0RGB[1]=Group0RGB[1] img[z 1]; Group0RGB[2]=Group0RGB[2] img[z 2]; } else if(distance[1]<=distance[0] && distance[1]<=distance[2]) { label[y]=1; Groupcount[1]=Groupcount[1] 1; Group1RGB[0]=Group1RGB[0] img[z]; Group1RGB[1]=Group1RGB[1] img[z 1]; Group1RGB[2]=Group1RGB[2] img[z 2]; } else if(distance[2]<=distance[0] && distance[2]<=distance[1]) { label[y]=2; Groupcount[2]=Groupcount[2] 1; Group2RGB[0]=Group2RGB[0] img[z]; Group2RGB[1]=Group2RGB[1] img[z 1]; Group2RGB[2]=Group2RGB[2] img[z 2]; } y ; } newgroup[0]=Group0RGB[0]/Groupcount[0]; newgroup[1]=Group0RGB[1]/Groupcount[0]; newgroup[2]=Group0RGB[2]/Groupcount[0]; newgroup[3]=Group1RGB[0]/Groupcount[1]; newgroup[4]=Group1RGB[1]/Groupcount[1]; newgroup[5]=Group1RGB[2]/Groupcount[1]; newgroup[6]=Group2RGB[0]/Groupcount[2]; newgroup[7]=Group2RGB[1]/Groupcount[2]; newgroup[8]=Group2RGB[2]/Groupcount[2]; } while(newgroup[i]!=oldgroup[i]);
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-10-02 20:20:18 IP:211.76.xxx.xxx 未訂閱
do
{
  // oldgroup = newgroup
  // 重新計算 newgroup
}
while(newgroup[i]!=oldgroup[i]); // 想判斷當 oldgroup == newgroup 時結束
有想有問題就在那個紅色的部分,在此行,i 只會是一個固定值,如果真的要作判斷應該
bool Found=false;
int i;
do
{
  // oldgroup = newgroup
  // 重新計算 newgroup
  // 想判斷當 oldgroup == newgroup 時結束
  for(i=0;i<9;i  )
    if(newgroup[i]!=oldgroup[i])break;
  if(i==9) Found=true;
}
while(!Found);
也許您的 i 固定是 0 或某值,所以只要 newgroup[0] == oldgroup[0] do loop 就結束了,當然找出來的代表點也是不對的。 至於"等於"的狀況,您原本的寫法是:
if(distance[0]<=distance[1] && distance[0]<=distance[2])
{
  // 分到第 1 群
}
else if(distance[1]<=distance[0] && distance[1]<=distance[2])
{
  // 分到第 2 群
}
else if(distance[2]<=distance[0] && distance[2]<=distance[1])
{
  // 分到第 3 群
}
如此,有可能的錯誤是以上三個判斷都不成立,該點就沒有貢獻了。 比較好的方式是:
if(distance[0]<=distance[1] && distance[0]<=distance[2])
{
  // 分到第 1 群
}
else if(distance[1]<=distance[0] && distance[1]<=distance[2])
{
  // 分到第 2 群
}
else // if(distance[2]<=distance[0] && distance[2]<=distance[1])
{ // 不是第 1,2 群的都視為第 3 群,這樣才不會有漏網之魚
  // 分到第 3 群
}
當然,我沒有很仔細去推敲,也許您原本的寫法也是不會有漏網之魚的 再試試吧。 最後,再提醒您,在貼原始碼時,請使用: <>[<>><>] // >[<>/><>] 的方式,以保留原本的縮排,程式碼才容易讀,別人也才容易幫您找問題, 不然,看到亂七八糟的程式碼,給人的感覺就是,沒有用心,很隨便的樣子。 > < href="http://free.greenworld.com.tw/~dllee/" target="blank">吃軟也吃硬 dllee.ktop.com.tw dllee's sharespace Beckhoff Fieldbus VMASK
------
http://www.ViewMove.com
系統時間:2024-04-25 9:28:05
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!