0.概述
1.原理说明
2.代码实现
#include <iostream>
#include <opencv2/opencv.hpp>
int main(int argc, char** argv) {
if(argc != 2) {
std::cerr << "Usage: " << argv[0] << " <video_path>" << std::endl;
return -1;
}
cv::VideoCapture cap(argv[1]);
if(!cap.isOpened()) {
std::cerr << "Error: Couldn't open the video file." << std::endl;
return -1;
}
cv::Mat oldFrame, oldGray;
std::vector<cv::Point2f> oldCorners;
// Parameters for Shi-Tomasi corner detection
int maxCorners = 100;
double qualityLevel = 0.3;
double minDistance = 7;
int blockSize = 7;
cap >> oldFrame;
cv::cvtColor(oldFrame, oldGray, cv::COLOR_BGR2GRAY);
// Detect corners in the first frame
cv::goodFeaturesToTrack(oldGray, oldCorners, maxCorners, qualityLevel, minDistance, cv::Mat(), blockSize);
// Color for optical flow
cv::Scalar color(0, 255, 0); // Green
while(true) {
cv::Mat frame, gray;
cap >> frame;
if(frame.empty()) {
break;
}
cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);
std::vector<cv::Point2f> newCorners;
std::vector<uchar> status;
std::vector<float> err;
// Calculate optical flow using Lucas-Kanade method
cv::calcOpticalFlowPyrLK(oldGray, gray, oldCorners, newCorners, status, err);
// Draw the motion vectors
for(size_t i = 0; i < oldCorners.size(); i++) {
if(status[i]) {
cv::line(frame, oldCorners[i], newCorners[i], color, 2);
cv::circle(frame, newCorners[i], 5, color, -1);
}
}
// Display the result
cv::imshow("Optical Flow - Lucas-Kanade", frame);
if(cv::waitKey(30) == 27) { // Exit on pressing 'Esc' key
break;
}
// Update the previous frame and corners
oldGray = gray.clone();
oldCorners = newCorners;
}
cap.release();
cv::destroyAllWindows();
return 0;
}