2016-05-06 93 views
0

我有一個檢測多尺度返回矩形輸入矩陣的界限以外的問題。OpenCV CascadeClassifier detectMultiScale生成Rect外部輸入墊界限

所以我正在做的是一種優化技術,其中視頻源的第一幀被全部傳遞給detectMultiScale。

如果檢測到一個對象,我創建一個臨時Mat,它從當前的完整幀中克隆前一幀檢測到的對象的矩形。

然後我通過這個溫度墊來detectMultiScale,所以只有前一幀檢測到一個對象的矩形周圍的區域。

我遇到的問題是,當傳遞temp Mat時detectMultiScale的結果會給出超出輸入temp temp邊界的矩形。

大部分我只想知道這裏發生了什麼。我對發生了什麼有兩個想法,但我無法弄清楚。

  1. 無論是從全幀到temp墊克隆一個矩形時,克隆操作墊目標設定在全幀的行和列的克隆區域內的某個地方。因此,例如,我有一個100x100的全幀,我試圖從位置80x80處克隆一個10x10矩形。產生的墊子的尺寸是10x10,但也可能在墊子的某個地方,墊子是從80x80開始的?

  2. CascadeClassifier是否保持狀態在我之前傳遞給它的全幀的某個位置?

我不知道這裏發生了什麼,但希望有人能說出點亮。

這裏是我想要做的,用的註釋說明了結果我看到一些代碼,例如:

std::vector<cv::Rect> DetectObjects(cv::Mat fullFrame, bool useFullFrame, cv::Rect detectionRect) 
{ 
    // fullFrame is 100x100 
    // detectionRect is 10x10 at position 80x80 eg. cv::Rect(80,80,10,10) 
    // useFullFrame is False 

    std::vector<cv::Rect> results; 
    if(useFullFrame) 
    { 
     object_cascade.detectMultiScale(fullFrame, 
       results, 
       m_ScaleFactor, 
       m_Neighbors, 
       0 | cv::CASCADE_SCALE_IMAGE | cv::CASCADE_DO_ROUGH_SEARCH | cv::CASCADE_DO_CANNY_PRUNING, 
       m_MinSize, 
       m_MaxSize); 
    } 
    else 
    { 
     // useFullFrame is false, so we run this block 

     cv::Mat tmpMat = fullFrame(detectionRect).clone(); 
     // tmpMat is size 10,10 

     object_cascade.detectMultiScale(tmpMat, 
       results, 
       m_ScaleFactor, 
       m_Neighbors, 
       0 | cv::CASCADE_SCALE_IMAGE | cv::CASCADE_DO_ROUGH_SEARCH | cv::CASCADE_DO_CANNY_PRUNING, 
       m_MinSize, 
       m_MaxSize); 
    } 

    if(results.size() > 0) 
    { 
     // this is the weird part. When looking at the first element of 
     // results, (result[0]), it is at position 80,80, size 10,10 
     // so it is cv::Rect(80,80,10,10) 
     // even though the second detectMultiScale was ran with a Mat of 10x10 

     // do stuff 
    } 
} 

這是接近相當不錯的我有什麼在代碼中,除了我在評論中提到的實際示例值,我使用的是容易的值,而不是像1920x1080那樣的全幀值和實際結果,例如像367x711。

那麼,爲什麼我從detectMultiScale獲得的結果超出了輸入Mat的範圍?

編輯:

我原本寫了這個程序的嵌入式Linux發行版,在這裏就不會出現這個問題(我總是得到預期的結果)。這個問題發生在Windows版本和opencv的構建上,所以我目前正在通過opencv代碼來查看是否有與此相關的突出內容。

回答

0

我相信這是一個簡單的邏輯錯誤。這:

if(fullFrame) 

應該是這樣的:

if(useFullFrame) 
+0

對不起,那是在上面的代碼中的錯字。我沒有複製和粘貼,只需手工輸入即可。if語句的第二個塊實際上正在運行。感謝你的建議,有時候你需要第二雙眼睛,但在這種情況下,我已經排除了這種可能性,通過調試並按照代碼執行行 – iedoc

+0

在那種情況下,我猜測關鍵是在[Mat :: operator()]的細節中(http://docs.opencv.org/2.4/modules/core/doc/basic_structures.html#id6)。根據文檔,它只創建一個新的頭文件,而克隆操作只是創建整個矩陣,頭文件和全部文件的新的深層副本。因此,儘管像'detectMultiScale'這樣的函數可能會遵守定義的ROI,但它們仍可能返回絕對座標。 (根據你的問題,這聽起來就像它的行爲。)我會消除克隆操作,並通過偏移調整返回的結果。 – Aenimated1

+0

我現在正在研究這個問題,這聽起來像是發生了什麼事情。我會用我的發現報告。但奇怪的是,這不是在我的Linux版本的opencv中發生的,你會認爲代碼在邏輯上大致相同 – iedoc