2014-01-09 69 views
4

我有這個問題,我不能包裹我的頭。我試圖在視頻中檢測並跟蹤某些內容。因此我使用的功能如GaussianBlur(), threshold(), findContours(),OpenCV;排序向量<Rect>並刪除某些條目

findContours()給我一個輪廓矢量,後來被轉換成了邊界矩形。到現在爲止還挺好。

現在我需要從邊界矩形的向量中得到它們,它們按大小(area)排序,並且只包含沒有被另一個矩形包圍的矩形。

我試圖畫出一些小圖以便更好的理解,click here for image

所以我要尋找的是#8是第一項,其次是#1, #3,.... 參賽作品像#2,#4, #9, #10 and #11應予刪除。

據我所知,載體對於排序和刪除並不理想。於是,我就矢量複製到一個列表,像這樣:

std::list<Rect> sorted_list(boundRect_temp.begin(), boundRect_temp.end()); 

但我現在無法訪問像區域中的成員變量。問題是算法不應該太耗時,這就是爲什麼我正在尋找一個好的解決方案。也許有一個功能呢?

+1

排序我建議丟棄'list'除非你有經驗證明,它比'VECTOR'代碼快。 – juanchopanza

+0

爲了擴大juanchopanza的評論,如果您使用臨時列表,您必須記住複製數據需要兩次(一次從向量到列表,然後一次回到向量)。 –

+0

嗨,你的圖片不能正常工作 –

回答

5

1)如果您使用findContours()和CV_RETR_EXTERNAL標誌,大多數交叉點都可以被過濾。這意味着包含在其他輪廓內的輪廓不會被返回。當然,這並不會阻止邊界框交叉的所有情況,但這會顯着提高後期處理的性能。2)矢量絕對適合分類。代碼將簡短而高效。由於數據將在內存中連續存在,因此它總比列表好。

3)從向量中逐個刪除值實際上並不有效,但您不需要那樣做。只要創建將包含選擇框,這樣臨時的向量:

vector <Rect> nonIntersect; 
for(unsigned int i=0; i < sortedBoxes.size(); i++) { 
    bool toAdd = true; 
    Point center = (sortedBoxes[i].tl()+sortedBoxes[i].br())*0.5; 
    for(unsigned int j=0; j < nonIntersect.size(); j++) 
     if (nonIntersect[j].contains(center)) { 
      toAdd = false; 
      break; 
     } 
    if (toAdd) 
     nonIntersect.push back(sortedBoxes[i]); 
} 

這是可以做到「就地」很好,但何必呢。與原始圖像的內存或findContours發現的輪廓內存相比,該內存可以忽略不計。

3

除了邁克爾·burdinov說,這裏的面積

struct byArea { 
    bool operator() (const Rect & a,const Rect & b) { 
     return a.width*a.height < b.width*b.height ; 
    } 
}; 

vector<Rect> rects; 
std::sort(rects.begin(), rects.end(), byArea());