2012-06-05 77 views
5

我試圖使用cv::calcOpticalFlowPyrLK但有時該函數內部斷言失敗。斷言是npoints = prevPtsMat.checkVector(2, CV_32F, true)) >= 0。我正在使用OpenCV 2.3.1。該函數的源代碼可用於herecv :: goodFeaturesToTrack不返回任何功能

很難將我的頭圍繞在他們的代碼上,尤其是因爲我對計算機圖形學的經驗有限,而且他們缺乏評論。爲什麼這個斷言被觸發,對我的問題有什麼看法?

編輯:我所說的功能如下:

cv::calcOpticalFlowPyrLK(curBwFrame, prvFrame, features, newFeatures, trackingStatus, errors); 

我發現上述features矢量,這是通過調用cv::goodFeaturesToTrack(curBwFrame, features, 5, 0.2, 0.5, skinMask);與顯示爲足夠大和一個非空掩模得到有效的圖像,不包含任何功能。這怎麼會發生?

curBwFrame

curBwFrame

skinMask

skinMask

我可以使用下面的代碼片段重現該問題:

#include <vector> 
#include <cassert> 
#include <opencv2\opencv.hpp> 
using std::vector; 
using namespace cv; 

int main() { 
    vector<Point2f> features; 
    cv::Mat curBwFrame = imread("curBwFrame.png"); 
    cv::cvtColor(curBwFrame, curBwFrame, CV_RGB2GRAY); 
    imwrite("test.png", curBwFrame); 

    cv::Mat skinMask = imread("skinMask.png"); 
    cv::cvtColor(skinMask, skinMask, CV_RGB2GRAY); 
    imwrite("test.png", skinMask); 

    cv::goodFeaturesToTrack(curBwFrame, features, 5, 0.2, 0.5, skinMask); 
    assert(features.size() > 0); 

    return 0; 
} 
+1

的斷言的檢查,當斷言將顯示輸入參數是點的向量。沒有你的代碼很難回答你的問題。 –

+0

我已經在上面添加了更多信息,但我不確定其他信息可能是相關的。我可以在這裏轉儲一些大的代碼片段,但他們可能會包含大量不相關的信息。 – Pieter

+0

對不起,我早些時候混合了一些函數調用。我在上面添加了正確的代碼片段!如果有必要,我也可以發佈「goodFeaturesToTrack」的面具和源圖片。 – Pieter

回答

4

的主要問題是你parameters.In的OpenCV 2.3.2 documentation(2.3.1之間沒有相容性的變化),這是該方法的參數的說明:

void goodFeaturesToTrack(InputArray image, OutputArray corners, int maxCorners, double qualityLevel, double minDistance, InputArray mask=noArray(), int blockSize=3, bool useHarrisDetector=false, double k=0.04) 

參數:

  • 圖像 - 輸入8位或浮點32位單通道圖像。
  • corner - 檢測到的角落的輸出向量。
  • maxCorners - 要返回的最大角點數。如果找到的角點多,則返回其中最強的角點。
  • qualityLevel - 表徵圖像角落的最小可接受質量 的參數。該參數值乘以最佳特徵值(參見 cornerMinEigenVal())或哈里斯函數響應(參見 cornerHarris())的最佳角質量度量。質量指標小於 產品的角落被拒絕。例如,如果最佳角點的質量爲 measure = 1500,qualityLevel = 0.01,則拒絕質量度量值小於15的所有角點。
  • minDistance - 返回的角落之間的最小可能歐幾里德距離。
  • mask - 感興趣的可選區域。如果圖像不是空的(它 需要類型CV_8UC1和大小與圖像相同),它 指定角落被檢測的區域。
  • blockSize - 用於計算每個像素鄰域上的導數 協變矩陣的平均塊大小。請參閱 cornerEigenValsAndVecs()。
  • useHarrisDetector - 指示是否使用Harris 檢測器(請參閱cornerHarris())或cornerMinEigenVal()的參數。
  • k - 哈里斯檢測器的自由參數。

我建議你玩一點qualityControl和minDistance來滿足你的需求。

+0

隨着qualityLevel = 0.1我已經能夠檢測到5個功能。 –

+0

0.1值如何影響誤差?我知道它會增加,但這是一個常用質量值,還是被認爲不可靠? – Pieter

+0

你的意思是誤差? goodFeaturesToTrack對尺寸爲blockSize的窗口上每個像素的「等級」分類起作用。這個「等級」最大的是,這個像素更可能是一個正確的可區分的特徵,這意味着如果該特徵在其他條件下可以看到,例如不同的環境光照或相機姿態,它仍然會被歸類爲相同的特徵。如果像素級別不夠大,則不會將其歸類爲特徵。質量等級越小,將像素歸類爲特徵所需的「等級」越小,使得提取的特徵不易區分。 –

1

您是否嘗試過使用goodFeaturesToTrack 而沒有使用掩膜來查看它是否檢測到掩膜區域內的功能?這可能是因爲圖像很暗,並且該區域有點紋理,那麼goodFeaturesToTrack無法在那裏找到特徵。

您也可以嘗試ORB or FAST而不是goodFeaturesToTrack。我已經成功地使用ORB與calcOpticalFlowPyrLK(但沒有嘗試使用掩碼)。

或者你可以嘗試照亮圖像,甚至增強對比度。不確定這是否會帶來改進,因爲我認爲您場景中最大的問題是場景中的物體沒有足夠的紋理或角落,這對於這些探測器來說是更合適的功能。 我建議你嘗試ORB,看看你是否得到更多的積分。

+0

當掩碼區域被省略時,它選擇以下像素:(864,1170)和(859,1149)。這些點都不在掩模區域內。我不熟悉ORB和FAST。我在哪裏可以找到關於這些技術的更多信息?我沒有[發現](https://encrypted.google.com/search?hl=en&q=site%3Aopencv.willowgarage.com%20orb%20fast%20goodfeaturestotrack)在他們的文檔的信息。 – Pieter

+0

如果它只檢測到沒有掩碼的點,它很可能證實了我在答案中解釋的內容。我會用更多信息更新它。 –

0

圖像是否以彩色開始?轉換爲灰色之前,使用cv :: transform來增強顏色對比度。拍攝灰度範圍從0到255的全系列圖像。不要擔心圖像在面罩外飽和。

0

如果你的代碼是類似的:

Imgproc.goodFeaturesToTrack(mCurrentFrame, initial, NUMBER_OF_FEATURES, 0.1, 10); 
//The OpenCV opticalFlow will crash if the feature vector does not include any elements 
if (initial.elemSize() == 0) { 
    return; 
} 
initial.convertTo(mPrevPts, CvType.CV_32FC2); 

Video.calcOpticalFlowPyrLK(mPreviousFrame, mCurrentFrame, mPrevPts, mNextPts, status,err); 

確保你不要忘了語句中檢查的特徵向量(initial.elemSize()== 0)的大小。

如果這個向量是空的,從點到浮動分)矩陣由initial.convertTo(完成的變換線將不會發生,並調用calOpticalFlowPyrLK