[英]OpenCV 2.4.2 calcOpticalFlowPyrLK doesn't find any points
我在Linux上使用OpenCV 2.4.2。 我是用C ++寫的。 我想跟蹤簡單的對象(例如白色背景上的黑色矩形)。 首先,我使用goodFeaturesToTrack,然后使用calcOpticalFlowPyrLK在另一個圖像上找到這些點。 問題是calcOpticalFlowPyrLK找不到這些點。
我找到了用C語言編寫的代碼,在我的例子中不起作用: http : //dasl.mem.drexel.edu/~noahKuntz/openCVTut9.html
我已將其轉換為C ++:
int main(int, char**) {
Mat imgAgray = imread("ImageA.png", CV_LOAD_IMAGE_GRAYSCALE);
Mat imgBgray = imread("ImageB.png", CV_LOAD_IMAGE_GRAYSCALE);
Mat imgC = imread("ImageC.png", CV_LOAD_IMAGE_UNCHANGED);
vector<Point2f> cornersA;
goodFeaturesToTrack(imgAgray, cornersA, 30, 0.01, 30);
for (unsigned int i = 0; i < cornersA.size(); i++) {
drawPixel(cornersA[i], &imgC, 2, blue);
}
// I have no idea what does it do
// cornerSubPix(imgAgray, cornersA, Size(15, 15), Size(-1, -1),
// TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 20, 0.03));
vector<Point2f> cornersB;
vector<uchar> status;
vector<float> error;
// winsize has to be 11 or 13, otherwise nothing is found
int winsize = 11;
int maxlvl = 5;
calcOpticalFlowPyrLK(imgAgray, imgBgray, cornersA, cornersB, status, error,
Size(winsize, winsize), maxlvl);
for (unsigned int i = 0; i < cornersB.size(); i++) {
if (status[i] == 0 || error[i] > 0) {
drawPixel(cornersB[i], &imgC, 2, red);
continue;
}
drawPixel(cornersB[i], &imgC, 2, green);
line(imgC, cornersA[i], cornersB[i], Scalar(255, 0, 0));
}
namedWindow("window", 1);
moveWindow("window", 50, 50);
imshow("window", imgC);
cvWaitKey(0);
return 0;
}
ImageA: http ://oi50.tinypic.com/14kv05v.jpg
ImageB: http ://oi46.tinypic.com/4l3xom.jpg
ImageC: http ://oi47.tinypic.com/35n3uox.jpg
我發現它只適用於winsize = 11.我嘗試在移動的矩形上使用它來檢查它與原點的距離。 它幾乎沒有檢測到所有四個角落。
int main(int, char**) {
std::cout << "Compiled at " << __TIME__ << std::endl;
Scalar white = Scalar(255, 255, 255);
Scalar black = Scalar(0, 0, 0);
Scalar red = Scalar(0, 0, 255);
Rect rect = Rect(50, 100, 100, 150);
Mat org = Mat(Size(640, 480), CV_8UC1, white);
rectangle(org, rect, black, -1, 0, 0);
vector<Point2f> features;
goodFeaturesToTrack(org, features, 30, 0.01, 30);
std::cout << "POINTS FOUND:" << std::endl;
for (unsigned int i = 0; i < features.size(); i++) {
std::cout << "Point found: " << features[i].x;
std::cout << " " << features[i].y << std::endl;
}
bool goRight = 1;
while (1) {
if (goRight) {
rect.x += 30;
rect.y += 30;
if (rect.x >= 250) {
goRight = 0;
}
} else {
rect.x -= 30;
rect.y -= 30;
if (rect.x <= 50) {
goRight = 1;
}
}
Mat frame = Mat(Size(640, 480), CV_8UC1, white);
rectangle(frame, rect, black, -1, 0, 0);
vector<Point2f> found;
vector<uchar> status;
vector<float> error;
calcOpticalFlowPyrLK(org, frame, features, found, status, error,
Size(11, 11), 5);
Mat display;
cvtColor(frame, display, CV_GRAY2BGR);
for (unsigned int i = 0; i < found.size(); i++) {
if (status[i] == 0 || error[i] > 0) {
continue;
} else {
line(display, features[i], found[i], red);
}
}
namedWindow("window", 1);
moveWindow("window", 50, 50);
imshow("window", display);
if (cvWaitKey(300) > 0) {
break;
}
}
}
Lucas-Kanade的OpenCV實現似乎無法跟蹤二進制圖像上的矩形。 我做錯了什么或者這個功能不起作用?
Lucas Kanade方法通過使用該區域中的梯度來估計區域的運動。 在一種情況下,梯度下降方法。 因此,如果在x和y方向上沒有漸變,則方法將失敗。 第二個重要的注意事項是Lucas Kanade方程式
E = sum_ {winsize}(Ix * u + Iy * v * It)²
是強度恆定約束的一階泰勒近似。
I(x,y,t)= I(x + u,y + v,t + 1)
所以沒有水平(圖像金字塔)的方法的限制是圖像需要是線性函數。 在實踐中,這意味着只能估計小動作,取決於你選擇的勝利。 這就是為什么你使用水平,線性化圖像(It)。 所以5的水平有點高到3應該足夠了。 在您的情況下,頂級圖像的大小為640x480 / 2 ^ 5 = 20 x 15。
最后你的代碼中的問題是:
if (status[i] == 0 || error[i] > 0) {
你從lucas kanade方法得到的錯誤是產生的SSD意味着:
error = sum(winSize)(I(x,y,0) - I(x + u,y + u,1)^ 2)/(winsize * winsize)
錯誤不太可能是0.所以最后你跳過所有功能。 我通過忽略錯誤獲得了很好的經驗,這只是一種信心度量。 作為前瞻/后退信心,有非常好的替代信心措施。 如果丟棄太多的女性,你也可以通過忽略狀態標志來開始實驗
KLT通過找到關於某個窗口的兩組點之間的轉換來進行點跟蹤。 窗口大小是一個區域,在該區域上將追逐每個點以便在另一個幀上匹配它。
它是另一種基於梯度的算法,可以找到跟蹤的好特征。
通常KLT使用金字塔方法以便即使在大運動時也能保持跟蹤。 它可能在“maxLevel”時間用於您指定的“窗口大小”。
從未在二進制圖像上試過KLT。 問題可能出在KLT實施上,開始向錯誤的方向搜索,然后就失去了積分。 當您更改窗口大小時,搜索算法也會更改。 在你的照片上,你只有4個興趣點,只有1個像素。
這些是您感興趣的參數:
winSize – Size of the search window at each pyramid level
maxLevel – 0-based maximal pyramid level number. If 0, pyramids are not used (single level), if 1, two levels are used etc.
criteria – Specifies the termination criteria of the iterative search algorithm (after the specified maximum number of iterations criteria.maxCount or when the search window moves by less than criteria.epsilon
建議:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.