2012-07-13 33 views
3

我目前正在實現一種用於識別彩色物體的最小慣性軸(由第二時刻提供)的算法。爲了做到這一點,我需要獲得第一時刻給出的質量中心。從小的二進制圖像中移除異常像素

加權平均函數效果很好,但由於像素點異常,我收到了不希望的結果。

這裏是平均功能:

(例如,x的加權平均)

for (i = 0, i < rows, i++) { 
    for (j = 0, j < cols, j++) { 
     if (colorAt(i,j).isForeground()) { 
      tempSumX++; 
      totalForeground++; 
     } 
    } 
    x_ += i*tempSumX; 
    tempSumX = 0; 
} 
x_ /= totalForeground; //where x_ represents the x coordinate of the weighted center of mass. 

Incorrect Center of Mass

給定一個圖像,如此,這是由只兩種顏色(背景和前景表示),我怎麼去除外圍像素?注意:外圍像素是指任何不屬於大顏色質量的部分。白點是計算出的重心,這是不正確的。

非常感謝。

+0

你看過形態濾波器嗎? – mathematician1975 2012-07-13 13:53:19

+0

我認爲他們,但我不知道他們將如何在我的情況下工作。只是不太瞭解。我也在研究圖論以確定關係。 – 2012-07-13 13:55:06

+0

它看起來不像一個平均值,還是你有任何異常值在圖像中不可見?在計算加權平均值時,你究竟是什麼權重? – TaZ 2012-07-13 17:45:02

回答

1

有很多洪水填充算法可以識別出所有連接像素的起點。

另外一種常見的方法來消除這些來自噪聲的小外星人是侵蝕圖像,然後擴大它恢復到相同的大小 - 雖然如果你純粹做CoG,你不一定需要擴張步驟

+0

我在mathematician1975的推薦書上看過形態濾波器,但是我對結構元素的使用感到困惑。一般原則是有道理的,但我對SE的東西不太確定。如果我使用洪水填充,我是否會簡單地多次使用它來確定哪種形狀最大?也就是說,我怎麼知道從哪裏開始搜索? – 2012-07-13 14:18:46

+0

FloodFill似乎是一個很好的方法給我。即使您使用連接組件標籤,您也必須決定使用哪個blob。這裏有一個OpenCV示例:http://areshopencv.blogspot.com/2011/12/blob-detection-connected-component-pure.html。然後你可以得到OpenCV來爲你計算時刻:http://opencv.willowgarage.com/documentation/cpp/structural_analysis_and_shape_descriptors.html – beaker 2012-07-16 18:37:48

+0

感謝您的幫助!然而,我最終使用了連接組件標籤算法,因爲它更適合我所需要的。感謝OpenCV API鏈接,燒杯...儘管我已經事先爲自己寫過所有代碼。哎呦。 – 2012-07-17 16:15:16

0

如何,在僞碼:

for(y = 0; y < rows; y++) 
{  
    for (x = 0; x < cols; x++) 
    { 
     if (pixel(x, y).isColor()) 
     { 
      int sum = 0; 
      // forgetting about edge cases for clarity... 
      if (!pixel(x-1, y-1).isColor()) sum++; 
      if (!pixel(x, y-1).isColor()) sum++; 
      if (!pixel(x+1, y-1).isColor()) sum++; 
      if (!pixel(x-1, y ).isColor()) sum++; 
      if (!pixel(x+1, y ).isColor()) sum++; 
      if (!pixel(x-1, y+1).isColor()) sum++; 
      if (!pixel(x, y+1).isColor()) sum++; 
      if (!pixel(x+1, y+1).isColor()) sum++; 
      if (sum >= 7) 
      { 
      pixel(x, y).setBackground(); 
      x -= 1; 
      y -= 1; 
      } 
     } 
    } 
} 

即去除由7個背景像素包圍的任何像素。如果您將像素的顏色更改爲現在可能受影響的最早像素。

您的「異常值」度量值可能會發生變化 - 例如,您可以將對角線像素計數爲1/2。例如。直接在上面,下面,左側和右側的像素計數爲2.然後使用不同的數字作爲總和。

您可以通過增加過濾器的大小來提高準確性 - 比如5x5而不是3x3。在那種情況下,像素2的計數應該更小。

0

我相信你的算法不正確。 M10(對不起,我無法弄清楚如何做標)的二進制圖像是前景像素的x座標的總和,所以你的代碼應該是這樣的:

for (i = 0, i < rows, i++) { 
    for (j = 0, j < cols, j++) { 
     if (colorAt(i,j).isForeground()) { 
      tempSumX += i; 
      totalForeground++; 
     } 
    } 
} 
x_ = tempSumX/totalForeground; //where x_ represents the x coordinate of the weighted center of mass. 

假設這是與以前的信息Algorithm for Finding Longest Stretch of a Value at any Angle in a 2D Matrix,您應該計算的第一和第二階矩在同一個循環:

m01 += j; 
m20 += i*i; 
m02 += j*j; 
m11 += i*j; 

(tempSumX在你的算法僅僅是M10和totalForeground是M00)

試試這個如果你仍然有痛苦你可以使用連接組件標籤http://en.wikipedia.org/wiki/Connected_component_labeling找到最大的質量。 (可在matlab中使用bwlabelbwconncomp。)

+0

這就是我正在做的事,除非你通過去除乘法方面來簡化它。循環中的tempSumX ++與外部的tempSumX * i與循環中的tempSumX + i完全相同。圖像的問題是我交換了圖像中Point的x和y座標。加權算法正常工作。我問過這個問題後,我確實嘗試了一種連接組件標籤算法,但是我在使用C++找到一個很好的聯合搜索實現時遇到了問題。任何建議? – 2012-07-13 22:11:27

+0

所以你是。我想我最大的x維是**行**和最大的y維是** cols **混淆。對不起,我碰巧沒有找到一個很好的聯盟發現實現,我可以指出你。 – beaker 2012-07-13 22:26:24

+0

你確定你的'colorAt(i,j)'函數將'y'(行)作爲第一個參數並將'x'(列)作爲第二個?也許錯誤在那裏。因爲您在交換座標時報告正確的結果。爲了清晰起見,我建議使用'y'和'x'來代替'i'和'j'。編輯:呃,現在我也感到困惑。重命名變量的建議仍然存在。 – TaZ 2012-07-14 00:32:52