2014-09-03 89 views
0

我有這個問題,請參閱。OpenCV卡爾曼濾波器,從std ::向量擦除

我正在使用OpenCV跟蹤視頻中的一隻手。手中有一個CascadeDetector,然後使用CamSHIFT進行跟蹤。如果CamShift算法在某些幀出現故障,我還使用卡爾曼濾波器來校正手的位置。

問題出現了,當我試圖從std :: vector中刪除一個元素時,我正在存儲我的手。擦除的原因是由於某些問題,臉部被誤解爲手,所以我正在檢測臉部,並且如果手部區域與臉部區域相交,我會刪除該手部。我知道,非常天真,但我目前剛剛起步。 的代碼看起來是這樣的:

class Hand { 
... 
public: 
    struct 
    { 
     ... 
     struct { 
      cv::Mat_<float> measurement; 
      cv::KalmanFilter KF; 
      cv::Mat state; 
      cv::Mat processNoise; 
     } KalmanTracker; 
    } Tracker; 
}; 
... 
std::vector<Hand> hands; 
... 
std::vector<cv::Rect> faces; 
faceCascade.detectMultiScale(frame, faces, 1.1, 2, CV_HAAR_FIND_BIGGEST_OBJECT); 
// iterate through hands 
for (std::vector<Hand>::iterator it = hands.begin(); it != hands.end(); ++it) { 
    // iterate through faces: 
    for (std::vector<cv::Rect>::iterator fc = faces.begin(); fc != faces.end(); ++fc) { 
     cv::Rect intersection = (*it).handBox.boundingRect() & (*fc); 
     // check if they have at leasy 75% intersection 
     if (intersection.area() >= ((*it).handBox.boundingRect().area() * 0.75)) { 
      // delete that hand from list 
      hands.erase(it); // this gets me a a EXC_BAD_ACCESS 
     } 
    } 
} 

hands.erase(it)線讓我一個EXC_BAD_ACCESS,而在我的KalmanFilterTracker結構指點,以及此行mat.hppEXC_i386_GPFLT

inline void Mat::release() 
{ 
    if(refcount && CV_XADD(refcount, -1) == 1) // EXC_BAD_ACCESS, code=EXC_i386_GPFLT 
    ... 
} 

無論hands也不faces是空的。 如果我從我的項目中完全刪除卡爾曼濾波器,並且提及或使用它,錯誤消失。

+0

從矢量中擦除後,您無法重新使用舊的迭代器。 – berak 2014-09-03 11:28:48

回答

1

vector :: erase(iterator)使正在被擦除的迭代器無效。但它確實將新的迭代器返回到向量中的下一個有效項目。因此,該行應該是:berak的評論後

it = hands.erase(it); 

編輯:

啊,我錯過了內循環。由於你在內循環中使it無效,事情會變得有點複雜。你需要跳過一些環節才能把握好。

for (std::vector<Hand>::iterator it = hands.begin(); it != hands.end();) { 
    bool found = false; 
    // iterate through faces: 
    for (std::vector<cv::Rect>::iterator fc = faces.begin(); fc != faces.end() && !found; ++fc) { 
     cv::Rect intersection = (*it).handBox.boundingRect() & (*fc); 
     // check if they have at leasy 75% intersection 
     if (intersection.area() >= ((*it).handBox.boundingRect().area() * 0.75)) { 
      found = true; 
     } 
    } 

    if (found) { 
     it = hands.erase(it); 
    } 
    else { 
     ++it; 
    } 
} 

這是可能的折一些操作迭代器進入內環,但保持它的外部使得代碼更清楚一點,更容易推理。

+0

更改了該行,但錯誤仍然存​​在。我懷疑這個錯誤不是與迭代器本身有關,而是與卡爾曼濾波器實例有關。 – Xonxt 2014-09-03 11:35:48

+0

@Gnagn,不幸的是它不那麼簡單。因爲它在內部循環中,它需要另一個它!= hands.end();之後檢查(如果該向量的最後一項已被刪除,那麼== == end()now) – berak 2014-09-03 11:58:57

+0

但是這種方法在if(found)語句中是一個有效的迭代器,然後在下一次循環之前再次增加它。你錯過了這樣做,或者我錯了? – Jepessen 2014-09-03 12:52:32

0

好吧,通過一些調試,我發現,我的手矢量在某個點變空了,並且在嘗試從空矢量中擦除時出現錯誤。 唯一剩下的就是找出爲什麼它變成空的,在哪一點。 謝謝大家。