2012-03-21 75 views
0

我在使用OpenCV中的SIFT描述符實現時有點困惑。使用SIFT描述符的OpenCV(C++)增加了檢測到的功能數量?

我想測試各種特徵檢測器+描述符的計算方法,所以我用的cv::FeatureDetectorcv::DescriptorExtractor接口,這讓我簡單地不同的檢測方法和描述符之間改變的組合。

當調用cv::DescriptorExtractor::compute(...)(變體的單個圖像),該文件說,有可能給該算法下降如果無法計算其描述關鍵點的數量,我瞭解爲什麼這樣做。

但是,發生在我身上的是描述符計算後的關鍵點實際數量增加了。顯然是這樣的,我並沒有試圖阻止它的發生,我只是希望能夠解釋爲什麼(只是一種直觀的描述會很酷,儘管我更讚賞那些)。

我在實際的OpenCV上沒有任何代碼(只是設置了一些本地的非OpenCV標誌)的包裝層上有層,所以這裏是OpenCV代碼在底部被調用:

cv::Ptr<cv::FeatureDetector> dect = cv::FeatureDetector::create("MSER"); 
cv::Mat input = cv::imread("someImg.ppm", 0); 
std::vector<cv::KeyPoint> keypoints; 
dect->detect(input, keypoints); 

cv::Ptr<cv::DescriptorExtractor>deEx=cv::DescriptorCalculator::create("SIFT"); 

std::cout << "before computing, feats size " << keypoints.size() << std::endl; 
// code to print out 10 features 

cv::Mat desc; 
deEx->compute(input, keypoints, desc); 

std::cout << "after computing, feats size " << keypoints.size() << std::endl; 
// code to print out 10 features 

我之前打印出來的前10個關鍵點和描述符的計算後,所以這裏有一些具體的數字爲例:

before computing, feats size 379 
feat[0]: 10.7584 39.9262 176.526 0 12.5396 
feat[1]: 48.2209 207.904 275.091 0 11.1319 
feat[2]: 160.894 313.781 170.278 0 9.63786 
feat[3]: 166.061 239.115 158.33 0 19.5027 
feat[4]: 150.043 233.088 171.887 0 11.9569 
feat[5]: 262.323 322.173 188.103 0 8.65429 
feat[6]: 189.501 183.462 177.396 0 12.3069 
feat[7]: 218.135 253.027 171.763 0 123.069 
feat[8]: 234.508 353.236 173.281 0 11.8375 
feat[9]: 234.404 394.079 176.23 0 8.99652 
after computing, feats size 463 
feat[0]: 10.7584 39.9262 13.1313 0 12.5396 
feat[1]: 48.2209 207.904 69.0472 0 11.1319 
feat[2]: 48.2209 207.904 107.438 0 11.1319 
feat[3]: 160.894 313.781 9.57937 0 9.63786 
feat[4]: 166.061 239.115 166.144 0 19.5027 
feat[5]: 150.043 233.088 78.8696 0 11.9569 
feat[6]: 262.323 322.173 167.259 0 8.65429 
feat[7]: 189.501 183.462 -1.49394 0 12.3069 
feat[8]: 218.135 253.027 -117.067 3 123.069 
feat[9]: 218.135 253.027 7.44055 3 123.069 

我從這個例子可以看出,原始的​​和feat[7]已經跨越了每兩個新的關鍵點,但我看不出有任何合乎邏輯的解釋爲compute方法,這樣做:(

我這裏給出的是使用MSER檢測關鍵點的打印輸出,然後嘗試計算SIFT描述,但同樣增加大小也與STARSURFSIFT發生(即DoG)關鍵點檢測。我沒有嘗試將描述符更改爲其他內容,但如果有人認爲它與問題相關,我會嘗試並在我的問題中對其進行編輯。

+0

你可以添加你使用的部分代碼嗎?瞭解參數將很有用。 – Alex 2012-03-21 11:32:29

+0

呃......我實際上是在圍繞OpenCV代碼的封裝進行封裝,但是我會嘗試挖掘實際的5行代碼,它們將完成所有工作並編輯它。 – penelope 2012-03-21 14:45:34

回答

2

看起來像是由於OpenCV使用Rob Hess的SIFT實現,它有時會以多於一個主導方向複製關鍵點。

環顧OpenCV報告的錯誤做了詭計,問題報告爲here

這不是一個錯誤,行爲沒有在新版本中得到糾正,而是隻是記錄在案。由於我有義務使用我現在正在使用的OpenCV版本(v2.1),因此在我看來newer documentation還沒有發生其他行爲,因爲old one中描述的行爲對我而言意義重大。

5

首先,您可以在documentationcv::DescriptorExtractor::compute中看到std::vector<cv::Keypoints>參數,其中non const。這意味着這個矢量可以通過cv::DescriptorExtractor::compute進行修改。 實際上,KeyPointsFilter::runByImageBorderKeyPointsFilter::runByKeypointSize(兩個non-const函數)將應用於該向量,並將刪除無法計算描述符的關鍵點。不會重新提取關鍵點。 您應該張貼您用於進一步診斷的幾行代碼。

-

好了,我終於找到發生問題:cv::SiftDescriptorExtractor::compute方法調用SIFT::operator()這(重新)計算的功能定位,並與幾個主要的方向重複的點。 解決方案可能會將descriptorParams.recalculateAngles更改爲false。

+0

我知道爲什麼':: compute'函數允許改變'std :: vector '和'non const'的含義。他們在文檔中給出的原因是(和我引用)「關鍵點,描述符無法計算的關鍵點被刪除。」移除是可以的。但是當我的關鍵點完成這個過程時,其中有*更多*,而不是*更少*,這是我無法理解的。我發佈了一些真實代碼,以更好地理解打印輸出的內容。 – penelope 2012-03-21 15:00:31

+0

我想清楚瞭解它是否完全瞭解您的問題。沒有代碼,很難診斷。我嘗試了你編輯的代碼,並且改變了其他類型的DesciptorExtractor。看來只有Sift描述符纔會出現問題。 – Eric 2012-03-21 16:33:31

+0

是的,我已經給出了自己的答案,鏈接到新舊文檔以及報告問題的頁面。我之所以沒有發佈代碼,是因爲我更感興趣的是爲什麼發生這種情況(以何種方式提取SIFT描述符增加了關鍵點的數量)比在代碼中發生的確切點更爲重要。 – penelope 2012-03-22 08:02:55

0

這是不是一個錯誤,而是由設計:

SIFT在同一位置不同方向返回多個興趣點,如果沒有明確單一的主方向。通常,估計最多三個(取決於實際圖像補丁)方向。