2012-09-10 22 views
0

我正在閱讀thisthis有關手部/頭部跟蹤的論文。他們都談論檢測運動計算在每個像素的鄰域的差,並將結果與​​一個閾值進行比較:OpenCV中像素鄰域差異的高效算法

從第一紙引用:

我們使用在文獻中描述的時間差異的方法。 [41]計算每個像素周圍的鄰域差異的絕對值,然後通過求和所有相鄰像素的差異來導出累積差異。當累計差值高於預定閾值時,將像素分配給運動區域。

有沒有一種有效的方法來做到這一點(可能在OpenCV中)?
我寫的代碼是相當幼稚,除了丟失的實時性,似乎不給比簡單的像素到像素差效果會更好:

template<class T> class Image { 
private: 
    IplImage* imgp; 
public: 
    Image(IplImage* img=0) {imgp=img;} 
    ~Image(){imgp=0;} 
    void operator=(IplImage* img) {imgp=img;} 
    inline T* operator[](const int rowIndx) { 
     return ((T *)(imgp->imageData + rowIndx*imgp->widthStep));} 
}; 

typedef Image<unsigned char> BwImage; 
typedef Image<float>   BwImageFloat; 


void computeMovingRegion(IplImage* prev, IplImage* cur, IplImage *mov) { 

    BwImage _prev(prev); 
    BwImage _cur(cur); 
    BwImage _mov(mov); 

    for (int i = 3; i<prev->height-3; i++) { 
     for (int j=3; j<prev->width-3; j++) { 

      int res=0; 

      for (int k=i-3; k<i+3; k++) 
       for (int n=j-3; n<j+3; n++) 
        res += abs(_cur[k][n] -_prev[k][n]); 

      if (res>2000) { 
       _mov[i][j]=_cur[i][j]; 
      } 
      else 
       _mov[i][j]=0; 

     } 
    } 
} 

圖像在灰度。不要認爲它很重要,但我使用的是MacOS 10.8和Xcode 4.4.2。

回答

1

如果您首先計算絕對差值圖像(即abs(_cur[] - prev[])),然後對此進行迭代,則應該能夠消除大量冗餘。除此之外,還有很多優化可以做,但這對於相對較少的努力來說是一個好的開始。

還要注意,你的循環索引查找錯誤的 - 如果你想要做一個7x7的鄰里操作應該是:

for (int k=i-3; k<=i+3; k++) 
    for (int n=j-3; n<=j+3; n++) 
     ... 
+0

謝謝您的回答。你是對的我的代碼非常冗餘,我改變了它的計算方式,首先是一個「差異」的形象,而不是按照你的建議迭代它。但結果似乎有點不穩定,我還能做什麼? – Saphrosit

+0

下一個優化是在迭代每行時爲7列7像素絕對差分值保留單獨的總和。對於每個新像素,您只需計算一個新列的總和,丟棄最早的列,然後求和7列,這樣每個像素可以執行6 + 6 = 12次操作,而不是每像素7 * 7-1 = 48次操作。這應該會給您帶來另外4倍的吞吐量提升。 –