5-1稀疏光流Lucas-Kanade
程式說明:
運行結果:
我們先偵測影像中是否有特徵點可以使用,藉此比對此特徵點在下張影像中的出現位置,
藉此尋找像素的位移向量。
範例程式:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
int main(int argc, char** argv)
{
cv::Mat imgA = cv::imread("Img1.jpg", CV_LOAD_IMAGE_GRAYSCALE);
cv::Mat imgB = cv::imread("Img2.jpg", CV_LOAD_IMAGE_GRAYSCALE);
if (!imgA.data || !imgB.data)
{
std::cout<<"無法讀取影像" << std::endl;
return -1;
}
cv::resize(imgA, imgA, cv::Size(imgA.cols / 2, imgA.rows / 2));
cv::resize(imgB, imgB, cv::Size(imgB.cols / 2, imgB.rows / 2));
cv::Size img_sz = imgA.size();
int win_size = 10;
cv::Mat imgC = cv::imread("Img2.jpg", CV_LOAD_IMAGE_UNCHANGED);
cv::resize(imgC, imgC, cv::Size(imgC.cols / 2, imgC.rows / 2));
//檢查圖中是否有好的特徵點值得追蹤
std::vector< cv::Point2f > cornersA, cornersB;
const int MAX_CORNERS = 500;
cv::goodFeaturesToTrack(imgA, cornersA, MAX_CORNERS, 0.01,5, cv::noArray(), 3, false, 0.04 );
//再取特徵點中更細的subpixel
cv::cornerSubPix(imgA,cornersA, cv::Size(win_size, win_size), cv::Size(-1, -1),
cv::TermCriteria(cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS,20,0.03 ));
// 使用 Lucas Kanade 光流算法
std::vector
cv::calcOpticalFlowPyrLK(imgA, imgB, cornersA, cornersB, features_found, cv::noArray(), cv::Size(win_size * 2 + 1, win_size * 2 + 1),
5, cv::TermCriteria(cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS, 20, 0.3 ));
//將每個特徵點看是否有找出的對應點,如果有並畫出pixel間移動的距離
for (int i = 0; i < static_cast
if (!features_found[i]) {
continue;
}
cv::line(imgC, cornersA[i], cornersB[i], cv::Scalar(0, 255, 0), 1);
}
cv::imshow("ImageA", imgA);
cv::imshow("ImageB", imgB);
cv::imshow("LK Optical Flow Example", imgC);
cv::waitKey(0);
return 0;
}